3

I wrote dll injection program that works just fine. It loads dll into remote process and calls some function. Now i want to pass argument to that function. CreateRemoteThread has lpParameter for that, but how to get that passed argument inside dll to use it in function?

Update: dll entry point is common:

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)

Dll contains only one function with following prototype:

void TestFunction(const char* ua);

Code that calls that function is:

CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((void*)codecaveExecAddr), (LPVOID)argumentAddress, 0, NULL);

As you can see i try to pass "test" string inside TestFunction. But then i check ua argument inside TestFunction it contains some trash.

Here are the whole project files:
http://pastebin.com/gh4SnhmV
http://pastebin.com/Sq7hpSVx
http://pastebin.com/dvgXpUYz

UPDATE 2
Should TestFunction have some specific propotype or i can use any as long as it has only one parameter of LPVOID type? I'm confused. Can anyone give me an example of how to call injected dll's function with some argument?

clumpter
  • 1,898
  • 6
  • 27
  • 38
  • Cast it, dereference it, use it. – Kerrek SB Jul 05 '11 at 11:50
  • @Kerrek SB sorry, i don't understand what you mean. cast what? – clumpter Jul 05 '11 at 11:52
  • 1
    Sorry, I was being facetious. You asked a question with zero details or code and expected us to know what's in your mind, so I gave an answer in the same spirit. The real answer is, "post your code and be specific". – Kerrek SB Jul 05 '11 at 11:56
  • 1
    @Kerrek SB i gave all details to answer my question. There is no need to post whole dll code here since algorithm of passing argument to dll with CreateRemoteThread and extracting it in dll stays the same. Your answer wasn't smart. – clumpter Jul 05 '11 at 13:49

1 Answers1

6

You need to allocate the data inside the other process' memory. For that, use the VirtualAllocEx function which will return the address in the other process memory, that you pass to CreateRemoteThread.

CreateRemoteThread works exactly the same way as CreateThread, except that it creates the thread in the remote process. One thing to keep in mind is that when you are passing a pointer to an object in lpParameter the remote thread, which is running in a different virtual address space will try to access that address in that address space.

Grim
  • 937
  • 10
  • 24
  • 3
    Don't forget to WriteProcessMemory the string itself since that is what will be passed to LoadLibrary – Mike Kwan Jul 05 '11 at 12:30
  • I don't understand. CreateRemoteThread already has lpParameter that allows to pass 1 parameter to called function. Why do i need something else? I just want to know how to get that passed argument in called function. – clumpter Jul 05 '11 at 13:56
  • What is the type of the data that you want to pass? If it is a simple DWORD you can use that argument to pass it to the remote function. If it is something bigger than a DWORD you will have to allocate the memory block in the remote process – Grim Jul 05 '11 at 15:39
  • It's simple char string i pass – clumpter Jul 05 '11 at 15:44
  • You can't pass a char string. And LoadLibrary doesn't take a char string either. It takes a pointer to one which is what Grim has already explained. – Mike Kwan Jul 05 '11 at 15:54
  • 2
    Clumpter, you receive the parameter just like you receive parameters in any other function. When the OS calls your thread routine, it forwards the parameter you passed to CreateRemoteThread. You'll receive exactly what you pass. If the parameter is a pointer (which char strings are), then it's more complicated than usual because separate processes have separate address spaces, and addresses in the calling program might not be valid in the remote process. In the caller, you need to make sure the address you pass will be valid in the remote thread. VirtualAllocEx and WriteProcessMemory do that. – Rob Kennedy Jul 05 '11 at 16:00
  • @Rob Kennedy could you please give an example how to allocate space for some string in other process address space? – clumpter Jul 05 '11 at 16:16
  • @clumpter I just Googled "VirtualAllocEx" and the first two results were associated documentation, the third looks like it might provide a decent example for you, or at least point you in the right direction. [here](http://www.governmentsecurity.org/forum/index.php?showtopic=15931) – Loduwijk Jul 05 '11 at 16:35
  • Ok, i added following lines: LPVOID argumentAddress = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); WriteProcessMemory(hProcess, argumentAddress, "1234567\0", 8, &bytesRet); but argument ua in TestFunction still contains some trash, not "1234567". Am i right that passed in CreateRemoteThread function parameter is recieved in TestFunction argument? – clumpter Jul 05 '11 at 20:02
  • Yes, you are right about that. If you print the address of ua it should be the same as the address of argumentAddress. – Grim Jul 06 '11 at 09:04