// 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;
}


你可能感兴趣的文章

评论区

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。