首页
社区
课程
招聘
[原创]CSAPP-bomblab-writeup
发表于: 2022-3-21 12:15 9698

[原创]CSAPP-bomblab-writeup

2022-3-21 12:15
9698

Bomb这个程序是《深入理解计算机系统》的配套实验的一部分,一共6关。

原地址:

环境:

第一关热身题,输入一段明文保存的字符串:

key: Border relations with Canada have never been better.

要求输入6个数:

输入的6个数字会存在数组里,临时取名input。接下来rbx执行input[1],rbp指向input[6](用来结束循环):

input[i]input[i-1] * 2比较,相等即可,所以输入一个等比数列即可。

key: 1 2 4 8 16 32

输入两个数 num1, num2

有一个长度为8的跳转表,所以会检查num1<=7, 之后跳转到jpt_400F75[num1], 每个case都有一个数,与num2相等则通过

比如下面这个num1==0的case:

所以输入 0 207(0xcf==207) 即可,其它7个case也可以,所以应该是有8对数作为flag。

还是输入两个数num1 num2, 要求num1 <= 0xe

然后调用一个func4(0xe, 0, num1), 要求返回0,并且num2也需要为0:

分析一下func4函数,这是一个递归函数:

用c还原:

调试一下,执行到if时nEcx是7,所以key为 7 0

输入一段字符串,要求长度为6

然后根据输入的字符串,映射为另一个字符串。

映射的逻辑是,每个输入的字符的低4位,作为0x4024B0处字符串表(如下)的偏移。比如输入小写a(0x61),偏移就是0x61 & 0x0f == 0x01,映射为4024B1处的0x61。

我们的目标就是找到flyers这几个字母在以下字符串中的偏移,可以用python来解:

第6关,还是输入6个数字,紧接着是一个双重循环,要求每一个数字不能大于5,并且互不重复:

之后,将每个数字与7做差,比如,输入1,2,3,4,5,6,现在变为6,5,4,3,2,1:

loc_401197部分开始稍微复杂:

先注意到有个全局变量node1, 在IDA的符号窗口可以看到,一共有6个节点:

数据窗口看一下,原来是一个链表(如果没有node符号,对这种指针数据应该敏感一点):

结构还原:

识别出数据结构就稍微容易点了。比如现在输入的数组已经变成6,5,4,3,2,1, 那么下面的逻辑会依次把第6,5,4,3,2,1个链表节点的地址存到局部数组里:

执行完后的栈空间(arrLinkListNodes):

继续跟到4011ab处的逻辑,这里会根据局部数组,改变节点的next,重新排列链表:

局部数组是6,5,4,3,2,1,所以链表就被逆过来了,并且node1.next被置为NULL。

最后看关键的判断炸弹是否爆炸的逻辑。4011DF这里会按照重新排列好的链表顺序,判断它们的n2成员是否从大到小排列,不是则爆炸。

让我们再回看一下数据窗口的链表:

它们的n2依次为14c, a8, 39c, 2b3, 1dd, 1bb, 写个脚本排列一下:

key : 4 3 2 1 6 5

 
 
.text:0000000000400EE4 mov     esi, offset aBorderRelation     ; "Border relations with Canada have never"...
.text:0000000000400EE9 call    strings_not_equal
.text:0000000000400EEE test    eax, eax
.text:0000000000400EF0 jz      short loc_400EF7
.text:0000000000400EF2 call    explode_bomb
.text:0000000000400EE4 mov     esi, offset aBorderRelation     ; "Border relations with Canada have never"...
.text:0000000000400EE9 call    strings_not_equal
.text:0000000000400EEE test    eax, eax
.text:0000000000400EF0 jz      short loc_400EF7
.text:0000000000400EF2 call    explode_bomb
.text:000000000040145C public read_six_numbers
.text:000000000040145C read_six_numbers proc near
...
.text:0000000000401480 mov     esi, offset aDDDDDD             ; "%d %d %d %d %d %d"
.text:0000000000401485 mov     eax, 0
.text:000000000040148A call    ___isoc99_sscanf
.text:000000000040145C public read_six_numbers
.text:000000000040145C read_six_numbers proc near
...
.text:0000000000401480 mov     esi, offset aDDDDDD             ; "%d %d %d %d %d %d"
.text:0000000000401485 mov     eax, 0
.text:000000000040148A call    ___isoc99_sscanf
.text:0000000000400F30 loc_400F30:                            
.text:0000000000400F30                                         ; phase_2+19↑j
.text:0000000000400F30 lea     rbx, [rsp+38h+var_34]           ; rbx = pNum = &input[1]
.text:0000000000400F35 lea     rbp, [rsp+38h+var_20]           ; rbp = &input[6] = pEnd
.text:0000000000400F3A jmp     short loopCompare
.text:0000000000400F30 loc_400F30:                            
.text:0000000000400F30                                         ; phase_2+19↑j
.text:0000000000400F30 lea     rbx, [rsp+38h+var_34]           ; rbx = pNum = &input[1]
.text:0000000000400F35 lea     rbp, [rsp+38h+var_20]           ; rbp = &input[6] = pEnd
.text:0000000000400F3A jmp     short loopCompare
.text:0000000000400F17 loopCompare:                           
.text:0000000000400F17                                         ; phase_2+3E↓j
.text:0000000000400F17 mov     eax, [rbx-4]                    ; eax = *(--pNum)
.text:0000000000400F1A add     eax, eax                        ; eax *= 2
.text:0000000000400F1C cmp     [rbx], eax
.text:0000000000400F1E jz      short loc_400F25                ; if *pNum == 2*eax   continue
.text:0000000000400F20 call    explode_bomb
.text:0000000000400F25 ; ---------------------------------------------------------------------------
.text:0000000000400F25
.text:0000000000400F25 loc_400F25:                            
.text:0000000000400F25 add     rbx, 4
.text:0000000000400F29 cmp     rbx, rbp                        ; if i == len(inputbreak
.text:0000000000400F2C jnz     short loopCompare               ; eax = *(--pNum)
.text:0000000000400F2E jmp     short loc_400F3C
.text:0000000000400F17 loopCompare:                           
.text:0000000000400F17                                         ; phase_2+3E↓j
.text:0000000000400F17 mov     eax, [rbx-4]                    ; eax = *(--pNum)
.text:0000000000400F1A add     eax, eax                        ; eax *= 2
.text:0000000000400F1C cmp     [rbx], eax
.text:0000000000400F1E jz      short loc_400F25                ; if *pNum == 2*eax   continue
.text:0000000000400F20 call    explode_bomb
.text:0000000000400F25 ; ---------------------------------------------------------------------------
.text:0000000000400F25
.text:0000000000400F25 loc_400F25:                            
.text:0000000000400F25 add     rbx, 4
.text:0000000000400F29 cmp     rbx, rbp                        ; if i == len(inputbreak
.text:0000000000400F2C jnz     short loopCompare               ; eax = *(--pNum)
.text:0000000000400F2E jmp     short loc_400F3C
.text:0000000000400F51 mov     esi, (offset aDDDDDD+0Ch)       ; "%d %d"
.text:0000000000400F56 mov     eax, 0
.text:0000000000400F5B call    ___isoc99_sscanf
.text:0000000000400F51 mov     esi, (offset aDDDDDD+0Ch)       ; "%d %d"
.text:0000000000400F56 mov     eax, 0
.text:0000000000400F5B call    ___isoc99_sscanf
.text:0000000000400F6A loc_400F6A:                            
.text:0000000000400F6A cmp     [rsp+18h+var_10], 7             ; switch 8 cases
.text:0000000000400F6F ja      short def_400F75                ; jumptable 0000000000400F75 default case
.text:0000000000400F71 mov     eax, [rsp+18h+var_10]
.text:0000000000400F75 jmp     ds:jpt_400F75[rax*8]            ; switch jump
.text:0000000000400F6A loc_400F6A:                            
.text:0000000000400F6A cmp     [rsp+18h+var_10], 7             ; switch 8 cases
.text:0000000000400F6F ja      short def_400F75                ; jumptable 0000000000400F75 default case
.text:0000000000400F71 mov     eax, [rsp+18h+var_10]
.text:0000000000400F75 jmp     ds:jpt_400F75[rax*8]            ; switch jump
.text:0000000000400F7C loc_400F7C:                            
.text:0000000000400F7C                                         ; DATA XREF: .rodata:jpt_400F75↓o
.text:0000000000400F7C mov     eax, 0CFh                       ; jumptable 0000000000400F75 case 0
.text:0000000000400F81 jmp     short loc_400FBE
.text:0000000000400F7C loc_400F7C:                            
.text:0000000000400F7C                                         ; DATA XREF: .rodata:jpt_400F75↓o
.text:0000000000400F7C mov     eax, 0CFh                       ; jumptable 0000000000400F75 case 0
.text:0000000000400F81 jmp     short loc_400FBE
.text:000000000040101A mov     esi, (offset aDDDDDD+0Ch)       ; "%d %d"
.text:000000000040101F mov     eax, 0
.text:0000000000401024 call    ___isoc99_sscanf
.text:0000000000401029 cmp     eax, 2
.text:000000000040102C jnz     short loc_401035
.text:000000000040102E cmp     [rsp+18h+var_10], 0Eh           ; num 1 <= 0xe
.text:0000000000401033 jbe     short loc_40103A
.text:0000000000401035
.text:0000000000401035 call    explode_bomb
.text:000000000040101A mov     esi, (offset aDDDDDD+0Ch)       ; "%d %d"
.text:000000000040101F mov     eax, 0
.text:0000000000401024 call    ___isoc99_sscanf
.text:0000000000401029 cmp     eax, 2
.text:000000000040102C jnz     short loc_401035
.text:000000000040102E cmp     [rsp+18h+var_10], 0Eh           ; num 1 <= 0xe
.text:0000000000401033 jbe     short loc_40103A
.text:0000000000401035
.text:0000000000401035 call    explode_bomb
.text:000000000040103A mov     edx, 0Eh
.text:000000000040103F mov     esi, 0
.text:0000000000401044 mov     edi, [rsp+18h+var_10]           ; edi = num1
.text:0000000000401048 call    func4
.text:000000000040104D test    eax, eax
.text:000000000040104F jnz     short loc_401058                ; if func4() != 0    bomb
.text:0000000000401051 cmp     [rsp+18h+var_C], 0              ; if num2!=0  bomb
.text:0000000000401056 jz      short loc_40105D
.text:000000000040103A mov     edx, 0Eh
.text:000000000040103F mov     esi, 0
.text:0000000000401044 mov     edi, [rsp+18h+var_10]           ; edi = num1
.text:0000000000401048 call    func4
.text:000000000040104D test    eax, eax
.text:000000000040104F jnz     short loc_401058                ; if func4() != 0    bomb
.text:0000000000401051 cmp     [rsp+18h+var_C], 0              ; if num2!=0  bomb
.text:0000000000401056 jz      short loc_40105D
.text:0000000000400FCE public func4
.text:0000000000400FCE                                         ; func4+30↓p ...
.text:0000000000400FCE ; __unwind {
.text:0000000000400FCE sub     rsp, 8
.text:0000000000400FD2 mov     eax, edx                        ; eax = edx(init 0xe)
.text:0000000000400FD4 sub     eax, esi                        ; eax =  edx(init 0xe) - esi(init 0)
.text:0000000000400FD6 mov     ecx, eax
.text:0000000000400FD8 shr     ecx, 1Fh                        ; ecx = eax >> 1F
.text:0000000000400FD8                                         ; highest bit --> 0
.text:0000000000400FDB add     eax, ecx                        ; eax += ecx
.text:0000000000400FDD sar     eax, 1                          ; eax = eax >> 1
.text:0000000000400FDD                                         ; highest bit --> 0
 
.text:0000000000400FDF lea     ecx, [rax+rsi]                  ; ecx = rax+rsi
.text:0000000000400FE2 cmp     ecx, edi                        ; if ecx > num1
.text:0000000000400FE4 jle     short loc_400FF2
.text:0000000000400FE6 lea     edx, [rcx-1]                    ;   func(rcx-1, esi)
.text:0000000000400FE9 call    func4
.text:0000000000400FEE add     eax, eax
.text:0000000000400FF0 jmp     short ret_func4
.text:0000000000400FF2 ; ---------------------------------------------------------------------------
.text:0000000000400FF2 loc_400FF2:                            
.text:0000000000400FF2 mov     eax, 0                          ; else {
.text:0000000000400FF7 cmp     ecx, edi                        ;   if ecx < num1 {
.text:0000000000400FF9 jge     short ret_func4                 ;       ret = func4(edx, rcx+1)
.text:0000000000400FF9                                         ;       return 2*ret + 1
.text:0000000000400FFB lea     esi, [rcx+1]                    ;    }
.text:0000000000400FFE call    func4
.text:0000000000401003 lea     eax, [rax+rax+1]                ;   else return eax}
.text:0000000000401003                                         ; }
.text:0000000000401007
.text:0000000000401007 ret_func4:                              ; CODE XREF: func4+22↑j
.text:0000000000401007                                         ; func4+2B↑j
.text:0000000000401007 add     rsp, 8
.text:000000000040100B retn
.text:000000000040100B ; } // starts at 400FCE
.text:000000000040100B func4 endp
.text:0000000000400FCE public func4
.text:0000000000400FCE                                         ; func4+30↓p ...
.text:0000000000400FCE ; __unwind {
.text:0000000000400FCE sub     rsp, 8
.text:0000000000400FD2 mov     eax, edx                        ; eax = edx(init 0xe)
.text:0000000000400FD4 sub     eax, esi                        ; eax =  edx(init 0xe) - esi(init 0)
.text:0000000000400FD6 mov     ecx, eax
.text:0000000000400FD8 shr     ecx, 1Fh                        ; ecx = eax >> 1F
.text:0000000000400FD8                                         ; highest bit --> 0
.text:0000000000400FDB add     eax, ecx                        ; eax += ecx
.text:0000000000400FDD sar     eax, 1                          ; eax = eax >> 1
.text:0000000000400FDD                                         ; highest bit --> 0
 
.text:0000000000400FDF lea     ecx, [rax+rsi]                  ; ecx = rax+rsi
.text:0000000000400FE2 cmp     ecx, edi                        ; if ecx > num1
.text:0000000000400FE4 jle     short loc_400FF2
.text:0000000000400FE6 lea     edx, [rcx-1]                    ;   func(rcx-1, esi)
.text:0000000000400FE9 call    func4
.text:0000000000400FEE add     eax, eax
.text:0000000000400FF0 jmp     short ret_func4
.text:0000000000400FF2 ; ---------------------------------------------------------------------------
.text:0000000000400FF2 loc_400FF2:                            
.text:0000000000400FF2 mov     eax, 0                          ; else {
.text:0000000000400FF7 cmp     ecx, edi                        ;   if ecx < num1 {
.text:0000000000400FF9 jge     short ret_func4                 ;       ret = func4(edx, rcx+1)
.text:0000000000400FF9                                         ;       return 2*ret + 1
.text:0000000000400FFB lea     esi, [rcx+1]                    ;    }
.text:0000000000400FFE call    func4
.text:0000000000401003 lea     eax, [rax+rax+1]                ;   else return eax}
.text:0000000000401003                                         ; }
.text:0000000000401007
.text:0000000000401007 ret_func4:                              ; CODE XREF: func4+22↑j
.text:0000000000401007                                         ; func4+2B↑j
.text:0000000000401007 add     rsp, 8
.text:000000000040100B retn
.text:000000000040100B ; } // starts at 400FCE
.text:000000000040100B func4 endp
int func4(int nEdx, int nEsi, int nEdi)
{
    int nRet = 0;
    int nEcx = 0;
    nRet = nEdx - nEsi;
    nRet += nRet >> 0x1F;
    nRet = nRet >> 1;
 
    nEcx = nRet + nEsi;
    // 调试到这里, nEcx==7
    if (nEcx > nEdi)
    {
        nEdx = nEcx - 1;
        nRet = func4(nEdx, nEsi, nEdi);
        nRet += nRet;
    }
    else if (nEcx < nEdi)
    {
        nRet = 2 * func4(nEdx, nEsi, nEdi) + 1;
    }
 
    // 终止条件是 nEcx == nEdi
 
    return nRet;
}
 
int main()
{
    int nNum1 = 0;
    int ret = func4(0xe, 0, nNum1);
    return 0;
}
int func4(int nEdx, int nEsi, int nEdi)
{
    int nRet = 0;
    int nEcx = 0;
    nRet = nEdx - nEsi;
    nRet += nRet >> 0x1F;
    nRet = nRet >> 1;
 
    nEcx = nRet + nEsi;
    // 调试到这里, nEcx==7
    if (nEcx > nEdi)
    {
        nEdx = nEcx - 1;
        nRet = func4(nEdx, nEsi, nEdi);
        nRet += nRet;
    }
    else if (nEcx < nEdi)
    {
        nRet = 2 * func4(nEdx, nEsi, nEdi) + 1;
    }
 
    // 终止条件是 nEcx == nEdi
 
    return nRet;
}
 
int main()
{
    int nNum1 = 0;
    int ret = func4(0xe, 0, nNum1);
    return 0;
}
.text:000000000040107A call    string_length
.text:000000000040107F cmp     eax, 6
.text:0000000000401082 jz      short loc_4010D2
.text:0000000000401084 call    explode_bomb
...
.text:00000000004010D2 mov     eax, 0
.text:00000000004010D7 jmp     short loc_40108B
.text:000000000040107A call    string_length
.text:000000000040107F cmp     eax, 6
.text:0000000000401082 jz      short loc_4010D2
.text:0000000000401084 call    explode_bomb
...
.text:00000000004010D2 mov     eax, 0
.text:00000000004010D7 jmp     short loc_40108B
.text:000000000040108B loc_40108B:                             ; CODE XREF: phase_5+4A↓j
.text:000000000040108B                                         ; phase_5+75↓j
.text:000000000040108B movzx   ecx, byte ptr [rbx+rax]         ; rbx=input
.text:000000000040108B                                         ; rax-->i
.text:000000000040108F mov     byte ptr [rsp+28h+var_28], cl
.text:0000000000401092 mov     rdx, [rsp+28h+var_28]
.text:0000000000401096 and     edx, 0Fh                        ; edx = 0x0F & input[i]
.text:0000000000401099 movzx   edx, byte ptr [rdx+4024B0h]       ; string table
.text:00000000004010A0 mov     [rsp+rax+28h+var_18], dl
.text:00000000004010A4 add     rax, 1
.text:00000000004010A8 cmp     rax, 6
.text:00000000004010AC jnz     short loc_40108B                ; rbx=input
.text:00000000004010AC                                         ; rax-->i
.text:00000000004010AE mov     [rsp+28h+var_12], 0
.text:00000000004010B3 mov     esi, offset aFlyers             ; "flyers"
.text:00000000004010B8 lea     rdi, [rsp+28h+var_18]
.text:00000000004010BD call    strings_not_equal
.text:00000000004010C2 test    eax, eax
.text:00000000004010C4 jz      short loc_4010D9
.text:00000000004010C6 call    explode_bomb
.text:000000000040108B loc_40108B:                             ; CODE XREF: phase_5+4A↓j
.text:000000000040108B                                         ; phase_5+75↓j
.text:000000000040108B movzx   ecx, byte ptr [rbx+rax]         ; rbx=input
.text:000000000040108B                                         ; rax-->i
.text:000000000040108F mov     byte ptr [rsp+28h+var_28], cl
.text:0000000000401092 mov     rdx, [rsp+28h+var_28]
.text:0000000000401096 and     edx, 0Fh                        ; edx = 0x0F & input[i]
.text:0000000000401099 movzx   edx, byte ptr [rdx+4024B0h]       ; string table
.text:00000000004010A0 mov     [rsp+rax+28h+var_18], dl
.text:00000000004010A4 add     rax, 1
.text:00000000004010A8 cmp     rax, 6
.text:00000000004010AC jnz     short loc_40108B                ; rbx=input
.text:00000000004010AC                                         ; rax-->i
.text:00000000004010AE mov     [rsp+28h+var_12], 0
.text:00000000004010B3 mov     esi, offset aFlyers             ; "flyers"
.text:00000000004010B8 lea     rdi, [rsp+28h+var_18]
.text:00000000004010BD call    strings_not_equal
.text:00000000004010C2 test    eax, eax
.text:00000000004010C4 jz      short loc_4010D9
.text:00000000004010C6 call    explode_bomb
00000000004024B0  6D 61 64 75 69 65 72 73  6E 66 6F 74 76 62 79 6C  maduiersnfotvbyl
00000000004024C0  53 6F 20 79 6F 75 20 74  68 69 6E 6B 20 79 6F 75  So you think you
00000000004024D0  20 63 61 6E 20 73 74 6F  70 20 74 68 65 20 62 6F   can stop the bo
00000000004024E0  6D 62 20 77 69 74 68 20  63 74 72 6C 2D 63 2C 20  mb with ctrl-c,
00000000004024F0  64 6F 20 79 6F 75 3F 00  43 75 72 73 65 73 2C 20  do you?.Curses,
0000000000402500  79 6F 75 27 76 65 20 66  6F 75 6E 64 20 74 68 65  you've found the
0000000000402510  20 73 65 63 72 65 74 20  70 68 61 73 65 21 00 00   secret phase!..
0000000000402520  42 75 74 20 66 69 6E 64  69 6E 67 20 69 74 20 61  But finding it a
0000000000402530  6E 64 20 73 6F 6C 76 69  6E 67 20 69 74 20 61 72  nd solving it ar
 
maduiersnfotvbylSo you think you can stop the bomb with ctrl-c, do you?.Curses, you've found the secret phase!..But finding it and solving it ar
00000000004024B0  6D 61 64 75 69 65 72 73  6E 66 6F 74 76 62 79 6C  maduiersnfotvbyl
00000000004024C0  53 6F 20 79 6F 75 20 74  68 69 6E 6B 20 79 6F 75  So you think you
00000000004024D0  20 63 61 6E 20 73 74 6F  70 20 74 68 65 20 62 6F   can stop the bo
00000000004024E0  6D 62 20 77 69 74 68 20  63 74 72 6C 2D 63 2C 20  mb with ctrl-c,
00000000004024F0  64 6F 20 79 6F 75 3F 00  43 75 72 73 65 73 2C 20  do you?.Curses,
0000000000402500  79 6F 75 27 76 65 20 66  6F 75 6E 64 20 74 68 65  you've found the
0000000000402510  20 73 65 63 72 65 74 20  70 68 61 73 65 21 00 00   secret phase!..

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//