__declspec 裸 returns 意外字节上的 memcpy
memcpy on __declspec naked returns unexpected bytes
我正在尝试获取 __declspec(naked)
函数的原始字节,但 memcpy
正在返回我不期望的字节。
我已经使用调试器检查 bytes/addresses。一切看起来都很好,但是 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调试器中,在中间window我执行了:
&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]
为什么我没有得到预期的字节数?
您所观察到的是由于 incremental linking in MSVC's Debug Mode. The address of widget_click_fix_asm
isn't actually the function itself, but the address of a JMP instruction in the JMP Thunk Table。此 table 用于将新版本的函数修补到现有的 executable 中。这是通过在具有足够 space 的 executable 的空闲区域写入新函数,然后用新地址更新 JMP thunk table 来完成的。这有助于 Visual Studio.
中的编辑和继续调试功能
在您的示例中,您对 memcpy
的调用最终将 JMP Thunk Table 的一部分复制到 buf
而不是函数本身。您可能希望考虑关闭增量链接功能以获得您想要的行为。
我正在尝试获取 __declspec(naked)
函数的原始字节,但 memcpy
正在返回我不期望的字节。
我已经使用调试器检查 bytes/addresses。一切看起来都很好,但是 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调试器中,在中间window我执行了:
&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]
为什么我没有得到预期的字节数?
您所观察到的是由于 incremental linking in MSVC's Debug Mode. The address of widget_click_fix_asm
isn't actually the function itself, but the address of a JMP instruction in the JMP Thunk Table。此 table 用于将新版本的函数修补到现有的 executable 中。这是通过在具有足够 space 的 executable 的空闲区域写入新函数,然后用新地址更新 JMP thunk table 来完成的。这有助于 Visual Studio.
在您的示例中,您对 memcpy
的调用最终将 JMP Thunk Table 的一部分复制到 buf
而不是函数本身。您可能希望考虑关闭增量链接功能以获得您想要的行为。