c++ - 弯路 - jmp 00000000

标签 c++ assembly reverse-engineering detours

这是我正在使用的代码:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <detours.h>
#include <fstream>

#define real_sendto 0x152942C6
void(__cdecl* originalFunction)();

void tompa_sendto() {
    printf("Hellooo");
    return originalFunction();
}

void hook() {
    originalFunction = (void(__cdecl*)())DetourFunction((PBYTE)real_sendto, (PBYTE)tompa_sendto);
}


BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH: hook(); break;
        case DLL_PROCESS_DETACH: return FALSE; break;
    }
    return TRUE;
}

这段代码没有问题,它将钩子(Hook)放在0x152942C6处,我可以看到它跳转到我的tompa_sendto()并再次返回。

当我使用此代码作为 Hook 时,它没有正确设置 Hook ,
在内存中我可以在0x152942C6处看到:jmp 00000000

void tompa_sendto() {
    char buffer[] = {'x', 'y', 'z'};
    return originalFunction();
}

无论我在 tompa_sendto() 中放置什么代码都会使程序崩溃(因为 jmp 错误),我设法放置的唯一 2 个代码是 printf 和 messageBoxA。

最佳答案

我能够重现这个问题(尽管只有 detours 1.5),所以我做了一些挖掘。看来问题只是你的绕行函数是空的。

当您通过从另一个调用返回来结束调用时,编译器会进行特定的优化:它不会调用该函数,而是通过跳转而不是调用来直接延迟控制。这不会推送返回地址,因此,当下一个函数返回时,它使用前一个函数的返回地址,并同时从两个函数返回。长话短说,函数以 jmp func 结尾,而不是 call func; ret.

现在,当你的函数为空时,这个跳转是函数中唯一的指令。另一个事实是,您通过变量调用原始函数,这转化为间接跳转。问题是,Detours 1.5 专门检查您的函数是否以间接跳转开始,如果是,它会根据找到的间接跳转通过直接跳转来 Hook 目标函数。为什么 ?因为许多函数(例如 DLL 调用)都是通过间接跳转表调用的,如果 Detours 找到一个跳转表,就会尝试快捷方式。

在您的情况下,目标函数通过跳转到 originalFunction 进行 Hook ,但当您安装 Hook 时此变量为 0,因此 jmp 0。尝试在钩子(Hook)之前将 originalFunction 设置为 3,你会看到。如果你的函数不为空就不会出现这个问题,所以不用担心。返回之前的一个简单的 __nop(); 将使其工作,即使它是空的。

关于c++ - 弯路 - jmp 00000000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28067801/

相关文章:

c++ - 如何获取 QNetworkConfiguration UserChoice 对话框?

c - 用于从堆栈中释放参数的函数和机器命令的激活记录

c++ - 函数钩子(Hook)地址复制错误

java - 对 Hibernate 数据库结构进行逆向工程

c++ - move 赋值运算符和`if(this!=&rhs)`

c++ - 与 c++11 正则表达式不匹配

c - 如何为ARMCC声明全局浮点寄存器

c++ - 使用 o2 标志编译会使程序出现访问冲突

eclipse - 用于逆向工程 Eclipse 项目的 UML 工具

c++ - 服务器关闭永远不会完成