// x64 没有 pushad popad 所以把寄存器全部保护是最安全的~~~ unsigned char codeToInject[] = { // Placeholder for the return address 0x68, 0xAA, 0xAA, 0xAA, 0xAA, // push 0AAAAAAAAh // Save the flags 0x9c, // pushfq // Save the registers 0x50, // push rax 0x51, // push rcx 0x52, // push rdx 0x53, // push rbx 0x55, // push rbp 0x56, // push rsi 0x57, // push rdi 0x41, 0x50, // push r8 0x41, 0x51, // push r9 0x41, 0x52, // push r10 0x41, 0x53, // push r11 0x41, 0x54, // push r12 0x41, 0x55, // push r13 0x41, 0x56, // push r14 0x41, 0x57, // push r15 // Placeholder for the string address and LoadLibrary 0x48, 0xB9, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, // mov rcx, 0BBBBBBBBBBBBBBBBh 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, // mov rax, 0CCCCCCCCCCCCCCCCh // Call LoadLibrary with the string parameter 0xFF, 0xD0, // call rax // Restore the registers 0x41, 0x5F, // pop r15 0x41, 0x5E, // pop r14 0x41, 0x5D, // pop r13 0x41, 0x5C, // pop r12 0x41, 0x5B, // pop r11 0x41, 0x5A, // pop r10 0x41, 0x59, // pop r9 0x41, 0x58, // pop r8 0x5F, // pop rdi 0x5E, // pop rsi 0x5D, // pop rbp 0x5B, // pop rbx 0x5A, // pop rdx 0x59, // pop rcx 0x58, // pop rax // Restore the flags 0x9D, // popfq 0xC3 // ret }; int WINAPI inject_lib_cave( HANDLE hProcess, HANDLE hThread, const char* lib_name ) { void* dllString; void* stub; DWORD64 stubLen, loadLibAddr; DWORD oldIP; CONTEXT ctx; BOOL result = FALSE; DWORD suspend_result = -1; stubLen = sizeof( codeToInject ); loadLibAddr = (DWORD64)GetProcAddress( GetModuleHandleA("Kernel32"), "LoadLibraryA" ); dllString = VirtualAllocEx(hProcess, NULL, (strlen(lib_name) + 1), MEM_COMMIT, PAGE_READWRITE); stub = VirtualAllocEx(hProcess, NULL, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if( dllString == NULL || stub == NULL ) { if(dllString != NULL) free( dllString ); if(stub != NULL) free( stub ); MessageBoxA( NULL, "Virtual Alloc failed.", "My Msg", MB_OK ); goto clean_exit; } result = WriteProcessMemory(hProcess, dllString, lib_name, strlen(lib_name), NULL); if ( !result ) { MessageBoxA( NULL, "Could not write process memory for dllString.", "My Msg", MB_OK ); goto clean_exit; } suspend_result = SuspendThread( hThread ); if ( suspend_result == -1 ) { MessageBoxA( NULL, "Could not suspend thread.", "My Msg", MB_OK ); goto clean_exit; } ctx.ContextFlags = CONTEXT_CONTROL; GetThreadContext(hThread, &ctx); oldIP = (DWORD)ctx.Rip; ctx.Rip = (DWORD)stub; ctx.ContextFlags = CONTEXT_CONTROL; /* * Insert the addresses into the local copy of the codeToInject before copying it to * the remote process */ memcpy( codeToInject + 1, &oldIP, sizeof( oldIP ) ); memcpy( codeToInject + 31, &dllString, sizeof( dllString ) ); memcpy( codeToInject + 41, &loadLibAddr, sizeof( loadLibAddr ) ); result = WriteProcessMemory(hProcess, stub, codeToInject, stubLen, NULL); if ( !result ) { MessageBoxA( NULL, "Could not write process memory.", "My Msg", MB_OK ); goto clean_exit; } result = SetThreadContext(hThread, &ctx); if ( !result ) { MessageBoxA( NULL, "Could not set thread context.", "My Msg", MB_OK ); goto clean_exit; } clean_exit: if ( suspend_result > -1 ) { suspend_result = ResumeThread( hThread ); if ( suspend_result == -1 ) { MessageBoxA( NULL, "Could not resume thread.", "My Msg", MB_OK ); } } return result; }
发表评论