二元炸弹第 4 阶段确认
Posted
技术标签:
【中文标题】二元炸弹第 4 阶段确认【英文标题】:Binary Bomb phase 4 confirmation 【发布时间】:2020-06-04 23:54:50 【问题描述】:我目前正在研究这个二元炸弹的第 4 阶段,我已经为此思考了几个小时。这是我目前的笔记。
第四阶段拆解
Dump of assembler code for function phase_4:
=> 0x0000000000401016 <+0>: sub $0x18,%rsp //rsp =-24
0x000000000040101a <+4>: lea 0xc(%rsp),%rcx // second input = rcx
0x000000000040101f <+9>: lea 0x8(%rsp),%rdx // first input = rdx
0x0000000000401024 <+14>: mov $0x4027cd,%esi // answer format is %d %d
0x0000000000401029 <+19>: mov $0x0,%eax // compare 0 and eax
0x000000000040102e <+24>: callq 0x400c30 <__isoc99_sscanf@plt>
0x0000000000401033 <+29>: cmp $0x2,%eax // compared 2 and eax
0x0000000000401036 <+32>: jne 0x401044 <phase_4+46> //if not equal to 2 jump to explode bomb
0x0000000000401038 <+34>: mov 0xc(%rsp),%eax // eax = *rsp+12(second input)
0x000000000040103c <+38>: sub $0x2,%eax // subtract 2 from second input
0x000000000040103f <+41>: cmp $0x2,%eax // compare 2 and second input
0x0000000000401042 <+44>: jbe 0x401049 <phase_4+51> // if below 2 then jump to +51
0x0000000000401044 <+46>: callq 0x401544 <explode_bomb>
0x0000000000401049 <+51>: mov 0xc(%rsp),%esi // second input becomes esi
0x000000000040104d <+55>: mov $0x8,%edi // edi becomes 8
0x0000000000401052 <+60>: callq 0x400fde <func4> //go to func4
0x0000000000401057 <+65>: cmp 0x8(%rsp),%eax // compare first input to eax(from func 4)
0x000000000040105b <+69>: je 0x401062 <phase_4+76> //if equal go to 76
0x000000000040105d <+71>: callq 0x401544 <explode_bomb>
0x0000000000401062 <+76>: add $0x18,%rsp
0x0000000000401066 <+80>: retq
func4 反汇编
Dump of assembler code for function func4:
0x0000000000400fde <+0>: push %r12 // push r12 onto stack
0x0000000000400fe0 <+2>: push %rbp // push rbp onto stack
0x0000000000400fe1 <+3>: push %rbx // push rbx onto stack
0x0000000000400fe2 <+4>: mov %edi,%ebx // ebx becomes edi(8)
0x0000000000400fe4 <+6>: test %edi,%edi // test 8 & 8
0x0000000000400fe6 <+8>: jle 0x40100c <func4+46> //if less than or equal to jump to 46
0x0000000000400fe8 <+10>: mov %esi,%ebp // esi(second input) becomes ebp
0x0000000000400fea <+12>: mov %esi,%eax // esi(second input) becomes eax
0x0000000000400fec <+14>: cmp $0x1,%edi // compare 1 and edi(8)
0x0000000000400fef <+17>: je 0x401011 <func4+51> // if equal then jump to 51
0x0000000000400ff1 <+19>: lea -0x1(%rdi),%edi // subtract 1 from edi(8) address
0x0000000000400ff4 <+22>: callq 0x400fde <func4> // call function 4
0x0000000000400ff9 <+27>: lea (%rax,%rbp,1),%r12d
0x0000000000400ffd <+31>: lea -0x2(%rbx),%edi // subtract 2 from edi address
0x0000000000401000 <+34>: mov %ebp,%esi // ebp becomes esi(8)
0x0000000000401002 <+36>: callq 0x400fde <func4> // call func 4
0x0000000000401007 <+41>: add %r12d,%eax // add r12d and eax
0x000000000040100a <+44>: jmp 0x401011 <func4+51> // jump to 51
0x000000000040100c <+46>: mov $0x0,%eax // eax is 0
0x0000000000401011 <+51>: pop %rbx
0x0000000000401012 <+52>: pop %rbp
0x0000000000401013 <+53>: pop %r12
0x0000000000401015 <+55>: retq
以及我对它们如何协同工作/输入应该是什么的注释
输入是“%d %d”
我认为第二个输入必须是 2
转到第 51 行
第二个输入减去 2 后变为 ESI(0)
EDI 变成 8
进入功能 4
edx 变成 EDI(8)
测试 edi 和 edi (8 & 8)
我研究过其他类似的问题,但我无法理解人们如何获得问题的答案。我知道有人有基本相同的 func4 但我不太明白有人给出的答案。
我想更好地弄清楚 func 4 的作用。我认为,因为它从 edi 和 edi(两者都是 8)之间的测试开始,它会达到 +46,这使得 eax 为 0,但我不知道它从那里去哪里。
我很确定第二个输入必须在 2 到 4 之间,但我不知道第一个输入的作用。我很确定第一个通过 func4 并最终等于第一个输入。
我是否理解它的正确作用?
非常感谢。
【问题讨论】:
你没有说明你想要回答什么或提出的问题是什么。 【参考方案1】:所以,看看func4
,您的 cmets 很大程度上重复了指令的作用,而不是每个指令的含义......我建议在任何给定时刻计算出各种寄存器包含的内容,因此每个步骤都在做什么.像这样的:
Dump of assembler code for function func4:
0x400fde <+0>: push %r12
0x400fe0 <+2>: push %rbp
0x400fe1 <+3>: push %rbx
// Arguments: a in %edi, b in %esi
0x400fe2 <+4>: mov %edi,%ebx // %ebx = a (copy of)
0x400fe4 <+6>: test %edi,%edi
0x400fe6 <+8>: jle 0x40100c <func4+46> // return 0 if a <= 0
0x400fe8 <+10>: mov %esi,%ebp // %ebp = b (copy of)
0x400fea <+12>: mov %esi,%eax // %eax = b (copy of) also
0x400fec <+14>: cmp $0x1,%edi
0x400fef <+17>: je 0x401011 <func4+51> // return b if a == 1
// Have: a in %edi and %ebx -- a > 1; b in %esi and %ebp
0x400ff1 <+19>: lea -0x1(%rdi),%edi // argument a for func4: a - 1
// argument b already in %esi
0x400ff4 <+22>: callq 0x400fde <func4> // func4(a - 1, b)
0x400ff9 <+27>: lea (%rax,%rbp,1),%r12d // r (%r12d) = b + func4(a - 1, b)
// Have: a in %ebx -- a > 1; b in %ebp ; r = b + func4(a - 1, b) in %r12d
0x400ffd <+31>: lea -0x2(%rbx),%edi // argument a for func4: a - 2
0x401000 <+34>: mov %ebp,%esi // argument b for func4: b
0x401002 <+36>: callq 0x400fde <func4> // func4(a - 2, b)
0x401007 <+41>: add %r12d,%eax // b + func4(a - 1, b) + func4(a - 2, b)
0x40100a <+44>: jmp 0x401011 <func4+51> // return result
0x40100c <+46>: mov $0x0,%eax // return 0
0x401011 <+51>: pop %rbx
0x401012 <+52>: pop %rbp
0x401013 <+53>: pop %r12
0x401015 <+55>: retq
所以现在应该可以弄清楚func4()
在做什么,因此,通过类似的分析,phase_4
在做什么。
【讨论】:
这很有帮助,我在这方面仍然很糟糕,但我基本上将它复制到记事本中,并在每次出现这些变量时将 a 更改为 8 并将 b 更改为 2,看看我是否可以做更多感。我希望我在这方面做得更好,但我不擅长汇编代码。再次感谢您的帮助。 这需要练习。 (所谓的)AT&T 的参数与 Intel/AMD 的顺序相反,这无济于事 :-( 此外,在反汇编编译的代码时,给定的变量可能会从一个寄存器转移到另一个寄存器——尤其是在调用时。然后是堆栈帧并跟踪%rsp
和/或%rbp
相对地址。多么有趣!以上是关于二元炸弹第 4 阶段确认的主要内容,如果未能解决你的问题,请参考以下文章