【发布时间】:2009-02-06 21:36:07
【问题描述】:
我在工作中一直在使用免费的 Digital Mars 编译器(我知道很淘气),并创建了一些代码来检查编译的函数并查看字节码以用于学习目的,看看我是否可以从中学到任何有价值的东西编译器构建它的函数。但是,在 MSVC++ 中重新创建相同的方法失败得很惨,我得到的结果非常混乱。我有这样的功能:
unsigned int __stdcall test()
{
return 42;
}
然后我会这样做:
unsigned char* testCode = (unsigned char*)test;
在这种情况下,我似乎无法让 C++ static_cast 工作(它会引发编译器错误)......因此是 C 风格的强制转换,但除此之外......我也尝试过使用参考 &test,但这无济于事。
现在,当我检查 testCode 指向的内存内容时,我感到很困惑,因为我所看到的甚至看起来都不像有效代码,甚至还有一个调试断点卡在那里......看起来像这样(目标是 IA-32):
0xe9、0xbc、0x18、0x00、0x00、0xcc...
这显然是错误的,0xe9是相对跳转指令,看0xbc字节后是这样的:
0xcc、0xcc、0xcc...
即对于未分配或未使用的内存,内存初始化为调试断点操作码。
我对返回 42 的函数的期望是:
0x8b、0x2a、0x00、0x00、0x00、0xc3
或者至少有一些 mov 的味道,然后是 ret(0xc2、0xc3、0xca 或 0xcb),再往下一点
MSVC++ 是出于安全原因采取措施阻止我做这种事情,还是我做了一些愚蠢的事情而没有意识到?使用 DMC 作为编译器,此方法似乎可以正常工作...
我也遇到了其他问题(执行字节),但我怀疑根本原因是相同的。
任何帮助或提示将不胜感激。
【问题讨论】:
-
reinterpret_cast 用于投射指针; static_cast 用于转换不适合 dynamic_cast 的“相关”类型。
标签: c++ visual-c++ bytecode x86