32位进程注入64位进程

Home / C++ MrLee 7月前 204

远程线程注入的做法是通过API:CreateRemoteThread在目标进程创建远程线程,让这个线程实现LoadLibrary去加载动态库。LoadLibrary函数通过kernel32导出,在32位和64位下的地址是不同的,所以一般来说32位是无法注入64位的。

在github上有一个开源项目rewolf-wow64ext,该项目的目的是让运行在Wow64下的32位程序可以调用x64下的API。

具体方法是通过该库的函数导出LdrLoadDll,RtlCreateUserThread,RtlExitUserThread三个API,RtlCreateUserThread创建远程线程,LdrLoadDll加载动态库,RtlExitUserThread退出远程线程。代码如下:

// Wow64Injectx64.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include "shlwapi.h"
#include "wow64ext.h"
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"wow64ext.lib")
using namespace std;
// 
unsigned char ShellCode[] = {
    0x48, 0x89, 0x4c, 0x24, 0x08,                               // mov       qword ptr [rsp+8],rcx 
    0x57,                                                       // push      rdi
    0x48, 0x83, 0xec, 0x20,                                     // sub       rsp,20h
    0x48, 0x8b, 0xfc,                                           // mov       rdi,rsp
    0xb9, 0x08, 0x00, 0x00, 0x00,                               // mov       ecx,8
    0xb8, 0xcc, 0xcc, 0xcc, 0xcc,                               // mov       eac,0CCCCCCCCh
    0xf3, 0xab,                                                 // rep stos  dword ptr [rdi]
    0x48, 0x8b, 0x4c, 0x24, 0x30,                               // mov       rcx,qword ptr [__formal]
    0x49, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       r9,0  //PVOID*  BaseAddr opt
    0x49, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       r8,0  //PUNICODE_STRING Name
    0x48, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       rdx,0
    0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       rcx,0
    0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       rax,0 
    0xff, 0xd0,                                                 // call      rax   LdrLoadDll
    0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       rcx,0
    0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov       rax,0
    0xff, 0xd0                                                  // call      rax
};
BOOL Wow64Injectx64(DWORD ProcessID, const TCHAR* FilePath);
int main()
{
    cout << "Input ProcessID" << endl;
    ULONG_PTR ProcessID = 0;
    cin >> ProcessID;
    WCHAR FilePath[] = L"C:\\Users\\ChangSungsin\\Desktop\\测试\\Injectx64\\Injectx64\\Dll.dll";
    if (Wow64Injectx64(ProcessID, FilePath))
    {
        cout << "Inject Success" << endl;
    }
    else
    {
        cout << "Failed to Inject" << endl;
    }
    return 0;
}
BOOL Wow64Injectx64(DWORD ProcessID, const TCHAR* FilePath)
{
    if (!PathFileExists(FilePath))
    {
        return FALSE;
    }
    HANDLE hTarget = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, ProcessID);
    if (INVALID_HANDLE_VALUE == hTarget)
    {
        return FALSE;
    }
    SIZE_T    FilePathLength        = (SIZE_T)::_tcslen(FilePath);
    SIZE_T    ParamemterSize        = (FilePathLength + 1)*sizeof(TCHAR) + sizeof(_UNICODE_STRING_T<DWORD64>) + sizeof(DWORD64);
    DWORD64    ParamemterMemAddr    = (DWORD64)VirtualAllocEx64(hTarget, NULL, ParamemterSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    DWORD64 ShellCodeAddr        = (DWORD64)VirtualAllocEx64(hTarget, NULL, sizeof(ShellCode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if ((!ParamemterMemAddr) || (!ShellCodeAddr))
    {
        return FALSE;
    }
    char* ParamemterMemLocal = new char[ParamemterSize];
    memset(ParamemterMemLocal, 0, ParamemterSize);
    _UNICODE_STRING_T<DWORD64>* UnicodeString    = (_UNICODE_STRING_T<DWORD64>*)(ParamemterMemLocal + sizeof(DWORD64));
    UnicodeString->Length            = FilePathLength * sizeof(wchar_t);
    UnicodeString->MaximumLength    = (FilePathLength +1)* 2;
    wcscpy((WCHAR*)(UnicodeString + 1), FilePath);
    UnicodeString->Buffer = ParamemterMemAddr + sizeof(DWORD64) + sizeof(_UNICODE_STRING_T<DWORD64>);
    DWORD64 Ntdll64                        = GetModuleHandle64(L"ntdll.dll");
    DWORD64 NtdllLdrLoadDll                = GetProcAddress64(Ntdll64, "LdrLoadDll");
    DWORD64 NtdllRtlCreateUserThread    = GetProcAddress64(Ntdll64, "RtlCreateUserThread");
    DWORD64 NtdllRtlExitThread            = GetProcAddress64(Ntdll64, "RtlExitUserThread");
    if (NtdllLdrLoadDll == NULL || NtdllRtlCreateUserThread == NULL || NtdllRtlExitThread == NULL)
    {
        return FALSE;
    }
    // DWORD转char
    union {
        DWORD64 from;
        unsigned char to[8];
    }Convert;
    // 写入r9寄存器
    Convert.from = ParamemterMemAddr;
    memcpy(ShellCode + 32, Convert.to, sizeof(Convert.to));
    // 写入r8寄存器
    Convert.from = ParamemterMemAddr + sizeof(DWORD64);
    memcpy(ShellCode + 42, Convert.to, sizeof(Convert.to));
    // 写入LdrLoadDll地址
    Convert.from = NtdllLdrLoadDll;
    memcpy(ShellCode + 72, Convert.to, sizeof(Convert.to));
    // 写入NtdllRtlExitThread地址
    Convert.from = NtdllRtlExitThread;
    memcpy(ShellCode + 94, Convert.to, sizeof(Convert.to));
    SIZE_T WriteSize = 0;
    if (!WriteProcessMemory64(hTarget, ParamemterMemAddr, ParamemterMemLocal, ParamemterSize, NULL) ||
        !WriteProcessMemory64(hTarget, ShellCodeAddr, ShellCode, sizeof(ShellCode), NULL))
    {
        return FALSE;
    }
    DWORD64 hRemoteThread = 0;
    struct {
        DWORD64 UniqueProcess;
        DWORD64 UniqueThread;
    }ClientID;
    int nRet = X64Call(NtdllRtlCreateUserThread, 10,
        (DWORD64)hTarget,                    // ProcessHandle
        (DWORD64)NULL,                      // SecurityDescriptor
        (DWORD64)FALSE,                     // CreateSuspended
        (DWORD64)0,                         // StackZeroBits
        (DWORD64)NULL,                      // StackReserved
        (DWORD64)NULL,                      // StackCommit
        ShellCodeAddr,                        // StartAddress
        (DWORD64)NULL,                      // StartParameter
        (DWORD64)&hRemoteThread,            // ThreadHandle
        (DWORD64)&ClientID);                // ClientID)
    if (hRemoteThread != 0) 
    {
        CloseHandle((HANDLE)hRemoteThread);
        return TRUE;
    }
    return TRUE;
}


本文链接:https://www.it72.com/12733.htm

上传的附件:
推荐阅读
最新回复 (0)
返回