Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <stdio.h>
- DWORD Inject( HANDLE hProcess,const char* dllPath,const char* functionName );
- int main( int argc,char* argv[ ] ) {
- if( argc < 3 ) {
- printf( "Usage: Inject <executable> <injected DLL>\n" );
- return 1;
- }
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- char szLibPath[ MAX_PATH + 1 ];
- // Start our process in suspended mode
- ZeroMemory( &si,sizeof( si ) );
- ZeroMemory( &pi,sizeof( pi ) );
- CreateProcess( argv[ 1 ],NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi );
- printf( "Process created\n" );
- DWORD exitCode = Inject( pi.hProcess,argv[ 2 ],"HotpatchMessageBox" );
- printf( "Injection returned with exit code %d\n",exitCode );
- // Resume the primary thread of our process
- ResumeThread( pi.hThread );
- }
- DWORD Inject( HANDLE hProcess,const char* dllPath,const char* functionName ) {
- // Get the address of the KERNEL32.DLL
- HMODULE kernel32 = LoadLibrary( "KERNEL32.DLL" );
- // Get needed functions
- FARPROC loadlibrary = GetProcAddress( kernel32,"LoadLibraryA" );
- FARPROC getprocaddress = GetProcAddress( kernel32,"GetProcAddress" );
- FARPROC exitthread = GetProcAddress( kernel32,"ExitThread" );
- // Create the workspace
- LPBYTE workspace = ( LPBYTE ) HeapAlloc( GetProcessHeap( ),HEAP_ZERO_MEMORY,1024 );
- // Allocate space for the codecave in the process
- LPVOID codecaveAddress = VirtualAllocEx( hProcess,0,1024,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE );
- DWORD dwCodecaveAddress = PtrToUlong( codecaveAddress );
- DWORD workspaceIndex = 0;
- DWORD dwTmpSize = 0;
- // First, let's define some data and room for pointers
- // Leave a 4-bytes slot for DLL address
- DWORD dllAddr = dwCodecaveAddress + workspaceIndex;
- workspaceIndex += 4;
- // A slot for function name
- DWORD funcNameAddr = dwCodecaveAddress + workspaceIndex;
- dwTmpSize = ( DWORD ) strlen( functionName ) + 1;
- memcpy( workspace + workspaceIndex,functionName,dwTmpSize );
- workspaceIndex += dwTmpSize;
- // A slot for DLL path
- DWORD dllPathAddr = workspaceIndex + dwCodecaveAddress;
- dwTmpSize = ( DWORD ) strlen( dllPath ) + 1;
- memcpy( workspace + workspaceIndex,dllPath,dwTmpSize );
- workspaceIndex += dwTmpSize;
- // Store where the codecave execution should begin
- DWORD startAddress = workspaceIndex + dwCodecaveAddress;
- // Actual executable instructions start here
- // PUSH 0x00000000 - Push the address of the DLL path to use in LoadLibraryA
- workspace[ workspaceIndex++ ] = 0x68;
- memcpy( workspace + workspaceIndex,&dllPathAddr,4 );
- workspaceIndex += 4;
- // MOV EAX, ADDRESS - Move the address of LoadLibraryA into EAX
- workspace[ workspaceIndex++ ] = 0xB8;
- memcpy( workspace + workspaceIndex,&loadlibrary,4 );
- workspaceIndex += 4;
- // CALL EAX - Call LoadLibraryA
- workspace[ workspaceIndex++ ] = 0xFF;
- workspace[ workspaceIndex++ ] = 0xD0;
- // MOV [ADDRESS], EAX - Save the address to our variable
- workspace[ workspaceIndex++ ] = 0xA3;
- memcpy( workspace + workspaceIndex,&dllAddr,4 );
- workspaceIndex += 4;
- // PUSH 0x000000 - Push the address of the function name to load
- workspace[ workspaceIndex++ ] = 0x68;
- memcpy(workspace + workspaceIndex,&funcNameAddr,4 );
- workspaceIndex += 4;
- // Push EAX, module to use in GetProcAddress
- workspace[ workspaceIndex++ ] = 0x50;
- // MOV EAX, ADDRESS - Move the address of GetProcAddress into EAX
- workspace[ workspaceIndex++ ] = 0xB8;
- memcpy( workspace + workspaceIndex,&getprocaddress,4 );
- workspaceIndex += 4;
- // CALL EAX - Call GetProcAddress. Address will be in EAX.
- workspace[workspaceIndex++] = 0xFF;
- workspace[workspaceIndex++] = 0xD0;
- // CALL EAX - Call requested function by using it's address from EAX.
- workspace[workspaceIndex++] = 0xFF;
- workspace[workspaceIndex++] = 0xD0;
- // Push 0 (exit code)
- workspace[ workspaceIndex++ ] = 0x6A;
- workspace[ workspaceIndex++ ] = 0x00;
- // MOV EAX, ADDRESS - Move the address of ExitThread into EAX
- workspace[ workspaceIndex++ ] = 0xB8;
- memcpy( workspace + workspaceIndex,&exitthread,4 );
- workspaceIndex += 4;
- // CALL EAX - Call ExitThread
- workspace[workspaceIndex++] = 0xFF;
- workspace[workspaceIndex++] = 0xD0;
- DWORD oldProtect = 0;
- DWORD bytesRet = 0;
- VirtualProtectEx( hProcess,codecaveAddress,workspaceIndex,PAGE_EXECUTE_READWRITE,&oldProtect );
- // Write out the patch
- WriteProcessMemory( hProcess,codecaveAddress,workspace,workspaceIndex,&bytesRet );
- // Restore page protection
- VirtualProtectEx( hProcess,codecaveAddress,workspaceIndex,oldProtect,&oldProtect );
- // Make sure our changes are written right away
- FlushInstructionCache( hProcess,codecaveAddress,workspaceIndex );
- HeapFree( GetProcessHeap( ),0,workspace );
- HANDLE hThread = CreateRemoteThread( hProcess,NULL,0,
- ( LPTHREAD_START_ROUTINE ) ( void* ) startAddress,0,0,NULL );
- // Wait for our thread to terminate
- WaitForSingleObject( hThread,INFINITE );
- // Get exit code from our remote thread
- DWORD exitCode = 0;
- GetExitCodeThread( hThread,&exitCode );
- // And finally close the handle
- CloseHandle( hThread );
- // Free the memory in the process that we allocated
- VirtualFreeEx( hProcess,codecaveAddress,0,MEM_RELEASE );
- return exitCode;
- }
Advertisement
Add Comment
Please, Sign In to add comment