FARPROC CRemoteLoader::GetRemoteProcAddress( PCHAR Module, SHORT Function ) { HMODULE hKernel32 = LoadLibraryA( "Kernel32.dll" ); if( hKernel32 == NULL ) return NULL; DWORD GetProcAddressOffset = ( DWORD ) GetProcAddress - ( DWORD ) hKernel32; HMODULE hRemoteKernel32 = GetRemoteModuleHandleA( "Kernel32.dll" ); if( hRemoteKernel32 == NULL ) return NULL; HMODULE hRemoteModule = GetRemoteModuleHandleA( Module ); if( hRemoteModule == NULL ) return NULL; PVOID ReturnPointerValue = RemoteAllocateMemory( sizeof( DWORD ) ); PushInt( ( INT ) hRemoteModule ); // HACKHACK: Why is this an int? PushInt( ( INT ) Function ); PushCall( CCONV_STDCALL, ( FARPROC )( ( DWORD_PTR ) hRemoteKernel32 + ( DWORD_PTR ) GetProcAddressOffset ) ); //mov ptr, eax AddByteToBuffer( 0xA3 ); AddLongToBuffer( ( DWORD ) ReturnPointerValue ); //xor eax, eax AddByteToBuffer( 0x33 ); AddByteToBuffer( 0xC0 ); //retn 4 AddByteToBuffer( 0xC2 ); AddByteToBuffer( 0x04 ); AddByteToBuffer( 0x00 ); if( ExecuteRemoteThreadBuffer( m_CurrentRemoteThreadBuffer, true ) == false ) { RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); return NULL; } DWORD ProcAddressRemote = 0; if( ReadProcessMemory( GetProcess(), ReturnPointerValue, &ProcAddressRemote, sizeof( DWORD ), NULL ) == TRUE ) { RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); return ( FARPROC ) ProcAddressRemote; } RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); return NULL; }
void* CRemoteCode::CommitMemory( void *data, size_t size_of_data ) { void *pPointer = RemoteAllocateMemory((unsigned long)size_of_data); if( data != NULL ) { WriteProcessMemory( m_hProcess, pPointer, data, size_of_data, NULL ); } return pPointer; }
bool CRemoteCode::ExecuteRemoteThreadBuffer( remote_thread_buffer_t thread_data, bool async ) { unsigned long ulMemorySize = ( unsigned long )thread_data.size(); void *vRemoteMemory = RemoteAllocateMemory( ulMemorySize ); if( vRemoteMemory == NULL ) return false; unsigned char *newBuffer = new unsigned char[ thread_data.size() ]; for( int i = 0; i < (int)thread_data.size(); i++ ) { memcpy( &newBuffer[i], &thread_data[i], sizeof( unsigned char ) ); } BOOL bWriteProcess = WriteProcessMemory( m_hProcess, vRemoteMemory, newBuffer, thread_data.size(), NULL ); if( bWriteProcess == FALSE ) return false; DebugShout( "Memory written to process" ); HANDLE hThreadHandle = CreateRemoteThreadInProcess( ( LPTHREAD_START_ROUTINE )vRemoteMemory, NULL ); if( hThreadHandle == INVALID_HANDLE_VALUE ) return false; DebugShout( "Remote Buffer Executed in process 0x%X", m_hProcess ); if( async == true ) { WaitForSingleObject( hThreadHandle, INFINITE ); } RemoteFreeMemory( vRemoteMemory, ulMemorySize ); memset( &m_CurrentInvokeInfo, 0, sizeof( m_CurrentInvokeInfo ) ); m_CurrentRemoteThreadBuffer.clear(); return true; }
HMODULE CRemoteLoader::LoadLibraryByPathW( PWCHAR Path ) { if( Path == NULL ) { DebugShout( "[LoadLibraryByPathW] szString is NULL" ); return NULL; } FARPROC RemoteLoadLibraryW = GetRemoteProcAddress( "kernel32.dll", "LoadLibraryW" ); if( RemoteLoadLibraryW == NULL ) { DebugShout( "[LoadLibraryByPathW] LoadLibraryW Resolve Failure" ); return NULL; } DebugShout( "[LoadLibraryByPathW] LoadLibraryW = 0x%X", RemoteLoadLibraryW ); PVOID ReturnPointerValue = RemoteAllocateMemory( sizeof( DWORD ) ); PushUNICODEString( Path ); PushCall( CCONV_STDCALL, RemoteLoadLibraryW ); //mov ptr, eax AddByteToBuffer( 0xA3 ); AddLongToBuffer( ( DWORD ) ReturnPointerValue ); //xor eax, eax AddByteToBuffer( 0x33 ); AddByteToBuffer( 0xC0 ); //retn 4 AddByteToBuffer( 0xC2 ); AddByteToBuffer( 0x04 ); AddByteToBuffer( 0x00 ); if( ExecuteRemoteThreadBuffer( m_CurrentRemoteThreadBuffer, true ) == false ) { DebugShout( "[LoadLibraryByPathW] ExecuteRemoteThreadBuffer failed" ); RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); return NULL; } DebugShout( "[LoadModuleByNameW] ExecuteRemoteThreadBuffer succeeded" ); DWORD RemoteModuleHandle = 0; if( ReadProcessMemory( GetProcess(), ReturnPointerValue, &RemoteModuleHandle, sizeof( DWORD ), NULL ) == TRUE ) { RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); } else { RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) ); if( RemoteModuleHandle == 0 ) { RemoteModuleHandle = ( DWORD ) GetRemoteModuleHandleW( Path ); } } return ( HMODULE ) RemoteModuleHandle; }
HMODULE CRemoteLoader::LoadLibraryFromMemory( PVOID BaseAddress, DWORD SizeOfModule, BOOL PEHeader, PCHAR OptionalPath ) { DebugShout( "[LoadLibraryFromMemory] BaseAddress (0x%X) - SizeOfModule (0x%X)", BaseAddress, SizeOfModule ); IMAGE_NT_HEADERS* ImageNtHeaders = ToNts( BaseAddress ); if( ImageNtHeaders == NULL ) { DebugShout( "[LoadLibraryFromMemory] Invalid Image: No IMAGE_NT_HEADERS" ); return NULL; } DebugShout( "[LoadLibraryFromMemory] SizeOfImage (0x%X)", ImageNtHeaders->OptionalHeader.SizeOfImage ); if( ImageNtHeaders->FileHeader.NumberOfSections == 0 ) { DebugShout( "[LoadLibraryFromMemory] Invalid Image: No Sections" ); return NULL; } if( ( ImageNtHeaders->OptionalHeader.ImageBase % 4096 ) != 0 ) { DebugShout( "[LoadLibraryFromMemory] Invalid Image: Not Page Aligned" ); return NULL; } if( ImageNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ].Size ) { if( ImageDirectoryEntryToData( BaseAddress, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ) ) { DebugShout( "[LoadLibraryFromMemory] This method is not supported for Managed executables!" ); return NULL; } } DebugShout( "[LoadLibraryFromMemory] No COM/CLR data found!" ); // SizeOfImage NOT the same as module size M**********R // http://www.youtube.com/watch?v=pele5vptVgc PVOID AllocatedRemoteMemory = RemoteAllocateMemory( ImageNtHeaders->OptionalHeader.SizeOfImage ); if( AllocatedRemoteMemory == NULL ) { DebugShout( "[LoadLibraryFromMemory] Failed to allocate remote memory for module!" ); return NULL; } DebugShout( "[LoadLibraryFromMemory] Allocated remote module at [0x%X]!", AllocatedRemoteMemory ); if( ProcessImportTable( BaseAddress, AllocatedRemoteMemory, OptionalPath ) == FALSE ) { DebugShout( "[LoadLibraryFromMemory] Failed to fix imports!" ); return NULL; } DebugShout( "[LoadLibraryFromMemory] Fixed Imports!" ); if( ProcessRelocations( BaseAddress, AllocatedRemoteMemory ) == FALSE ) { DebugShout( "[LoadLibraryFromMemory] Failed to process relocations!" ); RemoteFreeMemory( AllocatedRemoteMemory, SizeOfModule ); return NULL; } DebugShout( "[LoadLibraryFromMemory] Fixed Relocations!" ); if( ProcessSections( BaseAddress, AllocatedRemoteMemory, PEHeader ) == FALSE ) { DebugShout( "[LoadLibraryFromMemory] Failed to process sections!" ); } DebugShout( "[LoadLibraryFromMemory] Processed sections!" ); if( ProcessTlsEntries( BaseAddress, AllocatedRemoteMemory ) == FALSE ) { DebugShout( "[LoadModuleFromMemory] ProcessTlsEntries Failed!" ); // we can also choose to continue here.. return NULL; } DebugShout( "[LoadModuleFromMemory] Processed Tls Entries!" ); if( ImageNtHeaders->OptionalHeader.AddressOfEntryPoint ) { FARPROC DllEntryPoint = MakePtr( FARPROC, AllocatedRemoteMemory, ImageNtHeaders->OptionalHeader.AddressOfEntryPoint ); DebugShout( "[LoadModuleFromMemory] DllEntrypoint = 0x%X", DllEntryPoint ); if( CallEntryPoint( AllocatedRemoteMemory, DllEntryPoint ) == false ) { DebugShout( "[LoadModuleFromMemory] Failed to execute remote thread buffer" ); } else { DebugShout( "[LoadModuleFromMemory] Executed the remote thread buffer successfully [0x%X]", DllEntryPoint ); } } else { DebugShout( "[LoadModuleFromMemory] AddressOfEntryPoint is NULL" ); } DebugShout( "[LoadModuleFromMemory] Returning Pointer (0x%X)", AllocatedRemoteMemory ); return ( HMODULE ) AllocatedRemoteMemory; }