Bomb 日志
l 实验准备:
经过前两关炸弹的拆除,我们已经对程序执行时栈帧结构操作比较熟悉了,所以接下来我们只需要依照前两关炸弹的拆除办法依次对后面几关的代码进行反汇编、反汇编分析找出关键字符串即可。
l 具体过程:
通过vi指令打开反汇编得到bomb.s文件:
查看bomb.s文件:
找到关卡3的反汇编代码:
分析此段代码:
push %ebp 将ebp寄存器中的内容入栈
mov %esp,%ebp 将esp中的内容复制到ebp中
sub $0x28,%esp 分配16进制28即40个字节的空间
lea -0x10(%ebp),%eax 取出ebp-16处的值传送到eax中
mov %eax,0xc(%esp) 将eax中的值存入esp+12位置处
lea -0xc(%ebp),%eax 取出ebp-12处的值传送到eax中
mov %eax,0x8(%esp) 将eax中的值存入esp+8位置处
movl $0x804a23e,0x4(%esp) 将0x804a23e处的值双字节传送到esp+4位置处
mov 0x8(%ebp),%eax 将ebp+8位置处的数据传输到eax中
mov %eax,(%esp) 将eax中的值传输到esp中
call 8048840 <__isoc99_sscanf@plt>
过程调用,8048840为被调用过程起始点指令地址,将返回地址入栈,并跳转到被调用过程的起始处
cmp $0x1,%eax 将数值1与eax中的值相减
jg 8048ed2
根据上一步结果标志位进行跳转,有符号大于则跳转
call 80490d1
cmpl $0x7,-0xc(%ebp) 将数值7与ebp-12处的值相减
ja 8048f43
根据上一步结果标志位进行跳转,无符号大于则跳转
mov -0xc(%ebp),%eax 将ebp-12位置处的数据传输到eax中
jmp *0x804a1a0(,%eax,4) 无条件跳转到(4*%eax+0x804a1a0)地址处
mov $0x0,%eax 将数据0传输到eax中
xchg %ax;%ax 两个寄存器之间相互交换
jmp 8048f37
mov $0x0,%eax 将数据0传输到eax中
jmp 8048f32
mov $0x0,%eax 将数据0传输到eax中
xchg %ax,%ax 两个寄存器之间相互交换
jmp 8048f2d
mov $0x0,%eax 将数据0传输到eax中
jmp 8048f28
mov $0x0,%eax 将数据0传输到eax中
xchg %ax,%ax 两个寄存器之间相互交换
jmp 8048f23
mov $Ox314,%eax 将数据788传输到eax中
jnp 8048f1e
mov $0xO,%eax 将数据0传输到eax中
sub $Ox35a,%eax
将eax中的值减去(3*16*16+5*16+10)即858,结果存回eax中eax=eax-0x35a=788-(3*16*16+5*16+10)=-70
add $0x2ef,%eax
将eax中的值加上(2*16*16+14*16+15)即751,结果存回eax中
sub $Ox216,%eax
将eax中的值减去(2*16*16+1*16+6)即534,结果存回eax中
add $0x216,%eax
将eax中的值加上(2*16*16+1*16+6)即534,结果存回eax中
sub $0x216,%eax
将eax中的值减去(2*16*16+1*16+6)即534,结果存回eax中
add $Ox216,%eax
将eax中的值加上(2*16*16+1*16+6)即534,结果存回eax中
sub $Ox216,%eax
将eax中的值减去(2*16*16+1*16+6)即534,结果存回eax中
eax=eax+751-534+534-534+534-534=147
jnp 8048f4d
判断奇偶位,如果奇偶位为0则跳转到8048f4d地址处执行相关操作
call 80490d1
mov $0x0,%eax 将数据0传输到eax中
cmpl $0x5,-oxc(%ebp) 将数值5与ebp-12处的值相减
jg 8048f58
根据上一步结果标志位进行跳转,有符号大于则跳转
cmp -0x10(%ebp),%eax 将eax寄存器里的值与ebp-16处值相减
je 8048f5d
根据上一步相减的结果进行下一步,如果相等,执行je指令跳转到8048f5d
call 80490d1
leave
xchg %ax,%ax 两个寄存器之间相互交换
ret 结束程序
本题的栈帧结构如下图所示:
拆除炸弹三即不让第三段程序进入爆炸。分析代码,程序先给整个进程分配2*16+8即40个字节,准备工作完成。首先,将ebp-1*16处的值传输到eax中,再将eax中的值存入esp+12即ebp-24处;将ebp-12中的值传输到eax中,再将eax中的值存入esp+8处;将0x804a23e处的值存入到esp+4中;将ebp+8处的值传输到eax中,再将eax中的值(参数1)存入esp处;cmp将eax与数值1做减法,当结果大于0即eax>1时,程序跳过炸弹。cmpl将ebp-12的值(参数A)与数值7做减法,当结果大于0即ebp-12>7则跳转到炸弹处,所以ebp-12的值(参数A)<7;将ebp-12中的值(参数A)传输到eax中,跳转到0x804a1a0(,eax,4)中数据指向的地址,ebp-12中的值(参数A)的不同将会引起程序跳转到不同地方。将eax清零,跳转到8048f3c处,执行eax+0x216的指令;后面几行都是将eax清零,并对eax进行相关操作。cmpl将ebp-12中的值(参数A)与0x5相减,当结果大于0即ebp-12>5则跳转到炸弹处,所以ebp-12的值(参数A)<5;cmp将eax与ebp-16中的值(参数B)相减,当结果等于0即eax=ebp-16则跳转8048f5d处,所以eax=ebp-16中的值(参数B);所以易知,参数A的范围为0—5,并且参数A的值会决定eax中的值,而我们输入的参数B又必须和eax中的值相等,所以重点是分析参数A为不同值时,对应的eax的值:
查看指针指向内存的数据:
所以易知:
第二关炸弹有五组解,它们分别是:
(0,147)、(1,-641)、(2,217)、(3,-534)、(4,0)、(5,-534)