深入理解计算机系统LAB2

更新时间:2023-10-06 11:47:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

LAB1实验报告

实验目的:

使用课程知识拆除一个“Binary Bombs”来增强对程序的机器级表示、汇编语言、调试器和逆向工程等理解。

实验简介:

一个“Binary Bombs”(二进制炸弹,简称炸弹)是一个Linux可执行C程

序,包含phase1~phase6共6个阶段。炸弹运行各阶段要求输入一个字符串,若输入符合程序预期,该阶段炸弹被“拆除”,否则“爆炸”。实验目标是你需要拆除尽可能多的炸弹。

运行结果:

成功运行结果截图:

通关密码储存在0014301-151420131.txt文件中。

实验中的六组密码:

PHASE1:字符串比较

本关比较简单,根据课件中的提示用GDB将最先压栈的那个字符串常量打印

出来,然后将其作为密码输入,比较成功后即通关。

08048ab2 :

8048ab2: 83 ec 14 8048ab5: 68 04 9f 04 08 8048aba: ff 74 24 1c 8048abe: e8 4d 04 00 00

sub $0x14,%esp push $0x8049f04 pushl 0x1c(%esp)

call 8048f10

将地址0x8049f04中的值打印出来:

PHASE2:循环

在查看汇编语言的时候,会看到有调用一个read_six_number函数,猜测此即“The future will be better tomorrow.”

题是让输入六个数字。

08048ad3 :

8048ad3: 56 8048ad4: 53 8048ad5: 83 ec 2c 8048ad8: 8d 44 24 10 8048adc: 50 8048add: ff 74 24 3c 8048ae1: e8 46 05 00 00 8048ae6: 83 c4 10 8048ae9: 83 7c 24 08 01 8048aee: 74 1e 8048af0: e8 12 05 00 00 8048af5: eb 17 8048af7: 8b 03 8048af9: 01 c0 8048afb: 39 43 04 8048afe: 74 05 8048b00: e8 02 05 00 00 8048b05: 83 c3 04 8048b08: 39 f3 8048b0a: 75 eb 8048b0c: eb 0a

push %esi push ?x

sub $0x2c,%esp

lea 0x10(%esp),êx push êx

pushl 0x3c(%esp)

call 804902c add $0x10,%esp

cmpl $0x1,0x8(%esp)------?判定是否为1 je 8048b0e call 8049007 jmp 8048b0e mov (?x),êx

add êx,êx----?进行自加,扩大两倍 cmp êx,0x4(?x)

je 8048b05 call 8049007 add $0x4,?x cmp %esi,?x

jne 8048af7 jmp 8048b18

8048b0e: 8048b12: 8048b16: 8048b18: 8048b1b: 8048b1c: 8048b1d: 8d 5c 24 08 8d 74 24 1c eb df 83 c4 24 5b 5e c3 lea 0x8(%esp),?x lea 0x1c(%esp),%esi

jmp 8048af7 ?循环 add $0x24,%esp pop ?x pop %esi ret

有汇编语言进行分析,不难看出,这道题目要求输入六个数字,并且要求第

一个数字为1,之后跳入一个循环,将第一个数字加倍和已有的数字进行比较,所以不难看出所需要的密码是1,2,4,8,16,32这六个数字。

PHASE3:条件分支语句

这道题的汇编语句明显变长了,但是由于PPT中已经提示这是条件分支语句,

以此为切入点,此题也不难分析。

08048b1e :

8048b1e: 83 ec 1c 8048b21: 8d 44 24 08 8048b25: 50 8048b26: 8d 44 24 10 8048b2a: 50

sub $0x1c,%esp lea 0x8(%esp),êx push êx

lea 0x10(%esp),êx push êx

8048b2b: 68 0f a1 04 08 push $0x804a10f?打印该值为”%d%d” 8048b30: ff 74 24 2c pushl 0x2c(%esp)

8048b34: e8 87 fc ff ff call 80487c0 <__isoc99_sscanf@plt>

上面这一段调用了一个函数sscanf(),查询可知这个函数的原型为:int

sscanf(const char *buffer,const char *format,[argument ]...);即读取输入的字符串,并以指定的格式赋给参数。其中一个参数在地址0x804a10f中。可知需要输入两个整数。

8048b39: 8048b3c: 8048b3f: 8048b41: 8048b46: 8048b4b:

83 c4 10 83 f8 01 7f 05 e8 c1 04 00 00 83 7c 24 0c 07 77 66

add $0x10,%esp cmp $0x1,êx

jg 8048b46 call 8049007

cmpl $0x7,0xc(%esp)---------?不大于7 ja 8048bb3-?否则引爆

有这些可以得知第一个参数的信息,可以看出这是一个不大于7的数,因此

缩小了选择,不难猜出可能是分支条件。

8048b4d: 8b 44 24 0c mov 0xc(%esp),êx

8048b51: ff 24 85 80 9f 04 08 jmp *0x8049f80(,êx,4)

8048b58: 8048b5d: 8048b5f: 8048b64: 8048b69: 8048b6b: 8048b70: 8048b75: 8048b77: 8048b7c: 8048b81: 8048b83: 8048b88: 8048b8d: 8048b8f: 8048b94: 8048b99: 8048b9b: 8048ba0: 8048ba5: 8048ba7: 8048bac: 8048bb1: 8048bb3: b8 0c 03 00 00 eb 05 b8 00 00 00 00 2d d5 03 00 00 eb 05 b8 00 00 00 00 05 35 01 00 00 eb 05 b8 00 00 00 00 2d e9 02 00 00 eb 05 b8 00 00 00 00 05 e9 02 00 00 eb 05 b8 00 00 00 00 2d e9 02 00 00 eb 05 b8 00 00 00 00 05 e9 02 00 00 eb 05 b8 00 00 00 00 2d e9 02 00 00 eb 0a e8 4f 04 00 00 mov $0x30c,êx

jmp 8048b64 mov $0x0,êx sub $0x3d5,êx

jmp 8048b70 mov $0x0,êx add $0x135,êx

jmp 8048b7c mov $0x0,êx sub $0x2e9,êx

jmp 8048b88 mov $0x0,êx add $0x2e9,êx

jmp 8048b94 mov $0x0,êx sub $0x2e9,êx

jmp 8048ba0 mov $0x0,êx add $0x2e9,êx

jmp 8048bac mov $0x0,êx sub $0x2e9,êx

jmp 8048bbd call 8049007

上面是各种分支情况,看起来比较复杂,先放一放

b8 00 00 00 00 83 7c 24 0c 05 7f 06 3b 44 24 08 74 05 e8 38 04 00 00 83 c4 1c c3

mov $0x0,êx

cmpl $0x5,0xc(%esp)---?参数不能大于5 jg 8048bca cmp 0x8(%esp),êx

je 8048bcf call 8049007 add $0x1c,%esp ret

8048bb8: 8048bbd: 8048bc2: 8048bc4: 8048bc8: 8048bca: 8048bcf: 8048bd2:

可以看出参数不能大于五,因此这道题可能有多组解,不过结合分支语句,

不难看出当第一个参数比较大的时候,计算量比较小,所以我选择了第一个参数为5,代入进行逐步计算,可以得到此时的值为-745。

PHASE4:递归调用栈

这一步是递归调用栈,所以有两部分汇编代码,其中一个是被调用的函数,

简单地看一下代码,应该是一个递归的函数。先分析主程序部分的代码,其中也

有sscanf函数:

08048c2c :

8048c2c: 83 ec 1c 8048c2f: 8d 44 24 08 8048c33: 50 8048c34: 8d 44 24 10 8048c38: 50

sub $0x1c,%esp lea 0x8(%esp),êx push êx

lea 0x10(%esp),êx push êx

8048c39: 68 0f a1 04 08 push $0x804a10f---?输出为”%d%d” 8048c3e: 8048c42: 8048c47: 8048c4a:

ff 74 24 2c e8 79 fb ff ff 83 c4 10 83 f8 02

pushl 0x2c(%esp)

call 80487c0 <__isoc99_sscanf@plt> add $0x10,%esp

cmp $0x2,êx----?返回值为2

从上面这部分看出我们需要输入两个参数,且两个都是整数型的。

75 07 83 7c 24 0c 0e 76 05 e8 ac 03 00 00 83 ec 04 6a 0e 6a 00 ff 74 24 18 e8 68 ff ff ff 83 c4 10 83 f8 25 75 07 83 7c 24 08 25 74 05 e8 88 03 00 00 83 c4 1c c3

jne 8048c56

cmpl $0xe,0xc(%esp)?第一个参数不大于14 jbe 8048c5b call 8049007 sub $0x4,%esp push $0xe push $0x0

pushl 0x18(%esp)

call 8048bd3 add $0x10,%esp cmp $0x25,êx

jne 8048c7a

cmpl $0x25,0x8(%esp)---?第二个参数为37 je 8048c7f call 8049007 add $0x1c,%esp ret

8048c4d: 8048c4f: 8048c54: 8048c56: 8048c5b: 8048c5e: 8048c60: 8048c62: 8048c66: 8048c6b: 8048c6e: 8048c71: 8048c73: 8048c78: 8048c7a: 8048c7f: 8048c82:

从上面这些可以看出,虽然输入了两个参数,但是只有第一个参数被传递给

了func4另外一个没有变化,而且可以知道等于37。同时,第一个参数还不大于14。这样可能的情况就少了。考虑到func4本来就是一个递归函数,即使反汇编出来,也需要一步一步代入,不如直接进行尝试,枚举法得到第一个参数是10。

PHASE5:指针

这一道题的提示比较模糊,毕竟汇编程序里到处都有指针。

本文来源:https://www.bwwdw.com/article/08gd.html

Top