计算机系统基础实验二

 

 

学生实验报告

 

实验课程名称:计算机系统基础

实验项目名称:BinaryBomb实验

实验类型: 验证性 

指导教师:

 

实验日期:   2020 年 11 月 29 日

学生姓名

 

学号

07

班级

 

专业名称

软件工程

实验组

其他成员

实验地点

 

实验成绩

(教师签名)

 

 

 

 

 


实验目的与要求

1.加深对IA-32函数调用规则和栈结构的具体理解。

2. 了解汇编语言的特点和实际执行过程。特别是,针对高级语言中的分支、循环、嵌套等、结构体、指针、链表等在汇编语言级别如何实现加深理解。

3. 通过逆向工程进行程序执行过程的分析并抽取和破译通过密码。

实验原理与内容

n  作为实验目标的二进制炸弹“binary bombs” Linux可执行程序包含了多个阶段(或关卡),在每个阶段程序要求你输入一个特定字符串,如果输入满足程序代码所定义的要求,该阶段的炸弹就被拆除了,否则程序输出“炸弹爆炸BOOM!!! ”的提示并转到下一阶段再次等待对应的输入 ——实验的目标是设法得出解除尽可能多阶段的字符串。

n  为完成二进制炸弹拆除任务,需要通过反汇编和理解可执行炸弹文件程序或使用gdb调试器跟踪每一阶段的机器代码,从中理解关键机器指令的行为和作用,进而设法推断拆除炸弹所需的目标字符串。

 

通过逆向工程分析,拆解二进制炸弹程序

包含了7个阶段以及1个隐藏阶段,分别集中考察对以下二进制程序表示各方面的理解和掌握:

n  阶段0:字符串比较

n  阶段1:浮点表示

n  阶段2:循环

n  阶段3:条件/分支

n  阶段4:递归调用和栈

n  阶段5:指针

n  阶段6:链表/指针/结构

n  隐藏阶段:只有在阶段4的拆解字符串后再附加一特定字符串后才会出现(作为最后一个阶段)

 

实验设备与软件环境

1.硬件环境:笔记本电脑

2.软件环境:Debian10 32位

3.虚拟机

实验过程与结果

我只做了前四道,结果:

计算机系统基础实验二

 

 计算机系统基础实验二

 

 

 

 

Phase_0:

08049455 <phase_0>:

 8049455:  55                       push   %ebp

 8049456:  89 e5                    mov    %esp,%ebp

 8049458:  83 ec 08                 sub    $0x8,%esp

 804945b:83 ec 08               sub    $0x8,%esp

 804945e:  68 ec a1 04 08           push   $0x804a1ec #存放预定字符串的地址

 8049463:  ff 75 08                 pushl  0x8(%ebp)

 8049466:  e8 44 07 00 00           call   8049baf <strings_not_equal>

 804946b:83 c4 10               add    $0x10,%esp

 804946e:  85 c0                    test   %eax,%eax

 8049470:  74 0c                    je     804947e <phase_0+0x29>

 8049472:  e8 a0 09 00 00           call   8049e17 <explode_bomb>

 8049477:  b8 00 00 00 00           mov    $0x0,%eax

 804947c:  eb 05                    jmp    8049483 <phase_0+0x2e>

 804947e:  b8 01 00 00 00           mov    $0x1,%eax

 8049483:  c9                       leave 

 8049484:  c3                       ret   

 

计算机系统基础实验二

 

 

Phase_0的答案就是Disks are constructed from platters.

Phase_1:

08049485 <phase_1>:

 8049485:  55                          push   %ebp

 8049486:  89 e5                       mov    %esp,%ebp

 8049488:  83 ec 18                    sub    $0x18,%esp

 804948b:c7 45 f4 50 cd 4f 35   movl   $0x354fcd50,-0xc(%ebp)

 8049492:  db 45 f4                    fildl  -0xc(%ebp)

 8049495:  d9 5d f0                    fstps  -0x10(%ebp)

 8049498:  8d 45 e8                    lea    -0x18(%ebp),%eax

 804949b:50                        push   %eax

 804949c:  8d 45 ec                    lea    -0x14(%ebp),%eax

 804949f:  50                          push   %eax

 80494a0:  68 11 a2 04 08              push   $0x804a211 #明码地址,由此行得知需要输入两个“%d %d”数

 80494a5:  ff 75 08                    pushl  0x8(%ebp)

 80494a8:  e8 23 fc ff ff              call   80490d0 <__isoc99_sscanf@plt>

 80494ad:  83 c4 10                    add    $0x10,%esp

 80494b0:83 f8 02                  cmp    $0x2,%eax  #判断输入的是不是两个数,是的话跳到8049e17,不是的话bomb

 80494b3:74 0c                     je     80494c1 <phase_1+0x3c>

 80494b5:e8 5d 09 00 00            call   8049e17 <explode_bomb>

 80494ba:  b8 00 00 00 00              mov    $0x0,%eax

 80494bf:  eb 34                       jmp    80494f5 <phase_1+0x70>

 80494c1:  8d 45 f0                    lea    -0x10(%ebp),%eax

 80494c4:  83 c0 02                    add    $0x2,%eax  #%eax+2

 80494c7:  0f b7 00                    movzwl (%eax),%eax

 80494ca:  0f bf d0                    movswl %ax,%edx

 80494cd:  8b 45 ec                    mov    -0x14(%ebp),%eax

 80494d0:39 c2                     cmp    %eax,%edx  #输入的第一个数和%edx的值是否相等,不相等的话,跳到80494e4->bomb

 80494d2:75 10                     jne    80494e4 <phase_1+0x5f>

 80494d4:8d 45 f0                  lea    -0x10(%ebp),%eax

 80494d7:0f b7 00                  movzwl (%eax),%eax

 80494da:  0f bf d0                    movswl %ax,%edx

 80494dd:8b 45 e8                  mov    -0x18(%ebp),%eax

 80494e0:  39 c2                       cmp    %eax,%edx  #输入的第二个与%edx的值是否相等,相等的话,跳到80494f0,正常结束,不相等bomb

 80494e2:  74 0c                       je     80494f0 <phase_1+0x6b>

 80494e4:  e8 2e 09 00 00              call   8049e17 <explode_bomb>

 80494e9:  b8 00 00 00 00              mov    $0x0,%eax

 80494ee:  eb 05                       jmp    80494f5 <phase_1+0x70>

 80494f0:  b8 01 00 00 00              mov    $0x1,%eax

 80494f5:  c9                          leave 

 80494f6:  c3                          ret  

 

 计算机系统基础实验二

 

 计算机系统基础实验二

 

 

Phase_1的答案,第一个数是20053 第二个数是16181

Phase_2

080494f7 <phase_2>:

 80494f7:  55                       push   %ebp

 80494f8:  89 e5                    mov    %esp,%ebp

 80494fa:  83 ec 28                 sub    $0x28,%esp

 80494fd:  83 ec 04                 sub    $0x4,%esp

 8049500:  6a 07                    push   $0x7   #输入7个数字

 8049502:  8d 45 d8                 lea    -0x28(%ebp),%eax

 8049505:  50                       push   %eax

 8049506:  ff 75 08                 pushl  0x8(%ebp)

 8049509:  e8 e7 05 00 00           call   8049af5 <read_n_numbers> #读取7个数字

 804950e:  83 c4 10                 add    $0x10,%esp

 8049511:  85 c0                    test   %eax,%eax

 8049513:  75 07                    jne    804951c <phase_2+0x25>

 8049515:  b8 00 00 00 00           mov    $0x0,%eax

 804951a:  eb 65                    jmp    8049581 <phase_2+0x8a>

 804951c:  8b 45 d8                 mov    -0x28(%ebp),%eax

 804951f:  83 f8 1c                 cmp    $0x1c,%eax    #第一个数必须为28,如果不是28bomb

 8049522:  75 08                    jne    804952c <phase_2+0x35>

 8049524:  8b 45 dc                 mov    -0x24(%ebp),%eax

 8049527:  83 f8 39                 cmp    $0x39,%eax    #第二个数必须为57,不等就bomb,相等跳到8049538执行

 804952a:  74 0c                    je     8049538 <phase_2+0x41>

 804952c:  e8 e6 08 00 00           call   8049e17 <explode_bomb>

 8049531:  b8 00 00 00 00           mov    $0x0,%eax

 8049536:  eb 49                    jmp    8049581 <phase_2+0x8a>

 8049538:  c7 45 f4 02 00 00 00     movl   $0x2,-0xc(%ebp)   #初始i=2,跳到判断条件

 804953f:  eb 35                    jmp    8049576 <phase_2+0x7f>

//循环体

 8049541:  8b 45 f4                 mov    -0xc(%ebp),%eax

 8049544:  8b 44 85 d8              mov    -0x28(%ebp,%eax,4),%eax

 8049548:  8b 55 f4                 mov    -0xc(%ebp),%edx

 804954b:83 ea 02               sub    $0x2,%edx  #第i-2个数,num[i-2]

 804954e:  8b 54 95 d8              mov    -0x28(%ebp,%edx,4),%edx

 8049552:  89 d1                    mov    %edx,%ecx

 8049554:  d1 f9                    sar    %ecx   #第i-2个数除以2

 8049556:  8b 55 f4                 mov    -0xc(%ebp),%edx

 8049559:  83 ea 01                 sub    $0x1,%edx  #第i-1个数减1

 804955c:  8b 54 95 d8              mov    -0x28(%ebp,%edx,4),%edx

 8049560:  01 ca                    add    %ecx,%edx  #num[i]=(num[i-2]-1)+num[i-1]

 8049562:  39 d0                    cmp    %edx,%eax

 8049564:  74 0c                    je     8049572 <phase_2+0x7b>

//跳出循环

 8049566:  e8 ac 08 00 00           call   8049e17 <explode_bomb>

 804956b:  b8 00 00 00 00           mov    $0x0,%eax

 8049570:  eb 0f                    jmp    8049581 <phase_2+0x8a>

//循环判断条件

 8049572:  83 45 f4 01              addl   $0x1,-0xc(%ebp)   #i++

 8049576:  83 7d f4 06              cmpl   $0x6,-0xc(%ebp)   #i<=6

 804957a:  7e c5                    jle    8049541 <phase_2+0x4a>

 804957c:  b8 01 00 00 00           mov    $0x1,%eax

 8049581:  c9                       leave 

 8049582:  c3                       ret   

 计算机系统基础实验二

 

 

Phase_2的答案前两个规定为28 57后面的可以调试出来,或者有规律的,规律就是第三个数等于第一个数除以2加上第二个数,第四个数就等于第二个数减1除以2加第三个数,以此类推,得到的答案就是

28 57 71 99 134 183 250

Phase3

08049583 <phase_3>:

 8049583:  55                          push   %ebp

 8049584:  89 e5                       mov    %esp,%ebp

 8049586:  83 ec 18                    sub    $0x18,%esp

 8049589:  8d 45 e8                    lea    -0x18(%ebp),%eax

 804958c:  50                          push   %eax

 804958d:8d 45 ec                  lea    -0x14(%ebp),%eax

 8049590:  50                          push   %eax

 8049591:  68 11 a2 04 08              push   $0x804a211    #此行说明输入两个 %d % d的数

 8049596:  ff 75 08                    pushl  0x8(%ebp)

 8049599:  e8 32 fb ff ff              call   80490d0 <__isoc99_sscanf@plt>

 804959e:  83 c4 10                    add    $0x10,%esp

 80495a1:  89 45 f0                    mov    %eax,-0x10(%ebp)

 80495a4:  83 7d f0 01                 cmpl   $0x1,-0x10(%ebp)  #输入的数要大于1就跳转,否则bomb

 80495a8:  7f 0f                       jg     80495b9 <phase_3+0x36>

 80495aa:  e8 68 08 00 00              call   8049e17 <explode_bomb>

 80495af:  b8 00 00 00 00              mov    $0x0,%eax

 80495b4:e9 8a 00 00 00            jmp    8049643 <phase_3+0xc0>

 80495b9:c7 45 f4 00 00 00 00   movl   $0x0,-0xc(%ebp)

 80495c0:  8b 45 ec                    mov    -0x14(%ebp),%eax

 80495c3:  83 e8 1d                    sub    $0x1d,%eax #%eax-29

 80495c6:  83 f8 08                    cmp    $0x8,%eax #%eax-29<8,无符号比较减去29要小于8,即要小于37

 80495c9:  77 53                       ja     804961e <phase_3+0x9b>

 80495cb:  8b 04 85 18 a2 04 08     mov    0x804a218(,%eax,4),%eax    #0x804a218,此地址查看第一个数输入跳到哪里,决定第二个数是多少

 80495d2:ff e0                     jmp    *%eax 

 80495d4:81 45 f4 14 02 00 00   addl   $0x214,-0xc(%ebp) #第一个数为29时,第二个数为532

 80495db:81 45 f4 d5 02 00 00   addl   $0x2d5,-0xc(%ebp) #第一个数为30时,第二个数为725

 80495e2:  81 6d f4 14 02 00 00     subl   $0x214,-0xc(%ebp) #第一个数为31时,第二个数为532

 80495e9:  81 45 f4 14 02 00 00     addl   $0x214,-0xc(%ebp) #第一个数为32时,第二个数为532

 80495f0:  81 45 f4 d5 02 00 00     addl   $0x2d5,-0xc(%ebp) #第一个数为33时,第二个数为725

 80495f7:  81 6d f4 14 02 00 00     subl   $0x214,-0xc(%ebp) #第一个数为34时,第二个数为532

 80495fe:  81 45 f4 d5 02 00 00     addl   $0x2d5,-0xc(%ebp) #第一个数为35时,第二个数为725

 8049605:  81 6d f4 d5 02 00 00     subl   $0x2d5,-0xc(%ebp) #第一个数为36时,第二个数为725

 804960c:  81 45 f4 14 02 00 00     addl   $0x214,-0xc(%ebp) #第一个数为37时,第二个数为532

 8049613:  90                          nop

 8049614:  8b 45 ec                    mov    -0x14(%ebp),%eax

 8049617:  83 f8 23                    cmp    $0x23,%eax    #第一个数要小于35,大于就bomb

 804961a:  7f 16                       jg     8049632 <phase_3+0xaf>

 804961c:  eb 0c                       jmp    804962a <phase_3+0xa7>

 804961e:  e8 f4 07 00 00              call   8049e17 <explode_bomb>

 8049623:  b8 00 00 00 00              mov    $0x0,%eax

 8049628:  eb 19                       jmp    8049643 <phase_3+0xc0>

 804962a:  8b 45 e8                    mov    -0x18(%ebp),%eax 

 804962d:39 45 f4                  cmp    %eax,-0xc(%ebp)   #比较输入的第二个数是否与-0xc(%ebp)里的值相等,相等结束,不等bomb

 8049630:  74 0c                       je     804963e <phase_3+0xbb>

 8049632:  e8 e0 07 00 00              call   8049e17 <explode_bomb>

 8049637:  b8 00 00 00 00              mov    $0x0,%eax

 804963c:  eb 05                       jmp    8049643 <phase_3+0xc0>

 804963e:  b8 01 00 00 00              mov    $0x1,%eax

 8049643:  c9                       l   eave 

 8049644:  c3                       ret   

 计算机系统基础实验二

 

 

我输入的第一个数是33,由图知道下一个就转到0x080495d4,得出第二个数是725,这题的答案不唯一

操作异常问题与解决方案

对于linux操作命令的不熟悉,不懂得如何调试,对于反汇编代码的指令不熟悉,经过百度和csdn已经可以解决

实验总结

经过本次实验,我对汇编代码有了进一步的了解,加深了我对计算机系统基础的认识,让我受益良多

上一篇:【转贴】GCC内联汇编基础


下一篇:Python学习第三天----Linux基础命令