【软件逆向】如何在windows下远程注入dll并进行虚表hook

需要准备的工具

  1. Microsoft Visual Studio开发工具。
  2. IDA pro动态调试工具。
  3. Process Hacker 2进程监控工具。
  4. 被远程注入的exe程序。(以crackme.exe为例)

远程注入dll进行虚表hook

一、IDA pro反编译找到函数逻辑地址

  1. 使用IDA pro打开crackme.exe,开启动态调试。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第1张图片
  2. 找到需要hook的地方,一般是系统库里的函数,以jmp cs:EnterCriticalSection为例。(其中EnterCriticalSection可以是其他系统函数)
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第2张图片
  3. 双击函数名,找到其真实地址为0x7ff6472bd0c8。
    在这里插入图片描述
  4. 找到程序的起始地址为0x7ff6472a0000。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第3张图片
  5. 可以计算得出EnterCriticalSection函数相对程序入口的逻辑地址为0x7ff6472bd0c8-0x7ff6472a0000=0x1d0c8。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第4张图片

二、VS编写虚表hook动态链接库

  1. 打开Visual Studio,创建一个DLL项目。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第5张图片
  2. 将dllmain.cpp修改为以下代码,其中其中0x1d0c8修改为第一步中函数逻辑地址,Hooked_VtableFunc函数中写自己想要执行的代码。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include 
#include 
#include 
typedef void(__fastcall* VtableFunc_t)();
VtableFunc_t VtableFunc = nullptr;

// 需要执行的函数
void __fastcall Hooked_VtableFunc() {
    printf("正确\n");
    system("pause");
    return VtableFunc();
}

void HookVtableTest() {
    uintptr_t VtableAddress = (uintptr_t)GetModuleHandleA(0) + 0x1d0c8; //其中0x1d0c8修改为第一步中函数逻辑地址
    DWORD old_protect = 0;
    VirtualProtect((LPVOID)VtableAddress, 0x8, PAGE_EXECUTE_READWRITE, &old_protect);
    *(uintptr_t*)(VtableAddress) = (uintptr_t)Hooked_VtableFunc;
    VirtualProtect((LPVOID)VtableAddress, 0x8, old_protect, &old_protect);
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        HookVtableTest(); break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
  1. 生成解决方案后,可以得到虚表hook的dll文件。dll文件一般在“项目路径/x64/Debug/”。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第6张图片

三、VS编写远程注入代码

  1. 打开Visual Studio,创建一个控制台应用。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第7张图片
  2. 将以下代码复制到cpp源文件中,其中main函数的第一行wStr变量修改为第二步中生成的dll的路径(windows路径下的\需要用\转译),第二行修改为进程名(可以打开任务管理器查看)。
#include 
#include 
#include 
#include 
#include 
using namespace std;

bool Inject(DWORD dwId, WCHAR* szPath)//参数1:目标进程PID  参数2:DLL路径
{
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId);
    LPVOID pRemoteAddress = VirtualAllocEx(
        hProcess,
        NULL,
        wcslen(szPath) * 2,
        MEM_COMMIT,
        PAGE_READWRITE
    );
    DWORD dwWriteSize = 0;
    BOOL bRet = WriteProcessMemory(hProcess, pRemoteAddress, szPath, wcslen(szPath) * 2, NULL);
    HMODULE hModule = GetModuleHandle(L"kernel32.dll");
    if (!hModule)
    {
        printf("GetModuleHandle Error !\n");
        GetLastError();
        CloseHandle(hProcess);
        return FALSE;
    }
    LPTHREAD_START_ROUTINE dwLoadAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryW");
    if (!dwLoadAddr)
    {
        printf("GetProcAddress Error !\n");
        CloseHandle(hProcess);
        CloseHandle(hModule);
        return FALSE;
    }

    HANDLE hThread = CreateRemoteThread(
        hProcess,
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)dwLoadAddr,
        pRemoteAddress,
        NULL,
        NULL
    );
    return 0;
}
DWORD GetPid(WCHAR* szName)
{
    HANDLE hprocessSnap = NULL;
    PROCESSENTRY32  pe32 = { 0 };
    hprocessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (Process32First(hprocessSnap, &pe32))
    {
        do {
            if (!wcscmp(szName, pe32.szExeFile))
                return (int)pe32.th32ProcessID;
        } while (Process32Next(hprocessSnap, &pe32));
    }
    else
        CloseHandle(hprocessSnap);
    return 0;
}

int main()
{
    wchar_t wStr[] = L"C:\\Users\\zhang\\source\\repos\\crackme_dll\\x64\\Release\\crackme_dll.dll";
    WCHAR S[] = L"crackme.exe";
    DWORD SS = GetPid(S);
    printf("目标窗口的进程PID为:%d\n", SS);
    Inject(SS, wStr);
    return 0;
}
  1. 生成解决方案后,可以得到远程注入的exe文件。exe文件一般在“项目路径/x64/Debug/”。

四、远程注入dll并使用Process Hack 2观察注入结果

  1. 管理员运行crackme.exe,管理员运行Process Hacker 2,搜索crackme,并查看Modules,可以看到没有我们注入的dll。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第8张图片
  2. 管理员运行第三步中exe程序,再次打开Process Hacker 2,可以看到crackme_dll.dll已经注入成功。
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第9张图片
  3. 可以看到第二步代码中Hooked_VtableFunc函数成功执行
    【软件逆向】如何在windows下远程注入dll并进行虚表hook_第10张图片
    如果帮到你了,麻烦点个赞。如果暂时用不到,不妨也收藏以下,可能以后会有用。教程中有错误的地方也麻烦留言或私信指正,尽量及时修正。

你可能感兴趣的:(软件逆向)