Solved

Function Pointers

Posted on 1998-05-13
13
225 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
 
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
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 10 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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
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.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

707 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now