Lets say the process 1 is the main process and the process 2 is the target process(i can't edit it by the way), i want to be able to call a function from the process 2 in the process 1, anyone have a nice way to do that?I was thinking in inject a dll with exports that calls that function and use GetProcAddress externally...Is that possible?Is that the best way to do it?
Thanks for the time.
The title and body of your question ask two subtly different questions.
Having one executable call a function that's contained in another executable is quite easy, at least if the name of the function in question has been exported. You can use LoadLibrary to load an executable just like you would a DLL, then use GetProcAddress to get the address of the function you want to call, and call it normally. Keep in mind, however, that the function may not work correctly without other initialization that happens before it's called inside its own executable.
Calling a function in the context of another process (not just in another executable) is considerably more work. The basic idea is to have a function that makes the call and (for example) writes a result to some memory shared with the process making the call. You then use CreateRemoteThread to have that function execute in the context of the process containing the function you need to call.
If the target process has been written to support it there are other methods such as COM that are intended to support this type of capability much more cleanly. They're generally preferable if available.
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 want to call a function from an executable. The only way to reach that process is to inject a dll in the parent process. I can inject a dll in the parent process but how do I call a function from the child process?
Something like
_asm
{
call/jmp address
}
doesnt work. I hope you understand what I mean.
If you are running inside the process, you need to know the offset of the function you want to call from the base of the module (the exe) which contains the function. Then, you just need to make a function pointer and call it.
// assuming the function you're calling returns void and takes 0 params
typedef void(__stdcall * voidf_t)();
// make sure func_offset is the offset of the function when the module is loaded
voidf_t func = (voidf_t) (((uint8_t *)GetModuleHandle('module_name')) + func_offset);
func(); // the function you located is called here
The solution you have will work on 32bit systems (inline assembly is not permitted in 64 bit) if you know the address of the function, but you'll need to make sure you implement the calling convention properly. The code above uses GetModuleHandle to resolve the currently loaded base of the module whose function you want to call.
Once you've injected your module into the running process ASLR isn't really an issue, since you can just ask windows for the base of the module containing the code you wish to call. If you want to find the base of the exe running the current process, you can call GetModuleHandle with a parameter of NULL. If you are confident that the function offset is not going to change, you can hard code the offset of the function you wish to call, after you've found the offset in a disassembler or other tool. Assuming the exe containing the function isn't altered, that offset will be constant.
As mentioned in the comments, the calling convention is important in the function typedef, make sure it matches the calling convention of the function you're calling.
Execution Fundamentals
To call a function you need an address or a interrupt number. The address is loaded into the Program Counter register and execution is transferred. Some processors allow for "Software Interrupts", in which the program executes a special instruction that invokes the software interrupt. This is the foundation for executing functions.
More Background -- Relative Addresses
There are two common forms of executables: Absolute Addressing and Relative (or Position Independ Code,PIC). In absolute addressing, the functions are at hard-coded addresses. The functions won't move. Usually used in embedded systems.
In the relative addressing model, the addresses are relative to the value in the Program Counter register. For example, your function may be 1024 bytes away, so the compiler would emit a relative branch instruction for 1024 bytes (away).
Operating Systems and Moving Targets
Many operating systems load programs in different places for each invocation. This means your executable may start at address 1000, and the next time at address 127654. In these operating systems, there is no guarantee that an executable will be launched at the same location each time.
Executing within your program
Executing functions within your program is easy. The linker decides where all the functions will be located and determines how to execute them; whether to use absolute addressing, PIC or a mixture.
Executing Functions in another Executable
With the above knowledge, there are issues with executing functions in another program:
Location of the Function in the external executable
Determining if the executable is active
Calling protocol for the executable
Most executables do not contain any information about where their functions are, so you will need to know where it is. You will also need to know if the function is absolute addressing or PIC. You will also need to know if the function is in memory when you need it or if the OS has paged the function to the hard drive.
Knowing the function location is necessary. However, the location is of no use if the OS has not loaded the executable. Before you call a function in another executable, you will need to know if it is present in memory when the call is executed.
Lastly, you will need to know the protocol used for the external function. For example, are the values passed by register? Are they on the stack? Are they passed by pointer (address)?
A Solution: Shared Libraries
Operating systems (OS) have evolved to allow for dynamically sharing of functions. These functions exist in Dynamically Linked Libraries (DLL) or Shared Library(.SO). Your program tells the OS to load the library into memory, then you tell the OS to execute the function by giving it the name of the function.
The caveat is that the function you desire must be in a library. If the executable doesn't use a shared library or the function you need is not in a library, then your mission is more difficult.
Is there a way to call a function, that resides in a dll, (the dll is injected into a process) from that process?
By this I mean if i have myDLL.dll that exports a function, lets say void f(){do sth} and a process myProcess, "myDLL.dll" is injected using CreateRemoteThread(), can I call f() from myProcess so actually myProcess is the "user" that initiated the call to this function ?
I need to do this because I want the function f() not to be dependent by a certain program that can be killed in Task Manager, since employes can find the process and kill it. My manager asked me to do this because he thinks employees are doing other things than work.
Just use the usual, LoadLibrary() and GetProcAddress()
What you want to do probably won't work, and isn't the right approach anyway. The correct solution for preventing users from killing a process can be found here.
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 an application that does not use the standard libraries. Instead, it uses stubs to call LoadLibrary/GetProcAddress, then calls functions via the resultant function pointers.
Using the above method my application is calling DoDragDrop in ole32.dll. The call is returning E_UNEXPECTED, which apparently means 'catastophic failure'.
What I want to ask is does anyone know of a way to discover what is happening inside the call to DoDragDrop? Specifically, can I discover what function or variable it is looking for but cannot find? (I am guessing that it wants access to some function or variable that is not loaded at the point I call DoDragDrop, and if I can explicitly load it the call will succeed.) Obviously I can't step into the call - attempting to just runs the function and steps to the line in my code following the DoDragDrop call.
:)
(I'm using VS2005 in XP.)
I recall having something like this occur when I had forgotten to call OleInitialize(Ex) / CoInitialize(Ex) for the thread making the call. Note the apartment must be STA.