裸__declspec上的 memcpy 返回意外的字节
memcpy on __declspec naked returns unexpected bytes
我正在尝试获取__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]
为什么我没有得到预期的字节数?
您观察到的是由于 MSVC 调试模式下的增量链接。widget_click_fix_asm
的地址实际上不是函数本身,而是JMP输出表中JMP指令的地址。此表用于将新版本的函数修补到现有可执行文件中。这是通过在可执行文件中具有足够空间的可用区域中编写新函数,然后使用新地址更新JMP thunk表来完成的。这有助于Visual Studio中的编辑和继续调试功能。
在您的示例中,您对memcpy
的调用最终将 JMP Thunk 表的一部分复制到buf
而不是函数本身。您可能希望考虑关闭增量链接功能,以获得所需的行为。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 在C++中对T*类型执行std::move的意外行为
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- std::当在256字节边界上写入整数时,流的奇怪行为
- 处理除以零会导致<csignal>意外行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 裸__declspec上的 memcpy 返回意外的字节
- 为什么对小于 4 个字节的整数类型的位操作会发生意外行为?
- 从套接字到字节数组的读取数据中的意外字符
- 变量的字节表示的意外结果
- 动态创建字节数组后,监视中的符号数量意外
- 将dword强制转换为字节[4]时出现意外结果(endianity swap?)
- 在缓冲区之间移动字节时出现意外结果