1

I have been playing around with pointers and function pointers in c/c++. As you can get the adress of a function, can you change where a function call actually ends?

I tried getting the memory adress of a function, then writing a second functions adress to that location, but it gave me a access violation error.

Regards,

user1038502
  • 767
  • 1
  • 9
  • 21
  • Because a function is not a function pointer, so there's nothing to change. – fredoverflow Apr 25 '12 at 07:20
  • Sounds like some potentially dangerous practice that is prone to memory leaks. If you end a function prematurely then don't you also need to keep track of resources that needs to clean up? – Spoike Apr 25 '12 at 07:28
  • You used to be able to do this on Vax Pascal. The equivalent of: `void foo(int &j) { j=2; }` Then `foo(1); if(1==2) ...`. The compiler would actually pass in where it stored its `1`, which you would then have changed to a `2`, making the comparison true and turning every `1` in your program into a `2`! – David Schwartz Apr 25 '12 at 07:52

5 Answers5

2

Function pointers are variables, just like ints and doubles. The address of a function is something different. It is the location of the beginning of the function in the .text section of the binary. You can assign the address of a function to a function pointer of the same type however the .text section is read only and therefore you can't modify it. Writing to the address of a function would attempt to overwrite the code at the beginning of the function and is therefore not allowed.

Note: If you want to change, at runtime, where function calls end up you can create something called a vritual dispatch table, or vtable. This is a structure containing function pointers and is used in languages such as c++ for polymorphism.

e.g.:

struct VTable {
    int (*foo)(void);
    int (*bar)(int);
} vTbl;

At runtime you can change the values of vTbl.foo and vTbl.bar to point to different functions and any calls made to vTbl.foo() or .bar will be directed to the new functions.

Will
  • 4,585
  • 1
  • 26
  • 48
  • I see. I thought when you called a function, you sort of just jumped to the memory address where that function started. So my inserting a new memory address at that location you could sort of redirect where the function call ended. – user1038502 Apr 25 '12 at 07:24
  • You do jump to the memory address. However for a function `foo()` if you take the address `&foo` that _is_ the location that you would jump to. Overwriting this, such as `*((int*)&foo) = 8;` would write over the first instructions where you would be jumping to, the start of the function, with the value `8`. – Will Apr 25 '12 at 07:29
1

In some environments, it is possible to "patch" the beginning instructions of a function to make the call go somewhere else. This is an unusual technique and is not used for normal programming. It is sometimes used if you have an existing compiled program and need to change how it interacts with the operating system.

Microsoft Detours is an example of a library that has the ability to this.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
1

If the function you're trying to call is inlined, then you're pretty much out of luck. However, if it's not inlined, then there may be a way:

On Unix systems there's a common feature of the dynamic linker called LD_PRELOAD which allows you to override functions in shared libraries with your own versions. See the question What is the LD_PRELOAD trick? for some discussion of this. If the function you're trying to hijack is not loaded from a shared library (i.e. if it's part of the executable or if it's coming from a statically linked library), you're probably out of luck.

On Windows, there are other attack vectors. If the function to be hooked is exported by some DLL, you could use Import Address Table Patching to hijack it without tinkering with the code of the function. If it's not exported by the DLL but you can get the address of it (i.e. by taking the address of a function) you could use something like the free (and highly recommended) N-CodeHook project.

Community
  • 1
  • 1
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • What N-CodeHook does, is what I was asking about how to do. I am sure I will be able to find something usefull by downloading it. Thanks – user1038502 Apr 25 '12 at 08:58
0

You can change what a function pointer points to, but you can't change a normal function nor can you change what the function contains.

Pubby
  • 51,882
  • 13
  • 139
  • 180
0

You generally can't find where a function ends. There's no such standard functionality in the language and the compiler can optimize code in such ways that the function's code isn't contiguous and really has not a single point of end and in order to find where the code ends one would need to either use some non-standard tools or disassemble the code and make sense of it, which isn't something you can easily write a program for to do automatically.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180