CSAPP 3e: Bomb lab (phase_4)

先贴出phase_4的代码:

0000000000400fce <func4>:            ;%rdi=num_0;%rsi=0;%rdx=0xe;
  400fce:    48 83 ec 08              sub    $0x8,%rsp
  400fd2:    89 d0                    mov    %edx,%eax    ;%eax=0xe;
  400fd4:    29 f0                    sub    %esi,%eax    ;%eax=0xe-0==e;
  400fd6:    89 c1                    mov    %eax,%ecx    ;%ecx=e;
  400fd8:    c1 e9 1f                 shr    $0x1f,%ecx    ;右移31位,注意shr是逻辑右移!!!
  400fdb:    01 c8                    add    %ecx,%eax    ;也就是如果%eax为正数则不变,为负数则+1;
  400fdd:    d1 f8                    sar    %eax            ;(算术)右移1位,即%eax/2;
  400fdf:    8d 0c 30                 lea    (%rax,%rsi,1),%ecx    ;%ecx=e;
  400fe2:    39 f9                    cmp    %edi,%ecx
  400fe4:    7e 0c                    jle    400ff2 <func4+0x24>        ;if(cx<=di)continue;else %edx=-(1+%rcx);
  400fe6:    8d 51 ff                 lea    -0x1(%rcx),%edx
  400fe9:    e8 e0 ff ff ff           callq  400fce <func4>                                        ;%eax=2*%eax.
  400fee:    01 c0                    add    %eax,%eax            ;注意这里,自身调用func4后的操作,%eax乘以2了,然后ret。
  400ff0:    eb 15                    jmp    401007 <func4+0x39>
  400ff2:    b8 00 00 00 00           mov    $0x0, %eax              ;注意这里,%eax=0,然后ret返回。这里才开始停止调用自身。重点中的重点!!!
  400ff7:    39 f9                    cmp    %edi,%ecx
  400ff9:    7d 0c                    jge    401007 <func4+0x39>
  400ffb:    8d 71 01                 lea    0x1(%rcx),%esi
  400ffe:    e8 cb ff ff ff           callq  400fce <func4>                                        ;%eax=2*%eax+1.
  401003:    8d 44 00 01              lea    0x1(%rax,%rax,1),%eax;注意这里,自身调用func4后的操作,%eax乘以2并加1,然后ret。
  401007:    48 83 c4 08              add    $0x8,%rsp
  40100b:    c3                       retq   

000000000040100c <phase_4>:
  40100c:    48 83 ec 18              sub    $0x18,%rsp
  401010:    48 8d 4c 24 0c           lea    0xc(%rsp),%rcx    ;这里跟之前的一样,(%rsp+0xc)存储第二个数字,令其为num_1;
  401015:    48 8d 54 24 08           lea    0x8(%rsp),%rdx    ;(%rsp+8)存储第一数,令其为num_0.
  40101a:    be cf 25 40 00           mov    $0x4025cf,%esi    ;查看内存为字符串"%d %d",说明还是输入两个数。
  40101f:    b8 00 00 00 00           mov    $0x0,%eax
  401024:    e8 c7 fb ff ff           callq  400bf0 <[email protected]>
  401029:    83 f8 02                 cmp    $0x2,%eax        ;sscanf正常返回值为2,条件跳转不执行。
  40102c:    75 07                    jne    401035 <phase_4+0x29>
  40102e:    83 7c 24 08 0e           cmpl   $0xe,0x8(%rsp)            ;if(num_0 <= 14) jmp;else to bomb;
  401033:    76 05                    jbe    40103a <phase_4+0x2e>    ;所以这里要求num_0必须小于等于14
  401035:    e8 00 04 00 00           callq  40143a <explode_bomb>
  40103a:    ba 0e 00 00 00           mov    $0xe,%edx
  40103f:    be 00 00 00 00           mov    $0x0,%esi
  401044:    8b 7c 24 08              mov    0x8(%rsp),%edi        ;这里是针对num_0的运算,调用了函数func4,这里是重点!!
  401048:    e8 81 ff ff ff           callq  400fce <func4>
  40104d:    85 c0                    test   %eax,%eax            ;if(%eax==0)jmp;else to bomb;
  40104f:    75 07                    jne    401058 <phase_4+0x4c>;也就是call func4的返回值必须为0,否则爆炸。
  401051:    83 7c 24 0c 00           cmpl   $0x0,0xc(%rsp)
  401056:    74 05                    je     40105d <phase_4+0x51> ;这里比较num_1,要求第二个数必须等于0。
  401058:    e8 dd 03 00 00           callq  40143a <explode_bomb>
  40105d:    48 83 c4 18              add    $0x18,%rsp
  401061:    c3                       retq   

  指令的讲解在注释里了,但是想讲讲我的另一种分析方法:

  途中通道的意思,表述可能不对,可以理解为是一个运行的路程吧。

  为了保证总的返回值是0,所以只能走a,c通道(路程),由此可以计算出%ecx的值,只要在这几次计算中有一次num_0(即输入的第一个数)等于%ecx的值,就可以正确返回0了。

  所以最终的答案为 "7 0","3 0","1 0","0 0"。

  到这里,就结束了。

时间: 2024-10-13 16:09:03

CSAPP 3e: Bomb lab (phase_4)的相关文章

CSAPP 3e: Bomb lab (phase_1)

这一个lab拖了好久才开始慢慢完成,花的时间比较多,我也是没想到会需要这么多时间来折腾.考虑到如果把所有关卡的内容都一次发出来,太长了.所以分开操作吧. 然后,有一点是,在开始解题前的确该好好认识一下GDB,因为要使用这个工具.虽然我也感觉有些东西是可以等需要的时候再查的,但是后来找到了一篇介绍gdb命令的,写的比较详细,就下载了打印出来,占用了几节课的时间好好看了一下,就感觉特别有用,比之前更加熟悉了GDB.大概是在网页上看的时候比较急躁,所以吸收不好吧23333.还有,在解题过程中参考了不少

CSAPP 3e: Bomb lab (phase_2) + lab中的GDB 使用

这里是第二关,在这里分享一些在解题过程中用到的GDB功能. 首先,要进行断点,比如,在第二关中,断点操作有: 81: input = read_line(); 82: phase_2(input); 83: phase_defused(); break 81; break 82; break 83; 分别在read_line,phase_2,phase_defused,三个函数入口进行了断点. 另外,还有一个地方需要断点,那就是explode_bomb:操作:break explode_bomb

CSAPP 3e: Bomb lab (secret_phase)

这是秘密关卡,需要通过主动调用secret_phase函数才能触发,可以通过call secret 或者jump *0x地址来调用. 贴出函数:(fun7函数部分没有注释,后边续上了手写的图来解析这个函数了) 0000000000401204 <fun7>: 401204: 48 83 ec 08 sub $0x8,%rsp 401208: 48 85 ff test %rdi,%rdi 40120b: 74 2b je 401238 <fun7+0x34>;如果%rdi==0,r

CSAPP 3e: Bomb lab (phase_6)

这一关很复杂,需要非常耐心.如果感觉容易在循环中绕晕,可以参考一下我最后附上的画图分析法2333,小把戏,不过挺有用的. 先看函数phase_6: 00000000004010f4 <phase_6>: 4010f4: 41 56 push %r14 4010f6: 41 55 push %r13 4010f8: 41 54 push %r12 4010fa: 55 push %rbp 4010fb: 53 push %rbx 4010fc: 48 83 ec 50 sub $0x50,%rs

CSAPP 3e: Bomb lab (phase_5)

调出phase_5函数: 0000000000401062 <phase_5>: 401062: 53 push %rbx 401063: 48 83 ec 20 sub $0x20,%rsp 401067: 48 89 fb mov %rdi,%rbx 40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax ;此处搞不懂 401071: 00 00 401073: 48 89 44 24 18 mov %rax,0x18(%rsp) 401078: 31

CSAPP 3e : Data lab

/* * CS:APP Data Lab * * <Please put your name and userid here> * * bits.c - Source file with your solutions to the Lab. * This is the file you will hand in to your instructor. * * WARNING: Do not include the <stdio.h> header; it confuses the

CSAPP Bomb Lab记录

记录关于CSAPP 二进制炸弹实验过程 (CSAPP配套教学网站Bomb Lab自学版本,实验地址:http://csapp.cs.cmu.edu/2e/labs.html) (个人体验:对x86汇编寻址模式要有清晰的了解,如mov指令涉及的是计算出的地址所指向的存储单元的值,而lea指令保留的是计算出来的地址,数字是否加$表示常数的问题等: 实验中涉及的跳表的存储方式.链表的处理等是C语言的汇编语言实现方式,处理起来较为复杂,但可对这些方式的对象底层实现方式有一个较为清晰的了解: 涉及指针操作

深入理解计算机系统 (CS:APP) Lab2 - Bomb Lab 解析

原文地址:https://billc.io/2019/04/csapp-bomblab/ 写在前面 CS:APP是这学期的一门硬核课程,应该是目前接触到最底层的课程了.学校的教学也是尝试着尽量和CMU同步,课件和习题都直接照搬原版.包括现在着手的第二个实验室Bomb Lab.这个lab很有意思,没有提供全部c语言代码,需要手动根据反汇编语言推测在每一个阶段需要输入的内容,输入正确就可以进入下一个阶段. 理论上每个人获取到的lab都是不一样的,但对于自学学生而言在官网http://csapp.cs

CSAPP Lab:Bomb Lab(从拆弹到爆炸。。。

这个实验的要做的是用gdb逆向一段code,通过查看汇编代码以及单步调试找出这段code需要你填入的字符串,好像每个人都不一样,所以每个人都需要找到自己的拆弹密码,很有意思. 实验一共有6关,我们一关关来看一下: phase_1 打开bomb.c看些c源码(这里的核心方法已经被删除了,只能看到最外层的代码,但能得到一些线索). 很容易就发现这个phase_1方法是第一题的核心方法,直接逆向它,看下它的汇编. 第一句话是在为函数栈开辟空间,第二句话是关键,讲一个立即数赋值给%esi,然后就调用st