Related
I have a DLL that I inject into another process but I want to be able to call the exports on that DLL from my application. I've read elsewhere that you have to the SendMessage API but I have no idea what to do. Is there any example code on how this is done?
While it is not possible to directly call a function in another process, you can do it indirectly pretty easily with a few steps and the Windows API.
Get the addresses of LoadLibrary and GetProcAddress from your own process. kernel32.dll should be loaded at the same address in every process, so you can rely on them being present in the process into which you are injecting
Create a struct that will hold all the arguments you want to pass to your function that will call the functions in the other process (because CreateRemoteThread can only pass one argument to a function, so we'll use it to pass a pointer to the structure) which at least contains member function pointers to hold the addresses of LoadLibrary and GetProcAddress
Allocate enough memory for a struct in the remote process via VirtualAllocEx, then fill it with the correct information with WriteProcessMemory
Write a function, taking a pointer to the struct you wrote, that uses LoadLibrary/GetProcAddress to call the function you want. Remember to use the pointers to those functions in the struct you are passing the function, not the names.
Allocate enough memory in the remote process to hold the function with VirtualAllocEx, making sure to pass VAX the PAGE_EXECUTE_READWRITE flag so that it can hold executable code
Read and write the function's code from your process to the other process via Read/WriteProcessMemory
Call the function in the remote process (which is at the address returned by the VirtualAllocEx) by using CreateRemoteThread.
Make sure that all the data you pass to the function is either stored inside the struct and/or resides in the remote process's address space (get it there with VirtualAllocEx/WriteProcessMemory.
It may look a little involved, but it's not really that complicated. If you need some help with it, feel free to ask in a comment.
You can't directly call functions in another process, in general. There are, however, some workarounds you can use.
First, if you know the address of the export (which isn't the case a lot of the time), and the function you call uses the __stdcall calling convention, takes a pointer-sized integer as an argument, and returns a DWORD, you can use CreateRemoteThread to execute it in a thread in the remote process. This is often used to run LoadLibrary to inject a DLL into a target process, since LoadLibrary is loaded in the same address on all processes on a given computer.
Otherwise, the DLL you inject will need to do some sort of RPC with the process that called it. For example, you could have your injected DLL spawn a thread in its DLL_PROCESS_ATTACH handler, which in turn connects to a named pipe, or connects over COM or something to the master process.
SendMessage would need a window handle (hidden or visible), and a message-pump associated with it, that can handle the custom message. As with UAC/Windows-7, the integrity levels of applications may prevent other applications to send/post messages from other processes having low integrity.
It is better to have another thread that waits for these custom messages. For this, you may use pipes (named or unnamed), sockets, mail-slots, shared memory (along with mutex/event for triggering). The another processes would send the message using same protocol.
But before implementing this custom messaging/protocol/IPC mechanism, I suggest you to first determine the exact need.
I have been looking for a way to dynamically load functions into c++ for some time now, and I think I have finally figure it out. Here is the plan:
Pass the function as a string into C++ (via a socket connection, a file, or something).
Write the string into file.
Have the C++ program compile the file and execute it. If there are any errors, catch them and return it.
Have the newly executed program with the new function pass the memory location of the function to the currently running program.
Save the location of the function to a function pointer variable (the function will always have the same return type and arguments, so
this simplifies the declaration of the pointer).
Run the new function with the function pointer.
The issue is that after step 4, I do not want to keep the new program running since if I do this very often, many running programs will suck up threads. Is there some way to close the new program, but preserve the memory location where the new function is stored? I do not want it being overwritten or made available to other programs while it is still in use.
If you guys have any suggestions for the other steps as well, that would be appreciated as well. There might be other libraries that do things similar to this, and it is fine to recommend them, but this is the approach I want to look into — if not for the accomplishment of it, then for the knowledge of knowing how to do so.
Edit: I am aware of dynamically linked libraries. This is something I am largely looking into to gain a better understanding of how things work in C++.
I can't see how this can work. When you run the new program it'll be a separate process and so any addresses in its process space have no meaning in the original process.
And not just that, but the code you want to call doesn't even exist in the original process, so there's no way to call it in the original process.
As Nick says in his answer, you need either a DLL/shared library or you have to set up some form of interprocess communication so the original process can send data to the new process to be operated on by the function in question and then sent back to the original process.
How about a Dynamic Link Library?
These can be linked/unlinked/replaced at runtime.
Or, if you really want to communicated between processes, you could use a named pipe.
edit- you can also create named shared memory.
for the step 4. we can't directly pass the memory location(address) from one process to another process because the two process use the different virtual memory space. One process can't use memory in other process.
So you need create a shared memory through two processes. and copy your function to this memory, then you can close the newly process.
for shared memory, if in windows, looks Creating Named Shared Memory
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
after that, you still create another memory space to copy function to it again.
The idea is that the normal memory allocated only has read/write properties, if execute the programmer on it, the CPU will generate the exception.
So, if in windows, you need use VirtualAlloc to allocate the memory with the flag,PAGE_EXECUTE_READWRITE (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx)
void* address = NULL;
address= VirtualAlloc(NULL,
sizeof(emitcode),
MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
After copy the function to address, you can call the function in address, but need be very careful to keep the stack balance.
Dynamic library are best suited for your problem. Also forget about launching a different process, it's another problem by itself, but in addition to the post above, provided that you did the virtual alloc correctly, just call your function within the same "loadder", then you shouldn't have to worry since you will be running the same RAM size bound stack.
The real problems are:
1 - Compiling the function you want to load, offline from the main program.
2 - Extract the relevant code from the binary produced by the compiler.
3 - Load the string.
1 and 2 require deep understanding of the entire compiler suite, including compiler flag options, linker, etc ... not just the IDE's push buttons ...
If you are OK, with 1 and 2, you should know why using a std::string or anything but pure char *, is an harmfull.
I could continue the entire story but it definitely deserve it's book, since this is Hacker/Cracker way of doing things I strongly recommand to the normal user the use of dynamic library, this is why they exists.
Usually we call this code injection ...
Basically it is forbidden by any modern operating system to access something for exceution after the initial loading has been done for sake of security, so we must fall back to OS wide validated dynamic libraries.
That's said, one you have valid compiled code, if you realy want to achieve that effect you must load your function into memory then define it as executable ( clear the NX bit ) in a system specific way.
But let's be clear, your function must be code position independant and you have no help from the dynamic linker in order to resolve symbol ... that's the hard part of the job.
I have a DLL that I inject into another process but I want to be able to call the exports on that DLL from my application. I've read elsewhere that you have to the SendMessage API but I have no idea what to do. Is there any example code on how this is done?
While it is not possible to directly call a function in another process, you can do it indirectly pretty easily with a few steps and the Windows API.
Get the addresses of LoadLibrary and GetProcAddress from your own process. kernel32.dll should be loaded at the same address in every process, so you can rely on them being present in the process into which you are injecting
Create a struct that will hold all the arguments you want to pass to your function that will call the functions in the other process (because CreateRemoteThread can only pass one argument to a function, so we'll use it to pass a pointer to the structure) which at least contains member function pointers to hold the addresses of LoadLibrary and GetProcAddress
Allocate enough memory for a struct in the remote process via VirtualAllocEx, then fill it with the correct information with WriteProcessMemory
Write a function, taking a pointer to the struct you wrote, that uses LoadLibrary/GetProcAddress to call the function you want. Remember to use the pointers to those functions in the struct you are passing the function, not the names.
Allocate enough memory in the remote process to hold the function with VirtualAllocEx, making sure to pass VAX the PAGE_EXECUTE_READWRITE flag so that it can hold executable code
Read and write the function's code from your process to the other process via Read/WriteProcessMemory
Call the function in the remote process (which is at the address returned by the VirtualAllocEx) by using CreateRemoteThread.
Make sure that all the data you pass to the function is either stored inside the struct and/or resides in the remote process's address space (get it there with VirtualAllocEx/WriteProcessMemory.
It may look a little involved, but it's not really that complicated. If you need some help with it, feel free to ask in a comment.
You can't directly call functions in another process, in general. There are, however, some workarounds you can use.
First, if you know the address of the export (which isn't the case a lot of the time), and the function you call uses the __stdcall calling convention, takes a pointer-sized integer as an argument, and returns a DWORD, you can use CreateRemoteThread to execute it in a thread in the remote process. This is often used to run LoadLibrary to inject a DLL into a target process, since LoadLibrary is loaded in the same address on all processes on a given computer.
Otherwise, the DLL you inject will need to do some sort of RPC with the process that called it. For example, you could have your injected DLL spawn a thread in its DLL_PROCESS_ATTACH handler, which in turn connects to a named pipe, or connects over COM or something to the master process.
SendMessage would need a window handle (hidden or visible), and a message-pump associated with it, that can handle the custom message. As with UAC/Windows-7, the integrity levels of applications may prevent other applications to send/post messages from other processes having low integrity.
It is better to have another thread that waits for these custom messages. For this, you may use pipes (named or unnamed), sockets, mail-slots, shared memory (along with mutex/event for triggering). The another processes would send the message using same protocol.
But before implementing this custom messaging/protocol/IPC mechanism, I suggest you to first determine the exact need.
I have a pointer (void *) to a function and I want to know which process this function belongs to. I have no idea which way to go about it, but I think it's possible by using some form of VirtualQuery trickery. Any help would be appreciated.
Thanks in advance,
CLARIFICATION: By "belong to process" I mean what process the function is in. For example:
say there was an executable (test.exe) loaded in memory. This executable contains a function named SayHello, which is located at 0xDEADBEEF in memory. In an entirely different process, how would I know 0xDEADBEEF is in test.exe's memory space.
Hope that clears things up.
CLARIFICATION 2: I'm sure you're familiar with "VTable hooking", where an external module changes a VTable pointer in a seperate process to point to a different function. Thereby whenever the hooked member is called, it is passed to the external module.
To prevent this (anti-cheat), I want to be able to check whether all methods of a VTable point to the module they reside in.
SOLUTION CODE:
template<class T>
inline void **GetVTableArray(T *pClass, int *pSize)
{
void **ppVTable = *(void ***)pClass;
if(pSize)
{
*pSize = 0;
while(!IsBadReadPtr(ppVTable[*pSize], sizeof(UINT_PTR)))
(*pSize)++;
}
return ppVTable;
}
bool AllVTableMembersPointToCurrentModule(void *pClass)
{
DWORD dwOldProtect;
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 moduleEntry;
// Take a snapshot of all modules in the specified process
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if(hModuleSnap == INVALID_HANDLE_VALUE)
return false;
// Set the size of the structure before using it
moduleEntry.dwSize = sizeof(MODULEENTRY32);
// Retrieve information about the first module (current process)
if(!Module32First(hModuleSnap, &moduleEntry))
{
CloseHandle(hModuleSnap);
return false;
}
// Grab the base address and size of our module (the address range where
// the VTable can validly point to)
UINT_PTR ulBaseAddress = reinterpret_cast<UINT_PTR>(moduleEntry.modBaseAddr);
UINT_PTR ulBaseSize = moduleEntry.modBaseSize;
// Get the VTable array and VTable member count
int nMethods;
void **ppVTable = GetVTableArray(pClass, &nMethods);
#ifdef VTABLE_FAKING
// Allow patching
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE_READWRITE, &dwOldProtect);
// Now take the next module and set the first VTable pointer to point to an
// invalid address, outside of the current module's address range
Module32Next(hModuleSnap, &moduleEntry);
ppVTable[0] = moduleEntry.modBaseAddr;
#endif
// Don't allow people to overwrite VTables (can easily be bypassed, so make
// sure you check the VirtualProtect status of the VTable regularly with
// VirtualQuery)
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE, &dwOldProtect);
// Clean up the snapshot object
CloseHandle(hModuleSnap);
// Ensure all VTable pointers are in our current module's address range
for(int i = 0; i < nMethods; ++i)
{
// Get address of the method this VTable pointer points to
UINT_PTR ulFuncAddress = reinterpret_cast<UINT_PTR>(ppVTable[i]);
// Check the address is within our current module range
if(ulFuncAddress < ulBaseAddress || ulFuncAddress > ulBaseAddress + ulBaseSize)
return false;
}
return true;
}
Each process has its own address space. This means that the same address will contain different things for different processes, so there is no way to do what you're asking.
If this pointer is to a function in the current program (i.e. a function that you can currently call), then the answer is simple: it belongs to the current process.
To further clarify: A pointer by itself is meaningless unless you already know which process it belongs to. Process #1001 may have a function sayHello at address 0x12345678, while process #1002 has the function sayGoodbye at address 0x12345678, and process #1003 contains some data at the same address. There is no way to know which process the pointer came from.
The hijacked function pointer in the VTable can only be inside your process, as the other folks have already answered. The memory address only makes sense for your process. If someone is going to overwrite one of your VTable spots, then they would first have to hook something your process, which means running code inside your process. There exists plenty of win API that provides hooking.
See EnumProcessModule to go through all of the modules in your process. See this about modules info including base address of your module. You would then have to check your VTables to make sure those addressed exist inside of your module's address range.
To prevent VTable hijacking in the first place? I don't know how to do this, other than trying Microsoft's Detours library, which can in theory be used to detour any hook API call inside your process.
If you have the module handle, you can inspect the image header to ensure that the vtable pointers are in that module's virtual address space.
In any of the Windows operating systems that are descended from Windows NT (so, for all intents and purposes anything including and after XP, and before that NT 4 and NT 3.51) each process has it's own address space. Within reason, any pointer address can be different in every process in the system as they all have an 0xDEADBEEF address and it may, or may not contain the same thing as other processes. This was not the same with Windows 3.0, 3.1, 95, 98 and ME (they had one address space which all processes shared) where your question MAY have made more sense.
So, without a handle to a process to go with your pointer address the address is pretty much useless to you. With a handle to a process you can (possibly) work out what you want by walking the import tables for the DLLs that you import... If the function isn't an imported function then it's unlikely that you could work out what you want to know.
Note that if the address is to a function which is from a 'standard' system DLL then you MAY be able to work out where it lives by finding out what function it represents in the address space of your process as there is a strong chance that the DLL will be mapped to the same base address in your process as it is in every other process.
Why not tell us a little more about what it is, exactly, that you're actually trying to do?
Edit:
Well, as I described above, what you're suggesting is not possible except on very old versions of Windows. What IS possible is that you can inject code into a process to replace that code that should be executed. The address of this injected code is valid in the target process's address space and contains code that you (the hacking process) have created. You do this by a combination of allocating memory in the remote process with VirtualAllocEx() (1) and then writing your code to it with WriteProcessMemory() (2). You now have code that you wrote in the target process. You can then patch it in so that it's called instead of the code that should be called.
The common way to do this is IAT hooking (Import Address Table hooking) and this lets you replace imported functions from DLLs. To detect this you need to scan the DLL's Import Address Table from the DLL image on disk, work out where the functions are in memory and then scan the in memory IAT to check that the functions are where they should be; if they're not then they've likely been patched.
You're suggesting that someone is replacing an arbitrary C++ vTable entry. This is possible with the same technique but it's harder as there's no convenient table of names to addresses that you can use to work out where to patch. Anyway, assuming the bad guy can find the correct address to patch he can use the same technique as above to create his own function in your process.
Detecting the vTable problem is made more complex by the lack of name to address lookup, but if you're in the process that's being hacked you can simply have written code that takes the address of the function in question at start up. Store that somewhere and compare it later. However, you'd probably best take a copy of the whole function itself in memory and compare with that as you might find that the bad guys simply look for some recognisable function signature bytes and patch a jump into them somewhere to their own code or simply to skip yours.
Good luck and grab yourself a good book, such as one by Jeffrey Richter which will explain much of this far better than I can.
I don't really understand your question, so I'm going to take a stab in the dark and answer what I think you're asking.
You're asking how you can find out, from a function pointer, to which module it belongs.
The solution is rather simple in theory, scan backwards in memory to find the header, and then enjoy using this function GetModuleFileName.
Since your question isn't well worded, you don't get a well worded answer.
I'm aware that each process creates it's own memory address space, however I was wondering,
If Process A was to have a function like :
int DoStuff() { return 1; }
and a pointer typedef like :
typedef int(DoStuff_f*)();
and a getter function like :
DoStuff_f * getDoStuff() { return DoStuff; }
and a magical way to communicate with Process B via... say boost::interprocess
would it be possible to pass the function pointer to process B and call
Process A's DoStuff from Process B directly?
No. All a function pointer is is an address in your process's address space. It has no intrinsic marker that is unique to different processes. So, even if your function pointer just happened to still be valid once you've moved it over to B, it would call that function on behalf of process B.
For example, if you had
////PROCESS A////
int processA_myfun() { return 3; }
// get a pointer to pA_mf and pass it to process B
////PROCESS B////
int processB_myfun() { return 4; } // This happens to be at the same virtual address as pA_myfun
// get address from process A
int x = call_myfun(); // call via the pointer
x == 4; // x is 4, because we called process B's version!
If process A and B are running the same code, you might end up with identical functions at identical addresses - but you'll still be working with B's data structures and global memory! So the short answer is, no, this is not how you want to do this!
Also, security measures such as address space layout randomization could prevent these sort of "tricks" from ever working.
You're confusing IPC and RPC. IPC is for communicating data, such as your objects or a blob of text. RPC is for causing code to be executed in a remote process.
In short, you cannot use function pointer that passed to another process.
Codes of function are located in protected pages of memory, you cannot write to them. And each process has isolated virtual address space, so address of function is not valid in another process. In Windows you could use technique described in this article to inject your code in another process, but latest version of Windows rejects it.
Instead of passing function pointer, you should consider creating a library which will be used in both processes. In this case you could send message to another process when you need to call that function.
If you tried to use process A's function pointer from process B, you wouldn't be calling process A - you'd call whatever is at the same address in process B. If they are the same program you might get lucky and it will be the same code, but it won't have access to any of the data contained in process A.
A function pointer won't work for this, because it only contains the starting address for the code; if the code in question doesn't exist in the other process, or (due to something like address space randomization) is at a different location, the function pointer will be useless; in the second process, it will point to something, or nothing, but almost certainly not where you want it to.
You could, if you were insane^Wdaring, copy the actual instruction sequence onto the shared memory and then have the second process jump directly to it - but even if you could get this to work, the function would still run in Process B, not Process A.
It sounds like what you want is actually some sort of message-passing or RPC system.
This is why people have invented things like COM, RPC and CORBA. Each of them gives this general kind of capability. As you'd guess, each does so the job a bit differently from the others.
Boost IPC doesn't really support remote procedure calls. It will enable putting a variable in shared memory so its accessible to two processes, but if you want to use a getter/setter to access that variable, you'll have to do that yourself.
Those are all basically wrappers to produce a "palatable" version of something you can do without them though. In Windows, for example, you can put a variable in shared memory on your own. You can do the same in Linux. The Boost library is a fairly "thin" library around those, that lets you write the same code for Windows or Linux, but doesn't try to build a lot on top of that. CORBA (for one example) is a much thicker layer, providing a relatively complete distributed environment.
If both processes are in the same application, then this should work. If you are trying to send function pointers between applications then you are out of luck.
My original answer was correct if you assume a process and a thread are the same thing, which they're not. The other answers are correct - different processes cannot share function pointers (or any other kind of pointers, for that matter).