【问题标题】:How to hook an exe function?如何挂钩一个exe函数?
【发布时间】:2020-03-28 19:21:24
【问题描述】:

我需要从一个程序中得到一些东西。在 ollydbg 和 IDA 的帮助下,我发现我能得到的“东西”在一个名为 sub_HEXHEX 的函数中。

现在我知道如何从 Dll 中挂钩一个函数,例如 DrawTextA 或其他函数。 我需要获取函数地址

HMODULE hmod = LoadLibrary(L"User32.dll");
GetProcAddress(hmod, "DrawTextA")

但是当我需要挂钩这个sub_HEXHEX 时,我感到困惑。我可以得到那个 exe 的 HANDLE,我知道函数的地址(那个 0x00HEXHEX),但是没有 GetProcAddress 我可以使用。我尝试使用 HANDLE + 0x00HEXHEX 作为函数的地址,但我认为我对“偏移”的东西有误。

这就是我所做的

DWORD dwPid = GetCurrentProcessId();  
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPid);  
OldA2ECB0 = (sub_A2ECB0)((HMODULE)hProcess + 0xA2ECB0);  
pfOldA2ECB0 = (FARPROC)OldA2ECB0;

还有 sub_A2ECB0

typedef int(*sub_A2ECB0)(LPCSTR param1, int param2);

但 pfOldA2ECB0 将为 NULL。
我对 C++ 和 Win32(英语也是)的知识很差,所以这对我来说太难了。

【问题讨论】:

  • 没有GetProcAddress可以使用是什么意思?
  • @jkb 目标函数不是 DLL 中的导出函数,它是 EXE 中的函数。 GetProcAddress()不能用于获取此类函数的地址。
  • 雷米回答你的问题,这就是我的意思。谢谢。
  • 如果您知道函数的相对虚拟地址 (RVA),那么您可以使用 module_base + RVA 计算其在进程地址空间中的地址。如果这对你不起作用,那么你做错了。由于我们看不到该代码,因此我们无能为力。
  • 进程句柄不是模块句柄。向进程句柄添加内存偏移是无意义的操作。您需要致电 GetModuleHandle。一旦你放弃了 C 风格的强制转换,编译器就会帮助你。此外,您的函数指针 typedef 缺少调用约定。

标签: c++ winapi hook


【解决方案1】:

据我了解,我相信我正确理解您想要的是内部挂钩

我可以通过 3 个简单的步骤向您展示如何做到这一点。

这些是你必须了解的:

  • IDA中显示的函数没有导出,因此不能使用GetProcAddress()
  • 您必须在远程进程的上下文中才能挂钩内部函数
  • 你不能使用像 Detours 这样的库,你必须有自己的钩子方法/函数

这些是您必须执行的步骤:

  1. 使用远程进程的上下文,最简单的方法:注入您的 dll。
  2. 从 IDA 获取地址偏移量,在您的情况下是 00A2ECB0。
  3. 只需在远程进程中应用一次钩子:

    //0xE8指令为相对调用指令 SetCompleteHook(0xE8,0x00A2ECB0,&YOUR_OWN_FUNCTION);

助手:

void SetCompleteHook(BYTE head,DWORD offset,...)
{
    DWORD OldProtect;

    VirtualProtect((void*)offset,5,PAGE_EXECUTE_READWRITE,&OldProtect);

    if(head != 0xFF)
    {
        *(BYTE*)(offset) = head;
    }

    DWORD* function = &offset+1;

    *(DWORD*)(offset+1) = (*function)-(offset+5);

    VirtualProtect((void*)offset,5,OldProtect,&OldProtect);
}

就是这样,它在您的场景中尽可能简单明了。

您当然可以走得更远,执行更复杂的内部挂钩,但为了您的学习目的,这是一个巨大的进步和起点。

享受吧!

【讨论】:

  • 我试过你说的,我成功了,非常感谢!但是我发现了一个新问题,该应用程序现在显示错误external exception C000001D,我认为原因是我没有将其称为A2ECB0()。我做了一些搜索,但直到现在我都无法解决。
  • 这取决于该函数的作用,您必须检查 IDA 以查看它返回的内容。您还必须确保您没有破坏该功能。如果您挂钩了该函数并且它没想到它会出现,应用程序也可能会显示异常......有很多变量。你能做的就是测试。您还可以使用不同的操作码进行测试,例如 0xE9。
  • 我正在使用((int(*)(DWORD *a1, int a2))0x00A2ECB0)(param1,param2) 进行测试。我将进一步了解 asm,非常感谢。
  • 没问题,但是如果您需要更多帮助,则必须将代码放在 pastebin 或其他东西上。
猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2014-10-13
  • 2013-01-06
  • 1970-01-01
相关资源
最近更新 更多