34

Given knowledge of the prototype of a function and its address in memory, is it possible to call this function from another process or some piece of code that knows nothing but the prototype and memory address? If possible, how can a returned type be handled back in the code?

dtech
  • 47,916
  • 17
  • 112
  • 190
  • In C++ there are no processes. You need to specify your platform if you want help with that. – R. Martinho Fernandes Jan 18 '12 at 19:10
  • From another process? That's a very special case. Do you really need that? – jalf Jan 18 '12 at 19:10
  • So it is possible from another thread of the same executable but not in between executable? What if it is a shared library? – dtech Jan 18 '12 at 19:14
  • @jalf the idea is to create sort of a HANDLE to manipulate internals of other processes. – dtech Jan 18 '12 at 19:15
  • 2
    @ddriver - it sounds like you want to investigate inter-process communication, not function pointers. Unless you're trying to write a debugger, in which case you have a lot of hurdles ahead of you. – Carl Norum Jan 18 '12 at 19:18
  • 3
    @ddriver If you're talking about calling from a different process, you really do need to specify the platform. In most modern operating systems the memory owned by one process can't be arbitrarily read or written by a different process. If two processes want to share a region of memory, they have to set that up explicitly. This is generally a good thing, as it prevents a bad pointer or other bug in one process from taking down other processes, or even the entire OS. – Caleb Jan 18 '12 at 19:21
  • 1
    @Caleb: what problem are you trying to solve? In general, there are a lot of limitations on how processes can interact, and calling raw functions from other processes is very very tricky to do safely and reliably. Try to take a step back and explain to us what the end goal is, because it sounds like right now you're heading down the wrong track – jalf Jan 18 '12 at 19:32

6 Answers6

59

On modern operating systems, each process has its own address space and addresses are only valid within a process. If you want to execute code in some other process, you either have to inject a shared library or attach your program as a debugger.

Once you are in the other program's address space, this code invokes a function at an arbitrary address:

typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();
sbi
  • 219,715
  • 46
  • 258
  • 445
  • 6
    Thanks to @R.Martinho for the [better style to typedef function prototypes](http://chat.stackoverflow.com/transcript/message/2400130#2400130). I hadn't even known this works! – sbi Jan 18 '12 at 19:21
  • AFAIK, there's no way to *write* memory in other programs address space in new operating systems and that causes a SEGFAULT. But there's nothing that prevents a program from reading any memory location (hence, the heartbleed bug being scary in OpenSSL, because you can read anything in memory with that). So, Could you explain why I can't access other program's address space and require shared libraries or debugger? – The Quantum Physicist Mar 03 '17 at 07:29
  • 2
    @TheQuantumPhysicist: Because each process has its own virtual memory space. Your process' `0xdeadbeef` is yours, and my process' is mine. They are located at different addresses of physical memory. – sbi Mar 03 '17 at 22:43
  • @abi Only if the computer has an MMU. The computer might not even have processes if there is no OS... – Jerry Jeremiah Apr 02 '20 at 21:51
14

Yes - you're describing a function pointer. Here's a simple example;

int (*func)(void) = (int (*)(void))0x12345678;
int x = func();

It probably won't work between processes - in most operating systems, processes don't have access to each other's memory.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
8

When you need a direct call:

((void(*)(void))0x1234)();
Ulfhetnar
  • 681
  • 9
  • 11
7

All previous answers are nice but much too long:

int i = ((int (*)(void))0xdeadbeef)();
//                      ==========     --> addr of the function to call
//        =============                --> type of the function to call
//       =========================     --> ... we get a ptr to that fct
//      =============================  --> ... and we call the function
Fuujuhi
  • 313
  • 3
  • 8
1

In most OP, every process has its own memory, so you can't.

Sample code: a.c:

#include <stdio.h>

int r() {return 2;}
int main() {
    printf("%p\n",r);
    while(1);
}

b.c:

#include <stdio.h>

int main() {
int a,(*b)();
scanf("%p",&b);
a=b();
printf("%d\n",a);
return 0;
}

this get segmentation fault.

asaelr
  • 5,438
  • 1
  • 16
  • 22
  • In c c++ you can access any memory location you want, for better or worse – dtech Jan 18 '12 at 19:12
  • @ddriver: C++ allows you to access any _virtual_ memory location. However, many OS's give each process it's own virtual memory, so they can't affect each other. There are OS-specific calls you can make/use to affect another processes memory though. – Mooing Duck Jan 18 '12 at 19:16
  • 3
    @ddriver - no you can't. You can only access memory locations the operating system lets you access. All your program knows is the virtual memory environment in which it's running, which normally bears pretty much no relationship to physical reality. – Carl Norum Jan 18 '12 at 19:17
0

It is definitely possible, but there are restrictions. Each process will have its own block of memory which other processes can't interfere with. Now, you will notice, I wrote it is definitely possible, this is through DLL injection (or code injection).

We can use the typedef keyword to achieve this. Now, I see you've marked the answer as 'Answered' and it seems you've gotten on fine, this is just a notice for anyone else that may be interested.

  • That depends on your OS - if you have one. Some computers don't have a hardware MMU so there are no memory barriers - so even if there is an OS, the processes CAN write to each other's memory. – Jerry Jeremiah Apr 02 '20 at 21:50