Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you call a function in another address-space in C++

Tags:

c++

security

I'm aware of the threading issues etc that this could cause and of its dangers but I need to know how to do this for a security project I am doing at school. I need to know how to call a function in a remote address space of a given calling convention with arguments - preferably recovering the data the remote function has returned though its really not required that I do.

If I can get specifics from the remote function's function prototype at compile time, I will be able to make this method work. I need to know how big the arguments are and if the arguments are explicitly declared as pointers or not (void*, char*, int*, etc...)

I.e if I define a function prototype like:

typedef void (__cdecl *testFunc_t)(int* pData);

I would need to, at compile time, get the size of arguments at least, and if I could, which ones are pointers or not. Here we are assuming the remote function is either an stdcall or _cdecl call.

The IDE I am using is Microsoft Visual Studio 2007 in case the solution is specific to a particular product.

Here is my plan:

  1. Create a thread in the remote process using CreateRemoteThread at the origin of the function want to call, though I would do so in a suspended state.

  2. I would setup the stack such that the return address was that of a stub of code allocated inside of the process that would call ExitThread(eax) - as this would exit the thread with the function's return value - I would then recover this by by using GetExitCodeThread

  3. I would also copy the arguments for the function call from my local stack to that of the newly created thread - this is where I need to know if function arguments are pointers and the size of the arguments.

  4. Resume the thread and wait for it to exit, at which point I will return to the caller with the threads exit code.

I know that this should be doable at compile time but whether the compiler has some method I can use to do it, I'm not sure. I'm also aware all this data can be easily recovered from a PDB file created after compiling the code and that the size of arguments might change if the compiler performs optimizations. I don't need to be told how dangerous this is, as I am fully aware of it, but this is not a commercial product but a small project I must do for school.

The question: If I have a function prototype such as typedef void (__cdecl testFunc_t)(int pData);

Is there anyway I can get the size of this prototype's arguments at compile time(i.e in the above example, the arguments would sum to a total size of sizeof(int*) If, for example, I have a function like:

template<typename T> unsigned long getPrototypeArgLength<T>()
{ 
   //would return size of arguments described in the prototype T 
} 

//when called as

getPrototypeArgLength<testFunc>()
like image 559
Jeremy Avatar asked Nov 04 '22 10:11

Jeremy


1 Answers

This seems like quite a school project...

  1. For step 3 you can use ReadProcessMemory / WriteProcessMemory (one of them). For example, the new thread could receive the address (on the calling process), during the thread creation, of the parameters on the start (begin and end). Then it could read the caller process memory from that region and copy it to its own stack.

  2. Did you consider using COM for this whole thing? you could probably get things done much easier if you use a mechanism that was designed especially for that.

like image 72
OSH Avatar answered Nov 09 '22 10:11

OSH