Wednesday, March 9, 2011

Run our code in another process. Simple method with CreateRemoteThread & LoadLibrary

[Tip]
Inject our code into another process using CreateRemoteThread & LoadLibrary.

[Details]
In general, any process can load a DLL dynamically by using the LoadLibrary API. If we use CreateRemoteThread(), we can start LoadLibrary function in another process, in-effect our library will load in another process.
Both LoadLibrary and FreeLibray are functions residing in kernel32.dll. Because kernel32 is guaranteed to be present and at the same load address in every "normal" process , the address of LoadLibrary/FreeLibray is the same in every process too.
The steps to start a dll in another process.
1.       Retrieve a HANDLE to the remote process (OpenProcess).
2. Allocate memory for the DLL name in the remote process (VirtualAllocEx).
3. Write the DLL name, including full path, to the allocated memory (WriteProcessMemory).
4. Map your DLL to the remote process via CreateRemoteThread & LoadLibrary.
5. Wait until the remote thread terminates (WaitForSingleObject); this is until the call to LoadLibrary returns. Put another way, the thread will terminate as soon as our DllMain (called with reason DLL_PROCESS_ATTACH) returns.
6. Retrieve the exit code of the remote thread (GetExitCodeThread). Note that this is the value returned by LoadLibrary, thus the base address (HMODULE) of our mapped DLL.
7. Free the memory allocated in Step #2 (VirtualFreeEx).
8. Unload the DLL from the remote process via CreateRemoteThread & FreeLibrary. Pass the HMODULE handle retreived in Step #6 to FreeLibrary(via lpParameter in CreateRemoteThread).
Note: If your injected DLL spawns any new threads, be sure they are all terminated before unloading it.
9. Wait until the thread terminates (WaitForSingleObject).

Please check the attached sample application to demonstrate usage of CreateRemoteThread.
Run InjectApp, give any process ID to inject InjectLibrary.dll to that process.
InjectApp injects “InjectLibrary.dll” to the specifeid process[Provide process ID and process Inject button].
InjectLibrary creates a file from its DllMain(). This file logs current process id, just to prove this library started in another process.
 
// Implementation of InjectLibrary.dll
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                                            )
{
            switch (ul_reason_for_call)
            {
            case DLL_PROCESS_ATTACH:
        {
// Here prepares a file at D:\\File.txt, to prove which process loaded this library.
            FILE *pFIle = fopen( "D:\\File.txt", "w+" );
            fprintf( pFIle, "Dll Started From Process ID:%d", GetCurrentProcessId() );
            fclose(pFIle);
        }
            case DLL_THREAD_ATTACH:
            case DLL_THREAD_DETACH:
            case DLL_PROCESS_DETACH:
                        break;
            }
            return TRUE;
}


[Reference]
http://www.codeproject.com/KB/threads/winspy.aspx#section_3
http://www.codeproject.com/KB/threads/winspy.aspx
http://www.programmersheaven.com/2/Inject-code-to-Portable-Executable-file


Posted By : Santhosh G.

No comments:

Post a Comment