__declspec nude上的memcpy返回意外字节

时间:2019-08-17 07:12:35

标签: c++ assembly visual-c++ x86 inline-assembly

我正在尝试获取__declspec(naked)函数的原始字节,但是memcpy返回的是我不期望的字节。

我已使用调试器检查字节/地址。一切看起来都很好,但是memcpy的结果产生了不同的,看似不变的字节。

void __declspec(naked) widget_click_fix_asm()
{
    __asm {
        nop
        call patched_widget_handler
    }
}

void test_patch()
{
    char buf[7];

    ::memcpy(&buf, &widget_click_fix_asm, 7);
}

在VS调试器中,我在中间窗口中执行了

&widget_click_fix_asm
0x778816f0

导航到该内存位置将显示以下字节:

778816F0 90
778816F1 FF 15 38 91 88 77

我希望buf是以下字节的容器:

[0x90, 0xFF, 0x15, 0x38, 0x91, 0x88, 0x77]

每次测试时,buf都会包含以下恒定字节:

[0xE9, 0xD8, 0x05, 0x00, 0x00, 0xE9, 0x63]

为什么我没有得到我期望的字节?

1 个答案:

答案 0 :(得分:3)

您正在观察的原因是由于MSVC的“调试模式”中的incremental linkingwidget_click_fix_asm的地址实际上不是函数本身,而是JMP Thunk Table中JMP指令的地址。该表用于将功能的新版本修补到现有的可执行文件中。这是通过在具有足够空间的可执行文件的可用区域中写入新功能,然后用新地址更新JMP thunk表来完成的。这有助于Visual Studio中的编辑和继续调试功能。

在您的示例中,对memcpy的调用最终将JMP Thunk表的一部分复制到了buf而不是函数本身。您不妨考虑关闭增量链接功能,以获取所需的行为。