CSAPP BombLab Solution (基于IDA pro) (差4、5、6 隐藏)

时间:2020-11-24 18:09:56

前言

CSAPP对我个人的影响很大所以想自己写一份相关lab的答案,以供交流讨论。

概念辨析

lea dest [from]  //把from的地址赋给dest
mov dest from    //把from的值赋给dest
mov dest [from]  //把from指向的地址的值赋给dest
jz               //jump if zero(zero 指 zero flag 所以jz可以理解为相等时跳转)
ds               //数据开始的段地址 

phase_1 answer: Border relations with Canada have never been better.

public phase_1
phase_1 proc near
; __unwind {
sub     rsp, 8
mov     esi, offset aBorderRelation ; "Border relations with Canada have never"...
call    strings_not_equal
test    eax, eax
jz      short loc_400EF7

call explode_bomb
栈指针减8,开辟空间,esi为第二个接收函数第二个参数,调用strings_not_equal,推测第一个存储在rdi的参数为string 。当相同的时候跳转到 loc_400EF7 。否则就引爆炸弹。

loc_400EF7:
add     rsp, 8
retn
; } // starts at 400EE0
phase_1 endp

栈指针加8恢复之前的状态函数结束。
查看 内存中字符串的值:
Border relations with Canada have never been better.
输入即可

phase_2 answer: 1 2 4 8 16 32

public phase_2
phase_2 proc near

var_38= dword ptr -38h
var_34= byte ptr -34h
var_20= byte ptr -20h

; __unwind {
push    rbp
push    rbx
sub     rsp, 28h
mov     rsi, rsp
call    read_six_numbers
cmp     [rsp 38h var_38], 1
jz      short loc_400F30

栈指针减 40,开辟空间,将rsp中值放到rsi中。调用函数read_six_numbers,比较[rsp 38h var_38] ( a[0] )的值和1,如果相等就跳转到loc_400F30,否则引爆炸弹。

loc_400F30:
lea     rbx, [rsp 38h var_34]
lea     rbp, [rsp 38h var_20]
jmp     short loc_400F17

将[rsp 38h var_34] (a[1])中的地址放入rbx ,[rsp 38h var_20] (尾部)中的地址放入rbp。跳转到loc_400F17。

loc_400F17:
mov     eax, [rbx-4]
add     eax, eax
cmp     [rbx], eax
jz      short loc_400F25

将[rbx-4] (a[0])地址的值放到eax中 ,将eax的值加倍,后比较a[1]和2*a[0]的值如果相等跳转到loc_400F25,不相等就引爆炸弹。

loc_400F25:
add     rbx, 4
cmp     rbx, rbp
jnz     short loc_400F17

把rbx(a[1])中的地址值加4得到a[2],比较rbx与rbp的值如果不相等就跳回loc_400F17(do while 循环 每次比较 2*a[i]==a[i 1]),所以最终输入的数字应该为1,2,4,8,16,32。

read_six_numbers

public read_six_numbers
read_six_numbers proc near

var_18= qword ptr -18h
var_10= qword ptr -10h

; __unwind {
sub     rsp, 18h
mov     rdx, rsi
lea     rcx, [sri 4]
lea     rax, [rsi 14h]
mov     [rsp 18h var_10], rax
lea     rax, [rsi 10h]
mov     [rsp 18h var_18], rax
lea     r9, [rsi 0Ch]
lea     r8, [rsi 8]
mov     esi, offset unk_4025C3
mov     eax, 0
call    ___isoc99_sscanf
cmp     eax, 5
jg      short loc_401499

栈指针减24,又由函数名,推测为6个int。 分别存放在 (值:)rsi(rsi中为rsp中的值即为函数调用前栈底的地址),(地址:)[rsi 4],[rsi 8],[rsi 0Ch],[rsi 10h] ,[rsi 14h],又将上述内容(或地址)移动到rdx,rcx,r8,r9,rax,[rsp 18h var_18],[rsp 18h var_10],offset unk_4025C3 中内容为 %d %d %d %d %d %d,保存在rsi中,后调用___isoc99_sscanf函数(查看函数原型)之后比较eax中的值(读入int的个数)和5,如果大于就跳转到 short loc_401499,小于等于就引爆炸弹。为了下面叙述方便直接记各个寄存器的值分别为a[0],a[1],a[2],a[3],a[4],a[5]。

call explode_bomb

loc_401499:
add     rsp, 18h
retn
; } // starts at 40145C
read_six_numbers endp

结束读入。

phase_3 answer:(输入一组即可) 0 207 或 1 311 或 2 707 或 3 256 或 4 389 或 5 206 或 6 682 或 7 327

public phase_3
phase_3 proc near

var_10= dword ptr -10h
var_C= dword ptr -0Ch

; __unwind {
sub     rsp, 18h
lea     rcx, [rsp 18h var_C]
lea     rdx, [rsp 18h var_10]
mov     esi, offset aDD ; "%d %d"
mov     eax, 0
call    ___isoc99_sscanf
cmp     eax, 1
jg      short loc_400F6A

栈指针减24,开辟空间,将[rsp 18h var_C]的地址赋给rcx,将[rsp 18h var_10]的地址赋给rdx,将offset 中值赋给 esi,和前面相同是调用___isoc99_sscanf读入整数,查看内存可以看到"%d %d"读入两个,如果eax的值大于1就跳转(即输入两个整数),否则引爆炸弹。为了叙述方便记 [rsp 18h var_10]地址处存放的值为first,[rsp 18h var_C]为second。

loc_400F6A:             ; switch 8 cases
cmp     [rsp 18h var_10], 7
ja      short def_400F75 ; jumptable 0000000000400F75 default case

如果first大于7就引爆炸弹,所以first<=7。

mov     eax, [rsp 18h var_10]
jmp     ds:jpt_400F75[rax*8] ; switch jump

将second的值放到eax跳转到jpt_400F75对应的地址加8*first(switch语句)下面列出各种情况:

loc_400F7C:             ; jumptable 0000000000400F75 case 0
mov     eax, 0CFh
jmp     short loc_400FBE

loc_400FB9:             ; jumptable 0000000000400F75 case 1
mov     eax, 137h

loc_400F83:             ; jumptable 0000000000400F75 case 2
mov     eax, 2C3h
jmp     short loc_400FBE

loc_400F8A:             ; jumptable 0000000000400F75 case 3
mov     eax, 100h
jmp     short loc_400FBE

loc_400F91:             ; jumptable 0000000000400F75 case 4
mov     eax, 185h
jmp     short loc_400FBE

loc_400F98:             ; jumptable 0000000000400F75 case 5
mov     eax, 0CEh
jmp     short loc_400FBE

loc_400F9F:             ; jumptable 0000000000400F75 case 6
mov     eax, 2AAh
jmp     short loc_400FBE

loc_400FA6:             ; jumptable 0000000000400F75 case 7
mov     eax, 147h
jmp     short loc_400FBE

mov     eax, 0
jmp     short loc_400FBE
loc_400FBE:
cmp     eax, [rsp 18h var_C]
jz      short loc_400FC9

跳转到loc_400FBE比较eax和second,如果相等就跳转到loc_400FC9,否则引爆炸弹。

loc_400FC9:
add     rsp, 18h
retn
; } // starts at 400F43
phase_3 endp

函数结束。