Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Function Pointers

Posted on 1998-05-13
13
Medium Priority
?
237 Views
Last Modified: 2010-04-10
I have some demonstration code, below...

At this point i can make a function pointer to call func1 from F (a pointer to func1()). I would like to make OldFunc a pointer to func1 then replace the actual function pointer to func1with a pointer  to func3, which in turn calls func1 (or OldFunc pointer).

The effect would be that everytime you call func1 func3 is called first, then, func3 calls func1. Essentially an interception of func1 by func3.

--------------------------------------
diagram (func1 interception)

[call to func1]<---------------------------
         |points to func 3                         | points to OldFunc (func 1)
         -------------------->[func 3]---------
---------------------------------------
typedef void (* FUNC)(char str[20]);

void func1(char str[20]);
void func3(char str[20]);
FUNC OldFunc;

main (){
      FUNC F;
      F = func1;
      OldFunc = func1;
                      func1("hello"); //calls normally
//replace pointer here... how?????
                       func1("hello");//calls func3
}

void func1(char str[20]){
      MessageBox(NULL,str,"Message",MB_OK);
}

void func3(char str[20]){
      MessageBox(NULL,"Gottcha","Message",MB_OK);
      OldFunc(str);
}
------------------------------------------
0
Comment
Question by:lucidity
  • 5
  • 4
  • 3
  • +1
13 Comments
 
LVL 11

Expert Comment

by:alexo
ID: 1176975
You are confusing two things.

    func();

Calls a function directly, not through a pointer.  So there is nothing to replace.
On the other hand,

    p = func;
    p();

Calls through a pointer (indirectly).  You can assign another value to p.

In other words, the function's name (func) does not rever to any object you can change (it is not an lvalue).
0
 
LVL 2

Expert Comment

by:kellyjj
ID: 1176976
alexo is pretty much right on.  A pointer could point to anything, so changing the value would quite simple.  Now if you are wanting to maybe do multiple funcs/procs  then I would with array of pointers to functions.  Then that way you keep track of what func is being called a lot easier.  

But calling funcs through pointers could be very dangerous and may be more work than it is worth.  If you want 1 out of 2 funcs called depending on a condition or something then a if else... or maybe a switch would be the safer way.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1176977
Typing mistake "rever" --> "refer".

>> Essentially an interception of func1 by func3.
In view of my comment above - it cannot be done this way.

Now, if you would tell us exactly WHAT you want to accomplish and WHY, we might be able to supply the HOW.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 2

Author Comment

by:lucidity
ID: 1176978
I am experimenting with loading DLL functions, I have found that DLLs occupy the same memory no matter what app they are loaded from, thus the name I suppose . I want import a DLL function ("send" from winsock for example), then store a pointer to that function. I will also load a point to a send function of my own.

What I want to do is have the winsock send function "rerouted" to my send function which can do some preprocessing then call the real send, which I have stored in my programs memory space.  I just need to know how to place a pointer to my send function in the memory space that points to the winsock send function.

Thats what I want to do... do you have any ideas?

Thank you in advance.. Jason

Typing mistake "rever" --> "refer" --> "reefer" :) little joke
0
 
LVL 11

Expert Comment

by:alexo
ID: 1176979
Oh, why didn't you say so in the first place?

First you create a DLL which imports the send() function, call it WSOCK32.DLL (or whatever the "real" winsock DLL is called) and put it in the same directory as the application.  That way, it will be loaded instead of the "real" winsock.  Step 1 complete.

Then, in your DLL you LoadLibrary() the real DLL from the system directory using GetSystemDirectory(), get the address of the "real" send() using GetProcAddress() and call it via the resulting pointer whenever you like.

Remember that you'll have to provide all the winsock services in your DLL, not just the send().

0
 
LVL 2

Author Comment

by:lucidity
ID: 1176980
I know that, thats why I just want to replace the one, rather than rewriting the entire winsock function interface..... does anyone know how to replace a function pointer as I stated above.
0
 
LVL 3

Expert Comment

by:Norbert
ID: 1176981
As Alexo says Your Func1 and Func 3 are no lvalues but your
F OldFunc are I have changed your example a little bit and now it should work as you want

typedef void (* FUNC)(char str[20]);
void func1(char str[20]);
void func3(char str[20]);
FUNC OldFunc;

main (){
FUNC F;
F = func1;
OldFunc = func1;
                      F("hello"); //calls normally
//replace pointer here... how?????
//Simple assign it
                       F=func3;
                       F("hello");//calls func3
}
void func1(char str[20]){
MessageBox(NULL,str,"Message",MB_OK);
}

void func3(char str[20]){
MessageBox(NULL,"Gottcha","Message",MB_OK);
OldFunc(str);
}
This will also work with your DLL's

Hope that helps
Regards
      Norbert
PS:Greetings from germany
0
 
LVL 11

Expert Comment

by:alexo
ID: 1176982
You can use Winsock 2.  It contains the concept of layered protocols.  Check the MSDN.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1176983
Norbert, he wants *all* calls to func1() to be routed to func3().  Not those that are called through his pointer.
0
 
LVL 3

Expert Comment

by:Norbert
ID: 1176984
Alexo, if he use LoadLibrary , GetProcAddress where Is the problem?
The overlayed DLL should have a function to store the
function pointers that should rerouted
First load all needed functions of the original DLL.
Second load the function pointer of the rerouter storing function
Third give the function pointers to reroute to the storing function
Forth load the function pointers from the router dll overwriting the previous fetched and all calls now are rerouted from the application.

If he wants that all Applications use his overlayed functions I think he MUST rewrite the original DLL  AND also rename
it. His new DLL then must have the name of the old one.
And it must load the renamed DLL to map through all functions.

Remember
In Microsoft® Windows®, dynamic-link libraries (DLL) are modules that contain functions and data. A DLL is loaded at runtime by its calling modules (.EXE or DLL). When a DLL is loaded, it is mapped into the address space of the calling process.

Because of the mapping into the address space of the calling process GetProcAdress will return a virtual address.
Therefore it is not possible to patch the DLL in memory to reroute some functions for all applications
0
 
LVL 2

Author Comment

by:lucidity
ID: 1176985
but you can map your function into the program space of another program.

but just as an experiment I ran two different programs that got the function pointer for send from Wsock32.dll and both pointers pointed to the same memory location. So I am thinking it MIGHT work
0
 
LVL 2

Author Comment

by:lucidity
ID: 1176986
I have been playing around with this and found that this so ALMOST works :

memcpy(&f1,&f3,sizeof(f3));

now any calls to f1 will go to f3, and f3 in turn calls OldFunc, a pointer to func1. Unfortunatly if I call func1(), the real function, it acts normally. can anyone think of a way to get the same effect that I get with the pointers with real functions?

0
 
LVL 3

Accepted Solution

by:
Norbert earned 20 total points
ID: 1176987
Because f3 is a pointer sizeof(f3) returns the size of the pointer
so memcpy(&f1,&f3,sizeof(f3)); Is exactly the same like f1=f3

What you can try - it worked using good old DOS -
is to patch the memory where f1 points to but you *MUST* have
expirience using Assembler code.

I can give you a pseudoCode description:
    read code (sizeof jmp f3) that is where f1 points to and save it     for later use
    write jmp f3 to that location
now every call to f1 will go to f3
Back to f1:
     push return address where f1 should return to stack (post processing)
     execute code that was saved when the jump to f3 was implanted
     jump to the location behind the implanted code

But
1. this will not work using Win 95 or win NT because program memory is write protected.
2. if you found a workarond for 1. you have to interpret the code that is copied because instuctions have different lengths and you must copy the complete instruction
3. there are 2 posibilities of return:
a) the caller has to clear the stack after return
b) the callee clears the stack when it returns.

So I am sorry to say you have no simple chance to do what you want and doing so you would have more work than exchanging DLL and mapping functions through to the original DLL



0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

972 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question