试图理解这个汇编 x86 代码

Posted

技术标签:

【中文标题】试图理解这个汇编 x86 代码【英文标题】:Trying to understand this assembly x86 code 【发布时间】:2011-11-14 16:59:13 【问题描述】:

我目前正在拆除炸弹,正在进行炸弹的第四阶段,但我遇到了问题。我不确定这部分代码是什么意思。

    0x08048f64 <phase_4+81>:        mov    0x804a20c(,%edx,4),%eax
    0x08048f6b <phase_4+88>:        jmp    *%eax

我认为这行代码的意思是在 $eax 中输入一些代码并跳转到它,但不太确定,因为我不知道 0x804a20c 处的值是什么。我对组装有点陌生。到目前为止,我知道输入必须由两个数字组成,第二个数字必须是 126。但我不确定第一个数字是什么。每次我使用数字 x 和 126 运行代码时。X 是任何数字,我都会进入最后一步,但在该步骤中,它将 -0x8(ebp) 中的 0 值与字符串的长度进行比较。由于在第 56 行,它将 0 输入到 -0x8(ebp)。我想知道上面的代码是否与此有关。

例如,如果我输入“100 126”,那么程序会将 7 的值与 0 进行比较,并且不会让我在第 191 行跳最后一次爆炸。

这是完整的代码。

    0x08048f13 <phase_4+0>: push   %ebp
    0x08048f14 <phase_4+1>: mov    %esp,%ebp
    0x08048f16 <phase_4+3>: push   %ebx
    0x08048f17 <phase_4+4>: sub    $0x24,%esp
    0x08048f1a <phase_4+7>: lea    -0x14(%ebp),%eax
    0x08048f1d <phase_4+10>:        mov    %eax,0xc(%esp)
    0x08048f21 <phase_4+14>:        lea    -0x10(%ebp),%eax
    0x08048f24 <phase_4+17>:        mov    %eax,0x8(%esp)
    0x08048f28 <phase_4+21>:        movl   $0x804a206,0x4(%esp)
    0x08048f30 <phase_4+29>:        mov    0x8(%ebp),%eax
    0x08048f33 <phase_4+32>:        mov    %eax,(%esp)
    0x08048f36 <phase_4+35>:        call   0x8048b10 <sscanf@plt>
    0x08048f3b <phase_4+40>:        cmp    $0x2,%eax
    0x08048f3e <phase_4+43>:        je     0x8048f45 <phase_4+50>
    0x08048f40 <phase_4+45>:        call   0x8049e74 <explosion>
    0x08048f45 <phase_4+50>:        mov    -0x10(%ebp),%eax
    0x08048f48 <phase_4+53>:        mov    %eax,-0xc(%ebp)
    0x08048f4b <phase_4+56>:        movl   $0x0,-0x8(%ebp)
    0x08048f52 <phase_4+63>:        mov    -0x14(%ebp),%eax
    0x08048f55 <phase_4+66>:        sub    $0x74,%eax
    0x08048f58 <phase_4+69>:        mov    %eax,-0x18(%ebp)
    0x08048f5b <phase_4+72>:        cmpl   $0xa,-0x18(%ebp)
    0x08048f5f <phase_4+76>:        ja     0x8048fb5 <phase_4+162>
    0x08048f61 <phase_4+78>:        mov    -0x18(%ebp),%edx
    0x08048f64 <phase_4+81>:        mov    0x804a20c(,%edx,4),%eax
    0x08048f6b <phase_4+88>:        jmp    *%eax
    0x08048f6d <phase_4+90>:        addl   $0x1,-0x8(%ebp)
    0x08048f71 <phase_4+94>:        movl   $0x72,-0xc(%ebp)
    0x08048f78 <phase_4+101>:       shll   -0x8(%ebp)
    0x08048f7b <phase_4+104>:       jmp    0x8048fba <phase_4+167>
    0x08048f7d <phase_4+106>:       addl   $0x38,-0xc(%ebp)
    0x08048f81 <phase_4+110>:       addl   $0x1,-0xc(%ebp)
    0x08048f85 <phase_4+114>:       movl   $0x7a,-0x8(%ebp)
    0x08048f8c <phase_4+121>:       jmp    0x8048fba <phase_4+167>
    0x08048f8e <phase_4+123>:       movl   $0x44,-0xc(%ebp)
    0x08048f95 <phase_4+130>:       subl   $0x1,-0xc(%ebp)
    0x08048f99 <phase_4+134>:       shll   -0x8(%ebp)
    0x08048f9c <phase_4+137>:       jmp    0x8048fba <phase_4+167>
    0x08048f9e <phase_4+139>:       subl   $0x1,-0x8(%ebp)
    0x08048fa2 <phase_4+143>:       subl   $0x7a,-0xc(%ebp)
    0x08048fa6 <phase_4+147>:       jmp    0x8048fba <phase_4+167>
    0x08048fa8 <phase_4+149>:       movl   $0x3,-0xc(%ebp)
    0x08048faf <phase_4+156>:       addl   $0x1,-0x8(%ebp)
    0x08048fb3 <phase_4+160>:       jmp    0x8048fba <phase_4+167>
    0x08048fb5 <phase_4+162>:       call   0x8049e74 <explosion>
    0x08048fba <phase_4+167>:       mov    -0xc(%ebp),%eax
    0x08048fbd <phase_4+170>:       imul   -0x8(%ebp),%eax
    0x08048fc1 <phase_4+174>:       mov    %eax,%ebx
    0x08048fc3 <phase_4+176>:       mov    0x8(%ebp),%eax
    0x08048fc6 <phase_4+179>:       mov    %eax,(%esp)
    0x08048fc9 <phase_4+182>:       call   0x8048a20 <strlen@plt>
    0x08048fce <phase_4+187>:       cmp    %eax,%ebx
    0x08048fd0 <phase_4+189>:       je     0x8048fd7 <phase_4+196>
    0x08048fd2 <phase_4+191>:       call   0x8049e74 <explosion>
    0x08048fd7 <phase_4+196>:       add    $0x24,%esp
    0x08048fda <phase_4+199>:       pop    %ebx
    0x08048fdb <phase_4+200>:       pop    %ebp
    0x08048fdc <phase_4+201>:       ret    

感谢任何帮助。谢谢。

【问题讨论】:

看起来不像x86 对于可能是“Windows 老兄”来说看起来很奇怪,但我现在知道对其他人来说没问题。 @Roman R.:这是 AT&T 语法。这是它和英特尔的比较:imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm 所以,mov 0x804a20c(,%edx,4),%eax 对我来说就像 mov eax, [0x804a20c + edx * 4]。听起来像是从项目表跳转到地址。 0x804a20c 应该是一个包含要执行的代码的 32 位代码位置的数组。这是什么问题? +1 表示“致力于拆除炸弹”。引起了我的注意。 (-1 表示没有“作为家庭作业”) 【参考方案1】:

804a20c 中的内容无关紧要,因为加载跳转的地址取决于 edx 中的内容。该地址实际上是由 edx 索引的跳转表的基础。第二行跳转到的地址是内存中804a20c+(edx*4)处的地址。

【讨论】:

谢谢,这是有道理的。我一直盯着它看,想知道它是什么意思。

以上是关于试图理解这个汇编 x86 代码的主要内容,如果未能解决你的问题,请参考以下文章

试图了解 x86 上 alloca() 函数的汇编实现

帮助理解 x86 内联汇编中的 DIV 指令

试图从 g++ 中理解简单的反汇编代码

x86 汇编器:浮点比较

内核基础---AT&T汇编与x86汇编的区别

反汇编基本原理与x86指令构造