QUT大二汇编最后一个作业:拆炸弹 通过两天中间隙来做这个实验,不能交个实验报告就完事了,毕竟是第一次接触逆向工程,老师为了节省我们的时间,只让我们做三道题,我做bomb3 中的 1 2 4炸弹,报告内容如下所示,有时间再做做别的
32位Linux :Ubuntu 14.04.1 GDB
二进制炸弹实际是由C语言源程序生成的可执行目标代码,主程序可参考bomb.c。运行时,会按次序提示用户输入3个不同的字符串。如果输入的字符串有误,炸弹就会“爆炸”,输出一条错误信息。必须通过对可执行程序反汇编和逆向工程判断应该是哪3个数据串,从而拆除“炸弹”。
(用适当的形式表达算法设计思想与算法实现步骤)
1.首先阅读c语言程序,了解程序基本框架:
得到以下信息:
t:代表闯关的个数
x:放置要闯的关数的名称,长度为t
输入的t和x分别对应如图:
2.通读源程序后得知:
炸弹的入口在最后这个循环里边,input 应该是输入的对应的字符串,然后进入phase_funcs[]所指向的对应炸弹的函数的判断子程序,如果正确的话会调用phase_defused(第几个炸弹)子程序输出解决掉炸弹的字符串。
如下如所示:
3.gdb中导入程序,反汇编mian()函数后找到各个对应的跳转结点,返回编程序见附录,数字对应我设置的断点
4.通过p来读出各个 变量的值,可以确定上图中各个变量具体存储的数据,如下图所示:
可以验证上述2中猜测。
5.反汇编phase_1,phase_2,phase_4,由于我学号是33,取余30后为3,做bomb3,PhaseId为 -t 3 -x 124,所以我做的三道题分别为1,2,4题,反汇编结果见附录。
一:
phase_1对应答案:For NASA, space is still a high priority.
如图所示,将一个地址对应的字符串和输入的字符串进行
二:
反汇编phase_2,看到调用了read_six_numbers子程序,所以再反汇编read_six_numberh后分别大体画出两个程序的简易的流程图:
这个子程序中判断了eax与5的大小关系,而根据上文的输入判断eax是输入的个数,所以要本题输入六个整数。
查看phase_2的程序,在输入六个整数后,会进行一个循环操作,正循环,计数器通过地址计数,ebx作为地址指针,ebi作为终止地址,每次判断一下 数组的本位加上5等不等于下一位,总共循环五次,所以只要输入六个整数,每个整数大小不超过双字节,而且整数之间差为5即可,答案只要符和条件即可。
分析和答案见下图:
三:
反汇编phase_4汇编程序见附录,然后发现内部调用了子函数,func_4,反汇编func_4,发现func_4中自己调用了自己,有递归程序,结合两个函数的反汇编,绘制如下程序流程图:
还是有一个输入,x /s 查看一下地址0x8049ee4的内容为 %d,所以这题也是输入一个整数。
对应程序流程图分析递归的作用:
edx 作为一个递归判断变量,每次减一,当edx为0时停止调用,而edx的内容为输入的整数值,也就是递归输入的次数。
最底层的递归时,eax=1,edx=8*eax,edx=1,eax=edx,结果为eax=7,倒数第二次循环后eax=49也就相当于每层递归乘以7,而递归回来后,要求eax=0x961,
0x961=2401=7^4,也就是需要递归四次即可,所以本题答案为4.
1.炸弹1和2都比较简单,多加断点,单步执行理解程序意思即可,到了炸弹4的时候,一直没有理解递归内
这一行的意思,一直以为是上课讲的基址按比例变址寻址方式,是把一个地址的内容放到edx中,但是寻址内没有esi / edi等变址寄存器,但是在搜索学习基指比例变址寻址资料中,看到可以通过lea来表示一些乘法运算:
lea可以做简单的算术运算,特别是有了32位指令的增强的寻址方式:比如要把eax4+ebx+3放入到edx中只需要一行程序:
lea edx [eax3+ebx+3]
如此理解的话,题目中的递归的意思即是:edx=eax8+0 然后结合程序中的上下文立马就可以理解递归程序的含义,即每次乘以7,从1开始,最终结果是2401,从而得到递归次数,进而解决问题。
2.在反汇编后如果不理解某一行的意思,可以使用 b 地址的方式在此行加断点,然后同x 来输出有关地址的值,display 来输出寄存器的值,p输出变量的值,非常方便理解程序意思。
3.如果某一行即使理解了各寄存器和变量的值,但是还是不理解程序意思,可以通过 n(next) 或者s(step)来单步调试可以看到对应的c语言程序来理解,
n和s的区别在于,next单步调试不进入当前行的函数体内,step会进入当前行的函数体内。
总结:
本次实验的失误在于刚开始认为最好不要先看c原程序,结果没有了解程序的结构,直接反汇编了main函数后从main函数开始读,而main函数前部分都是判断文件读入和x内值不同的一些函数,跟炸弹没有任何关系,直到读到了循环中炸弹的入口后,一直没有思路解决炸弹,然后把老师发的ppt和建议文件都读了一下,然后看了一下源程序才理解程序结构,从而指导反汇编phase的炸弹子程序,从而解决了三个炸弹。
但是好在通过理解main函数的前段程序熟练掌握了gdb的各种命令,掌握了设置断点的绝妙之处,在该设断点的时候绝对不吝啬,进而掌握了delete删除断点,info了解断点的信息等各种调试方式。并非浪费时间。
phase_1: 反汇编得到的程序
(gdb) disas phase_1
Dump of assembler code for function phase_1:
0x08049045 <+0>: sub esp,0x14
0x08049048 <+3>: push 0x8049e8c
0x0804904d <+8>: push DWORD PTR [esp+0x1c]
0x08049051 <+12>: call 0x8049553
0x08049056 <+17>: add esp,0x10
0x08049059 <+20>: test eax,eax
0x0804905b <+22>: je 0x804906a
0x0804905d <+24>: sub esp,0xc
0x08049060 <+27>: push 0x1
0x08049062 <+29>: call 0x804994c
0x08049067 <+34>: add esp,0x10
0x0804906a <+37>: add esp,0xc
0x0804906d <+40>: ret
End of assembler dump.
phase_2: 反汇编得到的程序
disas phase_2
Dump of assembler code for function phase_2:
0x0804906e <+0>: push esi
0x0804906f <+1>: push ebx
0x08049070 <+2>: sub esp,0x2c
0x08049073 <+5>: lea ebx,[esp+0x10]
0x08049077 <+9>: push ebx
0x08049078 <+10>: push DWORD PTR [esp+0x3c]
0x0804907c <+14>: call 0x8049971 ==20==
0x08049081 <+19>: lea esi,[esp+0x2c]
0x08049085 <+23>: add esp,0x10 ==21==
0x08049088 <+26>: mov eax,DWORD PTR [ebx]
0x0804908a <+28>: add eax,0x5 ==22==
0x0804908d <+31>: cmp DWORD PTR [ebx+0x4],eax
0x08049090 <+34>: je 0x804909f
0x08049092 <+36>: sub esp,0xc
0x08049095 <+39>: push 0x2
0x08049097 <+41>: call 0x804994c
0x0804909c <+46>: add esp,0x10
0x0804909f <+49>: add ebx,0x4
0x080490a2 <+52>: cmp ebx,esi
0x080490a4 <+54>: jne 0x8049088
0x080490a6 <+56>: add esp,0x24
0x080490a9 <+59>: pop ebx
0x080490aa <+60>: pop esi
0x080490ab <+61>: ret
phase_4: 反汇编得到的程序
(gdb) disas phase_4
Dump of assembler code for function phase_4:
0x08049286 <+0>: sub esp,0x20
0x08049289 <+3>: lea eax,[esp+0x10]
0x0804928d <+7>: push eax
0x0804928e <+8>: push 0x8049ee4
0x08049293 <+13>: push DWORD PTR [esp+0x2c]
0x08049297 <+17>: call 0x8048950 <__isoc99_sscanf@plt>
0x0804929c <+22>: add esp,0x10
0x0804929f <+25>: cmp eax,0x1
0x080492a2 <+28>: jne 0x80492ab
0x080492a4 <+30>: cmp DWORD PTR [esp+0xc],0x0
0x080492a9 <+35>: jg 0x80492b8
0x080492ab <+37>: sub esp,0xc
0x080492ae <+40>: push 0x4 ==23==
0x080492b0 <+42>: call 0x804994c
0x080492b5 <+47>: add esp,0x10
0x080492b8 <+50>: sub esp,0xc
0x080492bb <+53>: push DWORD PTR [esp+0x18]
0x080492bf <+57>: call 0x8049258 n==25==
0x080492c4 <+62>: add esp,0x10
0x080492c7 <+65>: cmp eax,0x961
0x080492cc <+70>: je 0x80492db
0x080492ce <+72>: sub esp,0xc
0x080492d1 <+75>: push 0x4
0x080492d3 <+77>: call 0x804994c ==24==
0x080492d8 <+82>: add esp,0x10
0x080492db <+85>: add esp,0x1c
0x080492de <+88>: ret
End of assembler dump.
main函数的反汇编
0x08048cd6 <+0>: lea ecx,[esp+0x4]
0x08048cda <+4>: and esp,0xfffffff0
0x08048cdd <+7>: push DWORD PTR [ecx-0x4]
0x08048ce0 <+10>: push ebp
0x08048ce1 <+11>: mov ebp,esp
0x08048ce3 <+13>: push edi
0x08048ce4 <+14>: push esi
0x08048ce5 <+15>: push ebx
0x08048ce6 <+16>: push ecx
0x08048ce7 <+17>: sub esp,0x28
0x08048cea <+20>: mov ebx,DWORD PTR [ecx]
0x08048cec <+22>: mov eax,DWORD PTR [ecx+0x4]
0x08048cef <+25>: mov DWORD PTR [ebp-0x1c],eax
0x08048cf2 <+28>: cmp ebx,0x1
0x08048cf5 <+31>: jne 0x8048d06
0x08048cf7 <+33>: call 0x8048b38
0x08048cfc <+38>: sub esp,0xc
0x08048cff <+41>: push 0x8
0x08048d01 <+43>: call 0x8048910
0x08048d06 <+48>: mov eax,ds:0x804c740 =1=
0x08048d0b <+53>: mov ds:0x804c790,eax
0x08048d10 <+58>: mov DWORD PTR ds:0x804c760,0x1
---Type to continue, or q to quit---
0x08048d1a <+68>: mov DWORD PTR [ebp-0x28],0x0
0x08048d21 <+75>: mov DWORD PTR [ebp-0x24],0x0
0x08048d28 <+82>: mov DWORD PTR [ebp-0x20],0x0
0x08048d2f <+89>: jmp 0x8048de1
0x08048d34 <+94>: cmp eax,0x74 =2=
0x08048d37 <+97>: je 0x8048d49
0x08048d39 <+99>: cmp eax,0x78
0x08048d3c <+102>: je 0x8048d95
0x08048d3e <+104>: cmp eax,0x73
0x08048d41 <+107>: jne 0x8048dcb
0x08048d47 <+113>: jmp 0x8048dba
0x08048d49 <+115>: mov edi,DWORD PTR ds:0x804c780
0x08048d4f <+121>: movsx eax,BYTE PTR [edi]
0x08048d52 <+124>: sub eax,0x30
0x08048d55 <+127>: mov edx,eax
0x08048d57 <+129>: mov DWORD PTR [ebp-0x2c],eax
0x08048d5a <+132>: mov ecx,0xffffffff
0x08048d5f <+137>: mov eax,0x0
0x08048d64 <+142>: repnz scas al,BYTE PTR es:[edi]
0x08048d66 <+144>: cmp ecx,0xfffffffd =3=
0x08048d69 <+147>: jne 0x8048d75
0x08048d6b <+149>: mov eax,edx
0x08048d6d <+151>: sub eax,0x1
---Type to continue, or q to quit---
0x08048d70 <+154>: cmp eax,0x5 =4=
0x08048d73 <+157>: jbe 0x8048dda
0x08048d75 <+159>: push DWORD PTR ds:0x804c720
0x08048d7b <+165>: push 0x35
0x08048d7d <+167>: push 0x1
0x08048d7f <+169>: push 0x8049d78
0x08048d84 <+174>: call 0x80488a0
0x08048d89 <+179>: mov DWORD PTR [esp],0x8
0x08048d90 <+186>: call 0x8048910
0x08048d95 <+191>: mov esi,DWORD PTR ds:0x804c780
0x08048d9b <+197>: mov ecx,0xffffffff
0x08048da0 <+202>: mov edi,esi
0x08048da2 <+204>: mov eax,0x0
0x08048da7 <+209>: repnz scas al,BYTE PTR es:[edi]
0x08048da9 <+211>: not ecx
0x08048dab <+213>: lea eax,[ecx-0x1]
0x08048dae <+216>: mov DWORD PTR [ebp-0x30],eax
0x08048db1 <+219>: mov DWORD PTR [ebp-0x24],0x1
0x08048db8 <+226>: jmp 0x8048de1 ==7==
0x08048dba <+228>: mov eax,ds:0x804c780
0x08048dbf <+233>: mov DWORD PTR [ebp-0x34],eax
0x08048dc2 <+236>: mov DWORD PTR [ebp-0x28],0x1
0x08048dc9 <+243>: jmp 0x8048de1
---Type to continue, or q to quit---
0x08048dcb <+245>: call 0x8048b38
0x08048dd0 <+250>: sub esp,0xc
0x08048dd3 <+253>: push 0x8
0x08048dd5 <+255>: call 0x8048910
0x08048dda <+260>: mov DWORD PTR [ebp-0x20],0x1
0x08048de1 <+267>: sub esp,0x4
0x08048de4 <+270>: push 0x8049bd3 =5=
0x08048de9 <+275>: push DWORD PTR [ebp-0x1c]
0x08048dec <+278>: push ebx
0x08048ded <+279>: call 0x8048940
0x08048df2 <+284>: add esp,0x10
0x08048df5 <+287>: cmp eax,0xffffffff =6=
0x08048df8 <+290>: jne 0x8048d34
0x08048dfe <+296>: cmp DWORD PTR [ebp-0x20],0x0
0x08048e02 <+300>: je 0x8048e0a
0x08048e04 <+302>: cmp DWORD PTR [ebp-0x24],0x0
0x08048e08 <+306>: jne 0x8048e19 ==8==
0x08048e0a <+308>: call 0x8048b38
0x08048e0f <+313>: sub esp,0xc
0x08048e12 <+316>: push 0x8
0x08048e14 <+318>: call 0x8048910
0x08048e19 <+323>: sub esp,0xc
0x08048e1c <+326>: push esi
---Type to continue, or q to quit---
0x08048e1d <+327>: call 0x8048bbd
0x08048e22 <+332>: add esp,0x10
0x08048e25 <+335>: test eax,eax ==9==
0x08048e27 <+337>: jne 0x8048e49
0x08048e29 <+339>: push DWORD PTR ds:0x804c720
0x08048e2f <+345>: push 0x1e
0x08048e31 <+347>: push 0x1
0x08048e33 <+349>: push 0x8049db0
0x08048e38 <+354>: call 0x80488a0
0x08048e3d <+359>: mov DWORD PTR [esp],0x8
0x08048e44 <+366>: call 0x8048910
0x08048e49 <+371>: mov eax,DWORD PTR [ebp-0x2c]
0x08048e4c <+374>: mov edi,DWORD PTR [ebp-0x30]
0x08048e4f <+377>: cmp eax,edi ==10==
0x08048e51 <+379>: jne 0x8048e6c
0x08048e53 <+381>: test eax,eax
0x08048e55 <+383>: jle 0x8048f9b
0x08048e5b <+389>: movzx eax,BYTE PTR [esi]
0x08048e5e <+392>: lea edx,[eax-0x30]
0x08048e61 <+395>: mov BYTE PTR [esi],dl
0x08048e63 <+397>: sub eax,0x31
0x08048e66 <+400>: cmp al,0x5 ==11==
0x08048e68 <+402>: jbe 0x8048ec1
---Type to continue, or q to quit---
0x08048e6a <+404>: jmp 0x8048ea1
0x08048e6c <+406>: sub esp,0x4
0x08048e6f <+409>: push DWORD PTR [ebp-0x2c]
0x08048e72 <+412>: push 0x8049bdb
0x08048e77 <+417>: push DWORD PTR ds:0x804c720
0x08048e7d <+423>: call 0x8048930
0x08048e82 <+428>: mov DWORD PTR [esp],0x8
0x08048e89 <+435>: call 0x8048910
0x08048e8e <+440>: movzx edx,BYTE PTR [eax]
0x08048e91 <+443>: lea ebx,[edx-0x30]
0x08048e94 <+446>: mov BYTE PTR [eax],bl
0x08048e96 <+448>: add eax,0x1
0x08048e99 <+451>: sub edx,0x31
0x08048e9c <+454>: cmp dl,0x5
0x08048e9f <+457>: jbe 0x8048eca
0x08048ea1 <+459>: push DWORD PTR ds:0x804c720
0x08048ea7 <+465>: push 0x1e
0x08048ea9 <+467>: push 0x1
0x08048eab <+469>: push 0x8049dd0
0x08048eb0 <+474>: call 0x80488a0
0x08048eb5 <+479>: mov DWORD PTR [esp],0x8
0x08048ebc <+486>: call 0x8048910
0x08048ec1 <+491>: lea eax,[esi+0x1]
---Type to continue, or q to quit---
0x08048ec4 <+494>: mov edi,DWORD PTR [ebp-0x2c]
0x08048ec7 <+497>: lea ecx,[esi+edi*1]
0x08048eca <+500>: cmp eax,ecx ==12==
0x08048ecc <+502>: jne 0x8048e8e
0x08048ece <+504>: jmp 0x8048f6a
0x08048ed3 <+509>: sub esp,0x4
0x08048ed6 <+512>: push DWORD PTR [ebp-0x34]
0x08048ed9 <+515>: mov eax,DWORD PTR [ebp-0x1c]
0x08048edc <+518>: push DWORD PTR [eax]
0x08048ede <+520>: push 0x8049bf3
0x08048ee3 <+525>: call 0x8048820
0x08048ee8 <+530>: mov DWORD PTR [esp],0x8
0x08048eef <+537>: call 0x8048910
0x08048ef4 <+542>: mov ebx,0x0
0x08048ef9 <+547>: mov edi,DWORD PTR [ebp-0x2c]
0x08048efc <+550>: sub esp,0xc
0x08048eff <+553>: movsx eax,BYTE PTR [esi+ebx*1]
0x08048f03 <+557>: push eax
0x08048f04 <+558>: call 0x80499b1 ==17==
0x08048f09 <+563>: movsx edx,BYTE PTR [esi+ebx*1]
0x08048f0d <+567>: mov DWORD PTR [esp],eax
0x08048f10 <+570>: call DWORD PTR [edx*4+0x804c0a4] ==18==phase_funcs[phaseIds[defused]](input);
0x08048f17 <+577>: movsx eax,BYTE PTR [esi+ebx*1]
---Type to continue, or q to quit---
0x08048f1b <+581>: mov DWORD PTR [esp],eax ==19==
0x08048f1e <+584>: call 0x8049a8c
0x08048f23 <+589>: add esp,0x8
0x08048f26 <+592>: movsx eax,BYTE PTR [esi+ebx*1]
0x08048f2a <+596>: push eax
0x08048f2b <+597>: push 0x8049df0 //==The bomb phase %d is defused. Congratulations!==
0x08048f30 <+602>: call 0x8048820
0x08048f35 <+607>: add ebx,0x1
0x08048f38 <+610>: add esp,0x10
0x08048f3b <+613>: cmp edi,ebx
0x08048f3d <+615>: jg 0x8048efc
0x08048f3f <+617>: jmp 0x8049034
0x08048f44 <+622>: call 0x8049694
0x08048f49 <+627>: sub esp,0x8
0x08048f4c <+630>: push DWORD PTR [ebp-0x2c]
0x08048f4f <+633>: push 0x8049e20 //==Welcome to my fiendish little bomb. You have %d phases with\
0x08048f54 <+638>: call 0x8048820
0x08048f59 <+643>: mov DWORD PTR [esp],0x8049e60 ==which to blow yourself up. Have a nice day!==
0x08048f60 <+650>: call 0x80488e0
0x08048f65 <+655>: add esp,0x10
0x08048f68 <+658>: jmp 0x8048ef4 //跳
0x08048f6a <+660>: cmp DWORD PTR [ebp-0x28],0x0 ==13==
0x08048f6e <+664>: jne 0x8048fcc
---Type to continue, or q to quit---
0x08048f70 <+666>: jmp 0x8048f44 //跳
0x08048f72 <+668>: call 0x8049694
0x08048f77 <+673>: sub esp,0x8
0x08048f7a <+676>: push DWORD PTR [ebp-0x2c]
0x08048f7d <+679>: push 0x8049e20 ==Welcome to my fiendish little bomb. You have %d phases with==
0x08048f82 <+684>: call 0x8048820 ==16==
0x08048f87 <+689>: mov DWORD PTR [esp],0x8049e60
0x08048f8e <+696>: call 0x80488e0
0x08048f93 <+701>: add esp,0x10
0x08048f96 <+704>: jmp 0x8049034
0x08048f9b <+709>: cmp DWORD PTR [ebp-0x28],0x0
0x08048f9f <+713>: je 0x8048f72
0x08048fa1 <+715>: jmp 0x8049013
0x08048fa3 <+717>: call 0x8049694
0x08048fa8 <+722>: sub esp,0x8
0x08048fab <+725>: push DWORD PTR [ebp-0x2c]
0x08048fae <+728>: push 0x8049e20 ==Welcome to my fiendish little bomb. You have %d phases with==
0x08048fb3 <+733>: call 0x8048820
0x08048fb8 <+738>: mov DWORD PTR [esp],0x8049e60
0x08048fbf <+745>: call 0x80488e0
0x08048fc4 <+750>: add esp,0x10
0x08048fc7 <+753>: jmp 0x8048ef4
0x08048fcc <+758>: sub esp,0x8
---Type to continue, or q to quit---
0x08048fcf <+761>: push 0x804a092
0x08048fd4 <+766>: push DWORD PTR [ebp-0x34]
0x08048fd7 <+769>: call 0x8048960
0x08048fdc <+774>: mov ds:0x804c790,eax
0x08048fe1 <+779>: add esp,0x10
0x08048fe4 <+782>: test eax,eax
0x08048fe6 <+784>: jne 0x8048fa3
0x08048fe8 <+786>: jmp 0x8048ed3 ==14==
0x08048fed <+791>: call 0x8049694
0x08048ff2 <+796>: sub esp,0x8
0x08048ff5 <+799>: push DWORD PTR [ebp-0x2c]
0x08048ff8 <+802>: push 0x8049e20 ==Welcome to my fiendish little bomb. You have %d phases with==
0x08048ffd <+807>: call 0x8048820
0x08049002 <+812>: mov DWORD PTR [esp],0x8049e60
0x08049009 <+819>: call 0x80488e0
0x0804900e <+824>: add esp,0x10
0x08049011 <+827>: jmp 0x8049034
0x08049013 <+829>: sub esp,0x8
0x08049016 <+832>: push 0x804a092
0x0804901b <+837>: push DWORD PTR [ebp-0x34]
0x0804901e <+840>: call 0x8048960
0x08049023 <+845>: mov ds:0x804c790,eax
0x08049028 <+850>: add esp,0x10
---Type to continue, or q to quit---
0x0804902b <+853>: test eax,eax
0x0804902d <+855>: jne 0x8048fed
0x0804902f <+857>: jmp 0x8048ed3
0x08049034 <+862>: mov eax,0x0
0x08049039 <+867>: lea esp,[ebp-0x10]
0x0804903c <+870>: pop ecx
0x0804903d <+871>: pop ebx
0x0804903e <+872>: pop esi
0x0804903f <+873>: pop edi
0x08049040 <+874>: pop ebp
0x08049041 <+875>: lea esp,[ecx-0x4]
0x08049044 <+878>: ret
End of assembler dump.