CSAPP的boom_lab实验

逆向工程循环

  • 理解汇编与源代码之间的关系,关键是找到程序值和寄存器之间的映射关系。
  • 在循环之前如何初始化寄存器,在循环中如何更新和测试寄存器,在循环后如何使用寄存器。

bomb_lab


csapp的炸弹实验中一共有6个炸弹。之前的记录太乱了,有时间再整理。

1

sscanf返回从给定字符串成功按照格式读取的值的个数

2

  401480:       be c3 25 40 00          mov    $0x4025c3,%esi
  401485:       b8 00 00 00 00          mov    $0x0,%eax
  40148a:       e8 61 f7 ff ff          callq  400bf0 <__isoc99_sscanf@plt>

在<read_six_numbers>里有上面这段汇编代码,在gdb里打断点,print *0x4025c3,地址里面的值是"%d %d %d %d %d %d"是传入sscanf的参数,说明用sscanf从char *input里读取六个整数

  400f05:       e8 52 05 00 00          callq  40145c <read_six_numbers>
  400f0a:       83 3c 24 01             cmpl   $0x1,(%rsp)
  400f0e:       74 20                   je     400f30 <phase_2+0x34>

%rsp存储第一个数字的地址,%rsp+4,%rsp+8…存储另外五个数字(int型变量四个字节),0x400f0a比较第一个数字和1,第一个数字不是1则爆炸。

  400f1c:       39 03                   cmp    %eax,(%rbx)
  400f1e:       74 05                   je     400f25 <phase_2+0x29>
  400f20:       e8 15 05 00 00          callq  40143a <explode_bomb>

比较%eax和(%rbx)的值,%eax寄存器中是密码

3

  400f51:       be cf 25 40 00          mov    $0x4025cf,%esi
  400f56:       b8 00 00 00 00          mov    $0x0,%eax
  400f5b:       e8 90 fc ff ff          callq  400bf0 <__isoc99_sscanf@plt>

在sscanf之前打断点,输出地址0x4025cf的值为"%d %d",说明用sscanf从char *input里读取两个整数

  400f6a:       83 7c 24 08 07          cmpl   $0x7,0x8(%rsp)
  400f6f:       77 3c                   ja     400fad <phase_3+0x6a>

如果第一个整型大于7,会跳转到爆炸

  400f71:       8b 44 24 08             mov    0x8(%rsp),%eax
  400f75:       ff 24 c5 70 24 40 00    jmpq   *0x402470(,%rax,8)

这里把第一个整型mov到%eax(即%rax),下一步跳转到0x402470 + %rax * 8里的地址,即跳转到第一个整数*8加上0x402470的地址
如果%rax是0,跳转到400f7c,%eax = 207
如果%rax是1,跳转到400fb9,%eax = 311
如果%rax是2,跳转到400f83,%eax = 707
如果%rax是3,挑战到400f8a,%eax = 256
如果%rax是4,挑战到400f91,%eax = 389
如果%rax是5,挑战到400f98,%eax = 206
如果%rax是6,跳转到400f9f,%eax = 682
如果%rax是7,跳转到400fa6,%eax = 327

400fbe:       3b 44 24 0c             cmp    0xc(%rsp),%eax
400fc2:       74 05                   je     400fc9 <phase_3+0x86>
400fc4:       e8 71 04 00 00          callq  40143a <explode_bomb>

下一步跳转到0x400fbe,比较第二个整型和%eax的值,如果相等则跳转,否则爆炸

fb2没有跳转

  400fb2:       b8 00 00 00 00          mov    $0x0,%eax
  400fb7:       eb 05                   jmp    400fbe <phase_3+0x7b>

如果%rax == -1,则跳转到0x400fb2

phase_4

  40101a:       be cf 25 40 00          mov    $0x4025cf,%esi
  40101f:       b8 00 00 00 00          mov    $0x0,%eax
  401024:       e8 c7 fb ff ff          callq  400bf0 <__isoc99_sscanf@plt>

在sscanf之前打断点,输出地址0x4025cf的值为"%d %d",说明用sscanf从char *input里读取两个整数

000000000040100c <phase_4>:
  40100c:       48 83 ec 18             sub    $0x18,%rsp
  401010:       48 8d 4c 24 0c          lea    0xc(%rsp),%rcx
  401015:       48 8d 54 24 08          lea    0x8(%rsp),%rdx
  40101a:       be cf 25 40 00          mov    $0x4025cf,%esi
  40101f:       b8 00 00 00 00          mov    $0x0,%eax
  401024:       e8 c7 fb ff ff          callq  400bf0 <__isoc99_sscanf@plt>
  401029:       83 f8 02                cmp    $0x2,%eax
  40102c:       75 07                   jne    401035 <phase_4+0x29>
  40102e:       83 7c 24 08 0e          cmpl   $0xe,0x8(%rsp)
  401033:       76 05                   jbe    40103a <phase_4+0x2e>
  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
  401048:       e8 81 ff ff ff          callq  400fce <func4>
  40104d:       85 c0                   test   %eax,%eax
  40104f:       75 07                   jne    401058 <phase_4+0x4c>
  401051:       83 7c 24 0c 00          cmpl   $0x0,0xc(%rsp)
  401056:       74 05                   je     40105d <phase_4+0x51>
  401058:       e8 dd 03 00 00          callq  40143a <explode_bomb>
  40105d:       48 83 c4 18             add    $0x18,%rsp
  401061:       c3                      retq

void phase_4( char * input ) {
int num1, num2 ;
if( (sscanf( input , “%d %d”, num1, num2 ) != 2 ) || num1 > 14 )
explode_bomb();
else {
int eax = func4( num1, 0, 14 );
if( eax != 0 || num2 != 0) //如果返回值不为零,或num2不为零,则爆炸
explode_bomb();
return 0;
}
}

%edi %esi %edx
第一个整型 0 14

0000000000400fce <func4>:
  400fce:       48 83 ec 08             sub    $0x8,%rsp
  400fd2:       89 d0                   mov    %edx,%eax	%eax = %edx
  400fd4:       29 f0                   sub    %esi,%eax	%eax = %edx - %esi
  400fd6:       89 c1                   mov    %eax,%ecx	%ecx = %eax = %edx - %esi
  400fd8:       c1 e9 1f                shr    $0x1f,%ecx	%ecx = (%edx - %esi) >> 31
  400fdb:       01 c8                   add    %ecx,%eax	%eax = (%edx - %esi) +%ecx
  400fdd:       d1 f8                   sar    %eax			%eax = ( (%edx - %esi) + %ecx ) / 2
  400fdf:       8d 0c 30                lea    (%rax,%rsi,1),%ecx	%ecx = 
  400fe2:       39 f9                   cmp    %edi,%ecx
  400fe4:       7e 0c                   jle    400ff2 <func4+0x24>
  400fe6:       8d 51 ff                lea    -0x1(%rcx),%edx
  400fe9:       e8 e0 ff ff ff          callq  400fce <func4>
  400fee:       01 c0                   add    %eax,%eax
  400ff0:       eb 15                   jmp    401007 <func4+0x39>
  400ff2:       b8 00 00 00 00          mov    $0x0,%eax
  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>
  401003:       8d 44 00 01             lea    0x1(%rax,%rax,1),%eax
  401007:       48 83 c4 08             add    $0x8,%rsp
  40100b:       c3                      retq

int func4( int num1, int min, int max) {
int ret;//返回值
int ecx = 0;
if( max < min )
ret = ( max - min + 1 ) / 2;
else
ret = ( max - min ) / 2;
ecx = ret + min * 1; //第一次调用fun4,ret = ecx = 7
if( ecx <= num1) {
ret = 0;
if( ecx >= num1 )
return ret; //第一次调用fun4,如果num1 = 7,return 0,不会爆炸
else {
min = ecx + 1;
func4( num1, min, max); //第一次调用fun4,如果num1 < 7,调用func4( num1, 8, 14)
}
}
else { //第一次调用fun4,如果num1 > 7,调用func4( num1, 0, 6)
max = ecx -1;
func4( num1, min, max );
}
}

phase_5

  40107a:       e8 9c 02 00 00          callq  40131b <string_length>
  40107f:       83 f8 06                cmp    $0x6,%eax
  401082:       74 4e                   je     4010d2 <phase_5+0x70>
  401084:       e8 b1 03 00 00          callq  40143a <explode_bomb>

字符串长度不为6则爆炸

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 c0                   xor    %eax,%eax
  40107a:       e8 9c 02 00 00          callq  40131b <string_length>
  40107f:       83 f8 06                cmp    $0x6,%eax
  401082:       74 4e                   je     4010d2 <phase_5+0x70>
  401084:       e8 b1 03 00 00          callq  40143a <explode_bomb>
  401089:       eb 47                   jmp    4010d2 <phase_5+0x70>
  40108b:       0f b6 0c 03             movzbl (%rbx,%rax,1),%ecx
  40108f:       88 0c 24                mov    %cl,(%rsp)
  401092:       48 8b 14 24             mov    (%rsp),%rdx			第一次运行到这里时,print $rdx不是第一个字符的ascii码,%rdx的%dl才是,因为%rdx原本有值
  401096:       83 e2 0f                and    $0xf,%edx			取最低四位,
  401099:       0f b6 92 b0 24 40 00    movzbl 0x4024b0(%rdx),%edx
  4010a0:       88 54 04 10             mov    %dl,0x10(%rsp,%rax,1)
  4010a4:       48 83 c0 01             add    $0x1,%rax
  4010a8:       48 83 f8 06             cmp    $0x6,%rax
  4010ac:       75 dd                   jne    40108b <phase_5+0x29>
  4010ae:       c6 44 24 16 00          movb   $0x0,0x16(%rsp)
  4010b3:       be 5e 24 40 00          mov    $0x40245e,%esi
  4010b8:       48 8d 7c 24 10          lea    0x10(%rsp),%rdi
  4010bd:       e8 76 02 00 00          callq  401338 <strings_not_equal>
  4010c2:       85 c0                   test   %eax,%eax
  4010c4:       74 13                   je     4010d9 <phase_5+0x77>
  4010c6:       e8 6f 03 00 00          callq  40143a <explode_bomb>
  4010cb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
  4010d0:       eb 07                   jmp    4010d9 <phase_5+0x77>
  4010d2:       b8 00 00 00 00          mov    $0x0,%eax
  4010d7:       eb b2                   jmp    40108b <phase_5+0x29>
  4010d9:       48 8b 44 24 18          mov    0x18(%rsp),%rax
  4010de:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax
  4010e5:       00 00 
  4010e7:       74 05                   je     4010ee <phase_5+0x8c>
  4010e9:       e8 42 fa ff ff          callq  400b30 <__stack_chk_fail@plt>
  4010ee:       48 83 c4 20             add    $0x20,%rsp
  4010f2:       5b                      pop    %rbx
  4010f3:       c3                      retq

void phase_5(char *input) {
int ret;
if( string_length( input ) != 6)
explode_bomb();
else {
ret = 0;

}

}

  40108b:       0f b6 0c 03             movzbl (%rbx,%rax,1),%ecx
  40108f:       88 0c 24                mov    %cl,(%rsp)
  401092:       48 8b 14 24             mov    (%rsp),%rdx			第一次运行到这里时,print $rdx不是第一个字符的ascii码,%rdx的%dl才是,因为%rdx原本有值
  401096:       83 e2 0f                and    $0xf,%edx			取最低四位,其他位置零
  401099:       0f b6 92 b0 24 40 00    movzbl 0x4024b0(%rdx),%edx	%edx = (10000000010010010110000 + 每个字符的ascii码最低四位),再取零扩展
  4010a0:       88 54 04 10             mov    %dl,0x10(%rsp,%rax,1) 
  4010a4:       48 83 c0 01             add    $0x1,%rax
  4010a8:       48 83 f8 06             cmp    $0x6,%rax
  4010ac:       75 dd                   jne    40108b <phase_5+0x29>
  4010b3:       be 5e 24 40 00          mov    $0x40245e,%esi
  4010b8:       48 8d 7c 24 10          lea    0x10(%rsp),%rdi
  4010bd:       e8 76 02 00 00          callq  401338 <strings_not_equal>

地址0x4024b0的值:“maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?”
根据%rdx,即每个字符的ascii码最低四位的值,决定%edx的值
%rsp+0x10地址存储根据输入的六个字符判断得到的字符串
0x40245e地址存储的字符串是flyers
根据得到的字符串和flyers比较

逆推,应该输入ionefg

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,%rsp
  401100:       49 89 e5                mov    %rsp,%r13
  401103:       48 89 e6                mov    %rsp,%rsi
  401106:       e8 51 03 00 00          callq  40145c <read_six_numbers>	读入六个数字,地址存储在%rsp
  40110b:       49 89 e6                mov    %rsp,%r14
  40110e:       41 bc 00 00 00 00       mov    $0x0,%r12d
  401114:       4c 89 ed                mov    %r13,%rbp
  401117:       41 8b 45 00             mov    0x0(%r13),%eax			%r13存储正在判断的数字,并传入%eax
  40111b:       83 e8 01                sub    $0x1,%eax
  40111e:       83 f8 05                cmp    $0x5,%eax
  401121:       76 05                   jbe    401128 <phase_6+0x34>	
  401123:       e8 12 03 00 00          callq  40143a <explode_bomb>
  401128:       41 83 c4 01             add    $0x1,%r12d
  40112c:       41 83 fc 06             cmp    $0x6,%r12d
  401130:       74 21                   je     401153 <phase_6+0x5f>	
  401132:       44 89 e3                mov    %r12d,%ebx							
  401135:       48 63 c3                movslq %ebx,%rax				
  401138:       8b 04 84                mov    (%rsp,%rax,4),%eax
  40113b:       39 45 00                cmp    %eax,0x0(%rbp)			
  40113e:       75 05                   jne    401145 <phase_6+0x51>	
  401140:       e8 f5 02 00 00          callq  40143a <explode_bomb>
  401145:       83 c3 01                add    $0x1,%ebx
  401148:       83 fb 05                cmp    $0x5,%ebx
  40114b:       7e e8                   jle    401135 <phase_6+0x41>	
  40114d:       49 83 c5 04             add    $0x4,%r13							
  401151:       eb c1                   jmp    401114 <phase_6+0x20>  //前面这段汇编判断:每个数字要<7,且各不相等
  401153:       48 8d 74 24 18          lea    0x18(%rsp),%rsi        
  401158:       4c 89 f0                mov    %r14,%rax
  40115b:       b9 07 00 00 00          mov    $0x7,%ecx
  401160:       89 ca                   mov    %ecx,%edx
  401162:       2b 10                   sub    (%rax),%edx
  401164:       89 10                   mov    %edx,(%rax)
  401166:       48 83 c0 04             add    $0x4,%rax
  40116a:       48 39 f0                cmp    %rsi,%rax
  40116d:       75 f1                   jne    401160 <phase_6+0x6c>  //这段汇编把每个数变成:7 - num
  40116f:       be 00 00 00 00          mov    $0x0,%esi
  401174:       eb 21                   jmp    401197 <phase_6+0xa3>
    401176:       48 8b 52 08             mov    0x8(%rdx),%rdx
  40117a:       83 c0 01                add    $0x1,%eax
  40117d:       39 c8                   cmp    %ecx,%eax
  40117f:       75 f5                   jne    401176 <phase_6+0x82>
  401181:       eb 05                   jmp    401188 <phase_6+0x94>
    401183:       ba d0 32 60 00          mov    $0x6032d0,%edx
  401188:       48 89 54 74 20          mov    %rdx,0x20(%rsp,%rsi,2)
  40118d:       48 83 c6 04             add    $0x4,%rsi
  401191:       48 83 fe 18             cmp    $0x18,%rsi
  401195:       74 14                   je     4011ab <phase_6+0xb7>
  401197:       8b 0c 34                mov    (%rsp,%rsi,1),%ecx
  40119a:       83 f9 01                cmp    $0x1,%ecx
  40119d:       7e e4                   jle    401183 <phase_6+0x8f>
  40119f:       b8 01 00 00 00          mov    $0x1,%eax
  4011a4:       ba d0 32 60 00          mov    $0x6032d0,%edx
  4011a9:       eb cb                   jmp    401176 <phase_6+0x82>
  4011ab:       48 8b 5c 24 20          mov    0x20(%rsp),%rbx
  4011b0:       48 8d 44 24 28          lea    0x28(%rsp),%rax
  4011b5:       48 8d 74 24 50          lea    0x50(%rsp),%rsi
  4011ba:       48 89 d9                mov    %rbx,%rcx
    4011bd:       48 8b 10                mov    (%rax),%rdx
  4011c0:       48 89 51 08             mov    %rdx,0x8(%rcx)
  4011c4:       48 83 c0 08             add    $0x8,%rax
  4011c8:       48 39 f0                cmp    %rsi,%rax
  4011cb:       74 05                   je     4011d2 <phase_6+0xde>
  4011cd:       48 89 d1                mov    %rdx,%rcx
  4011d0:       eb eb                   jmp    4011bd <phase_6+0xc9>
  4011d2:       48 c7 42 08 00 00 00    movq   $0x0,0x8(%rdx)
  4011d9:       00 
  4011da:       bd 05 00 00 00          mov    $0x5,%ebp
    4011df:       48 8b 43 08             mov    0x8(%rbx),%rax
  4011e3:       8b 00                   mov    (%rax),%eax
  4011e5:       39 03                   cmp    %eax,(%rbx)
  4011e7:       7d 05                   jge    4011ee <phase_6+0xfa>
  4011e9:       e8 4c 02 00 00          callq  40143a <explode_bomb>
  4011ee:       48 8b 5b 08             mov    0x8(%rbx),%rbx
  4011f2:       83 ed 01                sub    $0x1,%ebp
  4011f5:       75 e8                   jne    4011df <phase_6+0xeb>
  4011f7:       48 83 c4 50             add    $0x50,%rsp
  4011fb:       5b                      pop    %rbx
  4011fc:       5d                      pop    %rbp
  4011fd:       41 5c                   pop    %r12
  4011ff:       41 5d                   pop    %r13
  401201:       41 5e                   pop    %r14
  401203:       c3                      retq

猜你喜欢

转载自blog.csdn.net/lqysgdb/article/details/112966424
今日推荐