




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
课程实验报告 课 程 名 称: 计算机组成与结构 实 验 名 称: 拆炸弹 专 业 班 级: 姓 名: 学 号: 完 成 时 间: (一) 实验目的:程序运行中有6个关卡(6个phase),每个phase需要用户在终端上输入特定的字符或者数字才能通关,否则会引爆炸弹!那么如何才能知道输入什么内容呢?这需要你使用gdb工具反汇编出汇编代码,结合c语言文件找到每个关卡的入口函数。然后分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符通关。(二) 实验环境:虚拟机ubuntu系统下32位操作系统,终端,gdb工具。(三) 实验目的和操作:拆炸弹准备操作:查看给出的bomb.c中的代码,得知控制检测密码正误的6个函数分别为:phase_1,phase_2,phase_3,phase_4,phase_5,phase_6。使用gbd工具对可执行文件bomb进行反汇编:打开bomb可执行文件所在的文件夹输入反汇编命令objdump -d bomb后,出现了大量汇编代码,在终端窗口可以看到很多行的汇编代码。也可以使用汇编指令objdump -d bomb 1.txt将汇编代码输出到服务器上一个自动生成的叫1.txt的文件中。开始拆炸弹::的反汇编代码如下:0x08048f61 :push %ebp0x08048f62 :mov %esp,%ebp0x08048f64 :sub $0x18,%esp0x08048f67 :movl 0x804a15c,0x4(%esp) /sp寄存器地址指向$0x804a15c0x08048f6f :mov 0x8(%ebp),%eax 将$0x804a15c的数据移给eax寄存器 0x08048f72 :mov %eax,(%esp)/函数条用的准备过程0x08048f75 :call x8048fab 0x08048f7a :test %eax,%eax /与这一行比较用户输入和$0x804a15c中的值0x08048f7c :je 0x8048f83 0x08048f7e :call x80490d1 0x08048f83 :leave 0x08048f84 :ret 通过分析代码可知:phase_1的密码是固定储存在$0x804a15c中的。令$0x804a15c中的数据与用户输入的数据比较,若相同则跳过explode_bomb,避开炸弹。用命令x/s 0x804a15c查看其中的数据如下:输入We have to stand with our North Korean allies.结果为:结果正确。反汇编代码如下:0x08048d6a :push %ebp0x08048d6b :mov %esp,%ebp0x08048d6d :push %esi0x08048d6e :push %ebx0x08048d6f :sub $0x30,%esp0x08048d72 :lea -0x20(%ebp),%eax0x08048d75 :mov %eax,0x4(%esp)0x08048d79 :mov 0x8(%ebp),%eax0x08048d7c :mov %eax,(%esp)0x08048d7f :call 0x804910b 读取六个数字0x08048d84 :cmpl $0x0,-0x20(%ebp) 0和第一个数字比较,不相等则爆炸。0x08048d88 :jne 0x8048d90 0x08048d8a :cmpl $0x1,-0x1c(%ebp) 1和第二个数字比较,相等则跳过爆炸。0x08048d8e :je 0x8048d95 0x08048d90 :call 0x80490d1 0x08048d95 :lea -0x18(%ebp),%ebx ebx指向第三个数字。0x08048d98 :lea -0x8(%ebp),%esi esi指向第六个数字再向后移一位的地址。0x08048d9b :mov -0x4(%ebx),%eax ebx向前第一位的数字赋给eax。0x08048d9e :add -0x8(%ebx),%eax eax再加上ebx向前第二位的数字。0x08048da1 :cmp %eax,(%ebx) 比较ebx前两位的和与ebx指向的数字。0x08048da3 :je 0x8048daa 相等则跳过爆炸(explode_bomb)0x08048da5 :call 0x80490d1 0x08048daa :add $0x4,%ebx ebx地址向后移动一位(四个字节)。0x08048dad :cmp %esi,%ebx 如果还未超过第六位数字,则跳转0x8048d9行。0x08048daf :jne 0x8048d9b 0x08048db1 :add $0x30,%esp0x08048db4 :pop %ebx0x08048db5 :pop %esi0x08048db6 :pop %ebp0x08048db7 :ret 从上面的代码分析可知:phase_2的密码需要输入六位数字,并且第一个是0,第二个是1,然后执行到0x8048d9b这一行代码发现往下运行会出现一个循环,两条重要指令是imull -0x4(%esi,%edx,4),%eax 和cmp %eax,(%esi,%edx,4),其中%eax 和%edx在每次循环中加1直到寄存器中值超过6,程序执行完毕。在循环中执行的是一个数等于前两个数之和,寄存器ebx每次循环将向前第一位的数字赋给寄存器eax。从而实现了计算前6位的斐波那契数列的值为:0 1 1 2 3 5。执行结果如下:反汇编代码如下:0x08048ea1 :push %ebp0x08048ea2 :mov %esp,%ebp0x08048ea4 :sub $0x28,%esp0x08048ea7 :lea -0x10(%ebp),%eax0x08048eaa :mov %eax,0 xc(%esp) 此处为第二个数字。0x08048eae :lea -0xc(%ebp),%eax0x08048eb1 :mov %eax,0x8(%esp) 此处为第一个数字。0x08048eb5 :movl $0x804a23e,0x4(%esp) 用x/s 0x804a23e命令查看$0x804a23e为0x08048ebd :mov 0x8(%ebp),%eax %d %d,即要输入两个整数,上面已经指出。0x08048ec0 :mov %eax,(%esp)0x08048ec3 :call 0x8048840 0x08048ec8 :cmp $0x1,%eax 以上两行即要求输入至少两组数据,否则引爆。0x08048ecb :jg 0x8048ed2 0x08048ecd :call 0x80490d1 0x08048ed2 :cmpl $0x7,-0xc(%ebp) 第一个数大于7引爆,即第一个数小于等于7。0x08048ed6 :ja 0x8048f43 0x08048ed8 :mov -0xc(%ebp),%eax0x08048edb :jmp *0x804a1a0(,%eax,4) 跳转至0x804a1a0+eax*4(第一个数)内数据所0x08048ee2 :mov $0x0,%eax 指的行数。0x08048ee7 :jmp 0x8048f3c 0x08048ee9 :mov $0x0,%eax0x08048eee :xchg %ax,%ax0x08048ef0 :jmp 0x8048f37 0x08048ef2 :mov $0x0,%eax0x08048ef7 :jmp 0x8048f32 0x08048ef9 :mov $0x0,%eax0x08048efe :xchg %ax,%ax0x08048f00 :jmp 0x8048f2d 0x08048f02 :mov $0x0,%eax0x08048f07 :jmp 0x8048f28 0x08048f09 :mov $0x0,%eax0x08048f0e :xchg %ax,%ax0x08048f10 :jmp 0x8048f23 0x08048f12 :mov $0x314,%eax 当第一个数为0时跳转到此处,第二个数x=788。0x08048f17 :jmp 0x8048f1e 跳转到0x8048f1e。0x08048f19 :mov $0x0,%eax0x08048f1e :sub $0x35a,%eax x=x-8580x08048f23 :add $0x2ef,%eax x=x+7510x08048f28 :sub $0x216,%eax x=x-5340x08048f2d :add $0x216,%eax x=x+5340x08048f32 :sub $0x216,%eax x=x-5340x08048f37 :add $0x216,%eax x=x+5340x08048f3c :sub $0x216,%eax x=x-5340x08048f41 :jmp 0x8048f4d 跳转到0x8048f4d行。0x08048f43 :call 0x80490d1 0x08048f48 :mov $0x0,%eax 0x08048f4d :cmpl $0x5,-0xc(%ebp) 第一个数大于5引爆,即第一个数小于等于5。0x08048f51 :jg 0x8048f58 0x08048f53 :cmp -0x10(%ebp),%eax 第一个数是0时,算得x=147,即第二个数0x08048f56 :je 0x8048f5d 为147。0x08048f58 :call 0x80490d1 0x08048f5d :leave 0x08048f5e :xchg %ax,%ax0x08048f60 :ret 从以上分析可知:再往下然后看到jmp输入指令x/s 0x8049abb,得到0x8049abb:%d %d,显示出应该输入两个数字。如果输入不满足两个数,则会引爆炸弹,并且第二个与第一个数的值相关。第一个值得范围为0-5的整数,当第一个数输入的不是0-5的整数,也会引爆炸弹。输入的第一个数存入在寄存器eax中,并且根据跳转指令jmp *0x804a1a0(,%eax,4)选择将要跳转的位置,执行相应的代码计算出第二个需要输入的值。1)当第一个数输入的是0,eax寄存器中对应的值为0,则跳转到指令*0x804a1a0用指令查看*0x804a1a0的值为:发现*0x804a1a0对应的值为0x8048f12,找到0x08048f12对应的代码执行发现第二个数计算得结果为:x = 0x(314-35a 2ef 216 +216-216+216-216 + ) = 1472)当输入的第一个数是1时,同理用指令查看*(0x804a1a0+4)的值为则代码从0x08048f19对应的代码执行第二个数计算得结果为:x = 0x(-35a 2ef 216 +216-216+216-216 + ) = -6413)同理输入2,3,4,5对应的第二个数字为:217,534,0,-534结果打印为:反汇编代码如下:0x08048e2e :push %ebp0x08048e2f :mov %esp,%ebp0x08048e31 :sub $0x28,%esp0x08048e34 :lea -0x10(%ebp),%eax0x08048e37 :mov %eax,0xc(%esp) 此处第二段数字。0x08048e3b :lea -0xc(%ebp),%eax0x08048e3e :mov %eax,0x8(%esp) 此处第一段数字。0x08048e42 :movl $0x804a23e,0x4(%esp) $0x804a23e内为%d %d,即输入两个整数。0x08048e4a :mov 0x8(%ebp),%eax0x08048e4d :mov %eax,(%esp)0x08048e50 :call 0x8048840 0x08048e55 :cmp $0x2,%eax 以上两行要求之前输入的为两个数据,否则引爆。0x08048e58 :jne 0x8048e66 0x08048e5a :mov -0xc(%ebp),%eax0x08048e5d :test %eax,%eax 第一段数据大于等于0,否则引爆。0x08048e5f :js 0x8048e66 0x08048e61 :cmp $0xe,%eax 第一段数据小于等于14时跳过引爆。0x08048e64 :jle 0x8048e6b 0x08048e66 :call 0x80490d1 0x08048e6b :movl $0xe,0x8(%esp)0x08048e73 :movl $0x0,0x4(%esp)0x08048e7b :mov -0xc(%ebp),%eax0x08048e7e :mov %eax,(%esp)0x08048e81 :call 0x8048b60 这几行为运行一个递归函数func4来确定第一0x08048e86 :cmp $0x1,%eax 段数据的值。0x08048e89 :jne 0x8048e91 0x08048e8b :cmpl $0x1,-0x10(%ebp) 第二个数据等于1则跳过爆炸。0x08048e8f :je 0x8048e9d 0x08048e91 :lea 0x0(%esi,%eiz,1),%esi0x08048e98 :call 0x80490d1 0x08048e9d :leave 0x08048e9e :xchg %ax,%ax0x08048ea0 :ret 以上对代码的分析可以看出,第二个数据确定为1。第一个数据范围为大于等于0,小于14,并且由一个递归函数func4又一次缩小了范围。但因为这个递归函数太过繁杂,而第一个数据范围又不大,直接将第一个数据从0尝试到13,得到了三个数字8、9、11符合要求。因此密码有三组:8 1,9 1,11 1。反汇编代码如下:0x08048db8 :push %ebp0x08048db9 :mov %esp,%ebp0x08048dbb :push %esi0x08048dbc :push %ebx0x08048dbd :sub $0x20,%esp0x08048dc0 :lea -0x10(%ebp),%eax0x08048dc3 :mov %eax,0xc(%esp) 此处为第二个数。0x08048dc7 :lea -0xc(%ebp),%eax0x08048dca :mov %eax,0x8(%esp) 此处为第一个数。0x08048dce :movl $0x804a23e,0x4(%esp) $0x804a23e内为%d %d,即输入两个整数。0x08048dd6 :mov 0x8(%ebp),%eax0x08048dd9 :mov %eax,(%esp)0x08048ddc :call 0x8048840 0x08048de1 :cmp $0x1,%eax 以上两行保证输入数据多于1组,否则引爆。0x08048de4 :jg 0x8048deb 0x08048de6 :call 0x80490d1 0x08048deb :mov -0xc(%ebp),%eax0x08048dee :and $0xf,%eax 按位与,即保留第一个数的后四位。0x08048df1 :mov %eax,-0xc(%ebp)0x08048df4 :cmp $0xf,%eax 第一个数二进制后四位不能为(1111)2,否则引爆。0x08048df7 :je 0x8048e22 0x08048df9 :mov $0x0,%ecx0x08048dfe :mov $0x0,%edx0x08048e03 :mov $0x804a1c0,%ebx $0x804a1c0指向的是一个数组,下面分析。0x08048e08 :add $0x1,%edx0x08048e0b :mov (%ebx,%eax,4),%eax0x08048e0e :add %eax,%ecx0x08048e10 :cmp $0xf,%eax0x08048e13 :jne 0x8048e08 以上五行为一个for循环语句, 0x08048e15 :mov %eax,-0xc(%ebp) 0x08048e18 :cmp $0xf,%edx 上述的for循环要循环15次。0x08048e1b :jne 0x8048e22 0x08048e1d :cmp %ecx,-0x10(%ebp) 确定第二个数的值,下面分析。0x08048e20 :je 0x8048e27 0x08048e22 :call 0x80490d1 0x08048e27 :add $0x20,%esp0x08048e2a :pop %ebx0x08048e2b :pop %esi0x08048e2c :pop %ebp0x08048e2d :ret 从代码的分析中可知:需要输入两个数,并且第一个数的后四位不能为1111,若为1111则引爆炸弹。在程序中我们会遇到一个给定值0x804a1c0。我们可以查看其值为:查看16个值,因为发现后面的循环中需要循环遍历使用16个数。其中最难懂的代码就是0x08048e0b :mov (%ebx,%eax,4),%eax这一行代码,ebx对应的是0x804a1c0对应的首地址。这句话的意思解释为C语言的意思就是 n = an。寄存器ecx保存的是计算得sum的总值。这段代码翻译成c语言类似于:sum=0;for(i=1;n=15;i+) n=an; sum+=n;其中第一次n取的值应为用户输入的第一个数二进制下的后四位。之后每次都等于an,sum为除去第一次之外所有n取值的和。采用逆推的方法来求出n第一次取的值。序号0123456789101112131415数组1021478121511041133965for循环当n为15时终止,因此最后一个n为15,对应序号为上一个n,即6。同理,可以得到,n从第一个到最后一个为:5 12 3 7 11 13 9 4 8 0 10 1 2 14 6 15。sum=15*16/2-5=115。即用户输入的第二个数为115。用户输入第一个数二进制下的后四位为0101(即第一个n=5),由于第一位只要满足输入的数的后四位不为1111,第二个数为115即可,如:10 115,5 1 15。反汇编代码如下:0x08048c89 :push %ebp0x08048c8a :mov %esp,%ebp0x08048c8c :push %edi0x08048c8d :push %esi0x08048c8e :push %ebx0x08048c8f :sub $0x5c,%esp0x08048c92 :lea -0x30(%ebp),%eax0x08048c95 :mov %eax,0x4(%esp)0x08048c99 :mov 0x8(%ebp),%eax0x08048c9c :mov %eax,(%esp)0x08048c9f :call 0x804910b 0x08048ca4 :mov $0x0,%esi0x08048ca9 :lea -0x30(%ebp),%edi0x08048cac :mov (%edi,%esi,4),%eax 第esi+1个数给eax。开始外层for循环。0x08048caf :sub $0x1,%eax eax-。0x08048cb2 :cmp $0x5,%eax eax小于等于5跳过炸弹,即第esi+1个数小于等于6。0x08048cb5 :jbe 0x8048cbc 0x08048cb7 :call 0x80490d1 0x08048cbc :add $0x1,%esi esi+。0x08048cbf :cmp $0x6,%esi esi不等于6时不跳转。等于6时跳转至0x8048ce6。0x08048cc2 :je 0x8048ce6 0x08048cc4 :lea (%edi,%esi,4),%ebx 第esi+1个数给ebx。0x08048cc7 :mov %esi,-0x4c(%ebp)0x08048cca :mov -0x4(%edi,%esi,4),%eax 第esi个数给eax。开始内层for循环。0x08048cce :cmp (%ebx),%eax 若eax和ebx不相等则跳过炸弹。0x08048cd0 :jne 0x8048cd7 0x08048cd2 :call 0x80490d1 0x08048cd7 :addl $0x1,-0x4c(%ebp) 每次加1。0x08048cdb :add $0x4,%ebx ebx+=4。0x08048cde :cmpl $0x5,-0x4c(%ebp) 小于等于5时跳转,即能循环6-esi次。0x08048ce2 :jle 0x8048cca 0x08048ce4 :jmp 0x8048cac 0x08048ce6 : mov $0x0,%ebx0x08048ceb : lea -0x30(%ebp),%edi0x08048cee :jmp 0x8048d06 跳转到第0x8048d06行。0x08048cf0 : mov 0x8(%edx),%edx 此处为两层for循环语句.作用为通过用户0x08048cf3 : add $0x1,%eax 输入的六个数字来调整链表中6个元素的位置。0x08048cf6 : cmp %ecx,%eax0x08048cf8 : jne 0x8048cf0 0x08048cfa : mov %edx,-0x48(%ebp,%esi,4)0x08048cfe : add $0x1,%ebx0x08048d01 :cmp $0x6,%ebx0x08048d04 :je 0x8048d1c 0x08048d06 :mov %ebx,%esi0x08048d08 :mov (%edi,%ebx,4),%ecx0x08048d0b :mov $0x804c0c4,%edx 0x804c0c4查看可知是一个链表,图下附。0x08048d10 :mov $0x1,%eax0x08048d15 :cmp $0x1,%ecx0x08048d18 :g 0x8048cf0 0x08048d1a :mp 0x8048cfa 0x08048d1c :mov -0x48(%ebp),%ebx 重新排列链表的值。0x08048d1f :mov -0x44(%ebp),%eax0x08048d22 :mov %eax,0x8(%ebx)0x08048d25 :mov -0x40(%ebp),%edx0x08048d28 :mov %edx,0x8(%eax)0x08048d2b :mov -0x3c(%ebp),%eax0x08048d2e :mov %eax,0x8(%edx)0x08048d31 :mov -0x38(%ebp),%edx0x08048d34 :mov %edx,0x8(%eax)0x08048d37 :mov -0x34(%ebp),%eax0x08048d3a :mov %eax,0x8(%edx) 对链表的值进行检测。0x08048d3d :movl $0x0,0x8(%eax)0x08048d
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 一棵开花的树1500字12篇
- 杭州宋城游记650字9篇
- 小王子读后感900字(9篇)
- 早期育儿知识培训方案课件
- 纪检业务知识培训目的课件
- 统编版语文四年级上册《语文园地八》课件
- 早期埃及课件
- 农村资源开发综合利用合同书
- 农村环保技术应用合作合同书
- 六年级观后感八佰观后感十五550字12篇
- 智能交通概论全套教学课件
- Stevens-Johnson-综合征及中毒性表皮坏死松解症
- 第六单元名著导读《水浒传》公开课一等奖创新教学设计统编版语文九年级上册
- 腾势使用说明书
- 五通桥区工业基地固体废弃物填埋场工程环评报告
- 增资先决条件确认函
- 园林植物基础PPT完整全套教学课件
- 国家有关安全生产的方针政策法律法规
- 江苏省综合评标评审专家库公共基础题库部分
- 丙二酸酯和吡唑结合封闭异氰酸酯提高涂料性能
- 北师大版小学六年级数学上册导学案全册
评论
0/150
提交评论