Link to home
Start Free TrialLog in
Avatar of lucidity
lucidity

asked on

Function Pointers

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);
}
------------------------------------------
Avatar of alexo
alexo
Flag of Antarctica image

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).
Avatar of kellyjj
kellyjj

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.
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.
Avatar of lucidity

ASKER

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
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().

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.
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
You can use Winsock 2.  It contains the concept of layered protocols.  Check the MSDN.
Norbert, he wants *all* calls to func1() to be routed to func3().  Not those that are called through his pointer.
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
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
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?

ASKER CERTIFIED SOLUTION
Avatar of Norbert
Norbert
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial