我试图通过在 中创建小的 C 程序来自学一些汇编。 Visual Studio 2012 Express ,然后在 中拆卸它们免疫调试器 .但我显然遇到了一些我不明白的事情:
012A13F0 68 58582A01 PUSH OFFSET Hello_Wo.??_C@_0M@KPLPPDAC@H>; ASCII "Hello World"
012A13F5 FF15 BC922A01 CALL DWORD PTR DS:[<&MSVCR110D.printf>] ; MSVCR110.printf
我对这两个说明感到困惑。事实上,操作码对我来说比调试器描述的实际指令更有意义。
显然,第一条指令将地址压入堆栈。当我跟踪转储中的地址时,它向我显示了一个区域,其中包含一些组成字符串
Hello World
的十六进制数。 .我相信这是.data segment
.我对么?并且;我猜
Hello_Wo.??_C@_0M@...
只是调试器提供给我的视觉辅助,所以我可以更好地理解这是......东西......但是是什么意思?偏移在这个推送指令中是什么意思?我在谷歌上找不到任何关于它的东西。
我还想问一下其他指令...
据我了解,它试图通过使用位于地址
DS:[102A92BC] (&MSVCR110D...)
处的 4 字节值来调用例程。 ,作为调用的地址?调试器告诉我
DS:[102A92BC] = 5C0A93A0
.并且该内存范围是为 MSVCR110 的 .text segment
保留的.我很抱歉,但我很难提出这个问题,因为我什至不确定我应该如何提问。我希望你明白。谢谢。
题外话:我有最后一个有点愚蠢和题外话的问题,但我希望你不要介意:你不应该把数据段读成反汇编代码,对吗?进口数据段让我在搜索
5C0A93A0
时感到困惑.
最佳答案
在 x86 架构中,每个地址都有两部分 - 段和偏移量。所以,OFFSET 的意思很简单,就是将某个变量“Hello_Wo.??_C@_0M@KPLPPDAC@H”的地址偏移压入栈中。该指令来自 MASM 语法,其中“推送变量”表示推送变量的值,“推送偏移变量”表示推送变量的偏移量。
提到的“.data”和“.text”不是段,而是节。这是完全不同的。该部分只是具有单独内存保护的可执行文件的一部分。 C/C++ 编译器通常使用“.text”作为程序代码。不要问我为什么。
在现代保护模式操作系统中,使用平面内存模型。这意味着所有代码和数据都放在一个大段中,因此您永远不必使用 DS、ES 等段寄存器。它们的值由操作系统管理。
附言用逆向 HLL 程序开始学习汇编语言并不是最好的策略。
最好尝试阅读和编写一些 native 汇编代码。互联网上有很多地方可以下载此类示例——非常简单和非常复杂,取决于您的进度。我建议使用 FASM .有一个留言板,其中包含大量有用的信息和可以回答您问题的人员。
关于assembly - x86 程序集 "push OFFSET ..."和助记符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17634244/