二進制炸彈(arm)

x86上的二進制炸彈對於反彙編的練習來說還是比較經典的,由於網上有很多該程序的講解,所以在此我打算寫一下arm平臺上的二進制拆炸彈這個遊戲。

環境的搭建

  • 由於是arm平臺的環境,所以需要在linux環境下安裝一個模擬器,在此我選擇了qemu該模擬器,具體操作如下(該操作對Ubuntu環境有效,其他linux版本可自行查找方法)

    sudo apt-get install qemu-user

  • 運行ARM指令集模擬器並運行開啓gdbserver和運行bomb_1程序

    qemu-arm -g 8009 bomb_1

其中,-g參數是爲了添加調試信息,爲了使遠程gdb調試能夠起作用,8009爲自定義的端口號。

  • 另外啓動一個終端,通過命令遠程開啓gdb調試器並加載待調試程序。

    arm-linux-gdb bomb_1

  • 輸命令來連接模擬器中的gdbserver

    target remote localhost:8009

  • 輔助工具IDA pro。IDA pro是一款靜態分析的反彙編工具,利用它可以查看數據段的具體數據,用起來十分方便。


具體分析

Phase 1

  1. Arm指令
 0000844c <phase_1>:
    844c:   e92d4800    push    {fp, lr}
    8450:   e28db004    add fp, sp, #4
    8454:   e24dd008    sub sp, sp, #8
    8458:   e50b0008    str r0, [fp, #-8]
    845c:   e51b0008    ldr r0, [fp, #-8]
    8460:   e59f101c    ldr r1, [pc, #28]   ; 8484 <phase_1+0x38>
    8464:   eb000241    bl  8d70 <strings_not_equal>
    8468:   e1a03000    mov r3, r0
    846c:   e3530000    cmp r3, #0
    8470:   0a000000    beq 8478 <phase_1+0x2c>
    8474:   eb000321    bl  9100 <explode_bomb>
    8478:   e24bd004    sub sp, fp, #4
    847c:   e8bd4800    pop {fp, lr}
    8480:   e12fff1e    bx  lr
    8484:   0006483c    .word   0x0006483c
  1. 反彙編分析
    從標重點的三行彙編可以看出,該代碼從把輸入的字符串爲參數1,把8484裏存的字符串作爲參數2,然後再調用函數strings_not_equal,判斷兩個函數是否相等。所以關鍵是找8484處的地址存的字符串。有IDA pro可以看出8484處存的是數據段6483c處存的字符串,所以用ida可以找出該處的字符串。
  2. 密碼

密碼爲Let’s begin now!

利用gdb及arm服務器驗證該答案正確。


Phase 2

  1. Arm指令
    00008488 <phase_2>:
    8488:   e92d4800    push    {fp, lr}
    848c:   e28db004    add fp, sp, #4
    8490:   e24dd028    sub sp, sp, #40 ; 0x28
    8494:   e50b0028    str r0, [fp, #-40]  ; 0xffffffd8
    8498:   e24b3020    sub r3, fp, #32
    849c:   e51b0028    ldr r0, [fp, #-40]  ; 0xffffffd8
    84a0:   e1a01003    mov r1, r3
    84a4:   eb0001f4    bl  8c7c <read_six_numbers>            ○1
    ////////////////////////////////////////////////
    84a8:   e51b3020    ldr r3, [fp, #-32]  ; 0xffffffe0 
    84ac:   e3530001    cmp r3, #1
    84b0:   0a000000    beq 84b8 <phase_2+0x30> ○2
    84b4:   eb000311    bl  9100 <explode_bomb>
    84b8:   e3a03001    mov r3, #1
    84bc:   e50b3008    str r3, [fp, #-8]
    84c0:   e51b3008    ldr r3, [fp, #-8]
    84c4:   e2432001    sub r2, r3, #1
    84c8:   e3e0301b    mvn r3, #27
    84cc:   e1a02102    lsl r2, r2, #2
    84d0:   e24b0004    sub r0, fp, #4
    84d4:   e0802002    add r2, r0, r2
    84d8:   e0823003    add r3, r2, r3
    84dc:   e5933000    ldr r3, [r3]
    84e0:   e51b2008    ldr r2, [fp, #-8]
    84e4:   e2421001    sub r1, r2, #1 ○3
    84e8:   e0020391    mul r2, r1, r3
    84ec:   e51b1008    ldr r1, [fp, #-8]
    84f0:   e3e0301b    mvn r3, #27
    84f4:   e1a01101    lsl r1, r1, #2
    84f8:   e24b0004    sub r0, fp, #4
    84fc:   e0801001    add r1, r0, r1
    8500:   e0813003    add r3, r1, r34
    8504:   e5933000    ldr r3, [r3]
    //////////////////////////////////////////////

    8508:   e1520003    cmp r2, r3
    850c:   0a000000    beq 8514 <phase_2+0x8c>   ○5
    8510:   eb0002fa    bl  9100 <explode_bomb>
    //////////////////////////////////////////////
    8514:   e51b3008    ldr r3, [fp, #-8]
    8518:   e2833001    add r3, r3, #1
    851c:   e50b3008    str r3, [fp, #-8]
    8520:   e51b3008    ldr r3, [fp, #-8]
    8524:   e3530005    cmp r3, #5
    8528:   daffffe4    ble 84c0 <phase_2+0x38>
    852c:   e24bd004    sub sp, fp, #4
    8530:   e8bd4800    pop {fp, lr}
    8534:   e12fff1e    bx  lr
  1. 反彙編分析
    該炸彈的邏輯是for循環。
    ○1處那兩行由函數名可以看出爲從終端讀取六個數,並將其存入一個數組中,且地址從fp-32開始。○2處那四行是讀取數組第一個數判斷是否爲1,如果是1繼續判斷,如果不是就會explode_bomb。如果是1 的話就會使i = 1到5,然後判斷每一個數值。○3那四行及以上幾行的邏輯是取出a[i-1]的值,並將a[i-1]*(i-1),然後存入r2中。○4那兩行及以上幾行的邏輯是取出a[i]的數據,並將其存入r3中。○5處的邏輯是判斷r2和r3的值,如果相等則i+1,繼續判斷,如果不行等則explode_bomb。
    其大致的c語言邏輯如下:
    if(a[0] != 1)

        explode_bomb();
    for(i = 1;i <= 5;i++)
    {
        if(a[i] != a[i-1]*(i-1))
            explode_bomb();
    }

所以a[0] = 1;a[1] = a[2] = a[3] = a[4] = a[5] = 0;

  1. 密碼

1 0 0 0 0 0


Phase 3

  1. arm指令
    00008538 <phase_3>:
    8538:   e92d4800    push    {fp, lr}
    853c:   e28db004    add fp, sp, #4
    8540:   e24dd020    sub sp, sp, #32
    8544:   e50b0018    str r0, [fp, #-24]  ; 0xffffffe8
    8548:   e51b0018    ldr r0, [fp, #-24]  ; 0xffffffe8
    854c:   e59f119c    ldr r1, [pc, #412]  ; 86f0 <phase_3+0x1b8>○1
    8550:   e24b2014    sub r2, fp, #20
    8554:   e24b300d    sub r3, fp, #13
    8558:   e24bc00c    sub ip, fp, #12
    855c:   e58dc000    str ip, [sp]
    8560:   eb000976    bl  ab40 <_IO_sscanf>
    8564:   e1a03000    mov r3, r0
    8568:   e3530002    cmp r3, #2
    856c:   ca000000    bgt 8574 <phase_3+0x3c> ○2  
    8570:   eb0002e2    bl  9100 <explode_bomb>
    ///////////////////////////////////////////////////
    8574:   e51b3014    ldr r3, [fp, #-20]  ; 0xffffffec
    8578:   e3530007    cmp r3, #7
    857c:   979ff103    ldrls   pc, [pc, r3, lsl #2]
    8580:   ea000041    b   868c <phase_3+0x154>
    8584:   000085a4    .word   0x000085a4
    8588:   000085c4    .word   0x000085c4
    858c:   000085e0    .word   0x000085e03
    8590:   00008600    .word   0x00008600  
    8594:   0000861c    .word   0x0000861c 
    8598:   00008638    .word   0x00008638
    859c:   00008658    .word   0x00008658
    85a0:   00008670    .word   0x00008670
    /////////////////////////////////////////////////
    85a4:   e3a03071    mov r3, #113    ; 0x71   ○4
    85a8:   e54b3005    strb    r3, [fp, #-5]
    85ac:   e51b200c    ldr r2, [fp, #-12]
    85b0:   e59f313c    ldr r3, [pc, #316]  ; 86f4 <phase_3+0x1bc>
    85b4:   e1520003    cmp r2, r3
    85b8:   0a000037    beq 869c <phase_3+0x164>
    85bc:   eb0002cf    bl  9100 <explode_bomb>
    85c0:   ea000042    b   86d0 <phase_3+0x198>
    85c4:   e3a03062    mov r3, #98 ; 0x62○5
    85c8:   e54b3005    strb    r3, [fp, #-5]
    85cc:   e51b300c    ldr r3, [fp, #-12]
    85d0:   e35300d6    cmp r3, #214    ; 0xd6
    85d4:   0a000032    beq 86a4 <phase_3+0x16c>
    85d8:   eb0002c8    bl  9100 <explode_bomb>
    85dc:   ea00003b    b   86d0 <phase_3+0x198>
    85e0:   e3a03062    mov r3, #98 ; 0x62○6
    85e4:   e54b3005    strb    r3, [fp, #-5]
    85e8:   e51b200c    ldr r2, [fp, #-12]
    85ec:   e59f3104    ldr r3, [pc, #260]  ; 86f8 <phase_3+0x1c0>
    85f0:   e1520003    cmp r2, r3
    85f4:   0a00002c    beq 86ac <phase_3+0x174>
    85f8:   eb0002c0    bl  9100 <explode_bomb>
    85fc:   ea000033    b   86d0 <phase_3+0x198>
    8600:   e3a0306b    mov r3, #107    ; 0x6b   ○7
    8604:   e54b3005    strb    r3, [fp, #-5]
    8608:   e51b300c    ldr r3, [fp, #-12]
    860c:   e35300fb    cmp r3, #251    ; 0xfb
    8610:   0a000027    beq 86b4 <phase_3+0x17c>
    8614:   eb0002b9    bl  9100 <explode_bomb>
    8618:   ea00002c    b   86d0 <phase_3+0x198>
    861c:   e3a0306f    mov r3, #111    ; 0x6f○8
    8620:   e54b3005    strb    r3, [fp, #-5]
    8624:   e51b300c    ldr r3, [fp, #-12]
    8628:   e35300a0    cmp r3, #160    ; 0xa0
    862c:   0a000022    beq 86bc <phase_3+0x184>
    8630:   eb0002b2    bl  9100 <explode_bomb>
    8634:   ea000025    b   86d0 <phase_3+0x198>
    8638:   e3a03074    mov r3, #116    ; 0x74○9
    863c:   e54b3005    strb    r3, [fp, #-5]
    8640:   e51b200c    ldr r2, [fp, #-12]
    8644:   e59f30b0    ldr r3, [pc, #176]  ; 86fc <phase_3+0x1c4>
    8648:   e1520003    cmp r2, r3
    864c:   0a00001c    beq 86c4 <phase_3+0x18c>
    8650:   eb0002aa    bl  9100 <explode_bomb>
    8654:   ea00001d    b   86d0 <phase_3+0x198>
    8658:   e3a03076    mov r3, #118    ; 0x76○10
    865c:   e54b3005    strb    r3, [fp, #-5]
    8660:   e51b300c    ldr r3, [fp, #-12]
    8664:   e3530fc3    cmp r3, #780    ; 0x30c
    8668:   0a000000    beq 8670 <phase_3+0x138>
    866c:   eb0002a3    bl  9100 <explode_bomb>
    8670:   e3a03062    mov r3, #98 ; 0x62○11
    8674:   e54b3005    strb    r3, [fp, #-5]
    8678:   e51b300c    ldr r3, [fp, #-12]
    867c:   e3530f83    cmp r3, #524    ; 0x20c
    8680:   0a000011    beq 86cc <phase_3+0x194>
    8684:   eb00029d    bl  9100 <explode_bomb>
    8688:   ea000010    b   86d0 <phase_3+0x198>
    868c:   e3a03078    mov r3, #120    ;0x78 ○12
    8690:   e54b3005    strb    r3, [fp, #-5]
    8694:   eb000299    bl  9100 <explode_bomb>
    8698:   ea00000c    b   86d0 <phase_3+0x198>
    869c:   e1a00000    nop         ; (mov r0, r0)
    86a0:   ea00000a    b   86d0 <phase_3+0x198>
    86a4:   e1a00000    nop         ; (mov r0, r0)
    86a8:   ea000008    b   86d0 <phase_3+0x198>
    86ac:   e1a00000    nop         ; (mov r0, r0)
    86b0:   ea000006    b   86d0 <phase_3+0x198>
    86b4:   e1a00000    nop         ; (mov r0, r0)
    86b8:   ea000004    b   86d0 <phase_3+0x198>
    86bc:   e1a00000    nop         ; (mov r0, r0)
    86c0:   ea000002    b   86d0 <phase_3+0x198>
    86c4:   e1a00000    nop         ; (mov r0, r0)
    86c8:   ea000000    b   86d0 <phase_3+0x198>
    86cc:   e1a00000    nop         ; (mov r0, r0)
    86d0:   e55b300d    ldrb    r3, [fp, #-13]
    86d4:   e55b2005    ldrb    r2, [fp, #-5]
    86d8:   e1520003    cmp r2,r313
    86dc:   0a000000    beq 86e4 <phase_3+0x1ac>
    86e0:   eb000286    bl  9100 <explode_bomb>
    86e4:   e24bd004    sub sp, fp, #4
    86e8:   e8bd4800    pop {fp, lr}
    86ec:   e12fff1e    bx  lr
    86f0:   00064850    .word   0x00064850
    86f4:   00000309    .word   0x00000309
    86f8:   000002f3    .word   0x000002f3
    86fc:   000001ca    .word   0x000001ca
  1. 反彙編分析

○1處將pc+412的數據傳入r1,藉助IDA pro可以查看pc+412引用的是
00064850處的數據,如圖:

所以該處的數據爲”%d %c %d”,由此可知輸入的數據的形式爲int,char,int。
○2處判斷第一個參數int是否大於2,如果大於2則進行switch操作,如果不是則explode_bomb。○3處是對輸入的第一個int進行switch判斷,其僞代碼如下:

    switch(int c)
    {
        case 0:
            jmp 85a4;
            break;
        case 1:
            jmp 85c4;
            break;
        case 2:
            jmp 85e0;
            break;
        case 3:
            jmp 8600;
            break;
        case 4:
            jmp 861c;
            break;
        case 5:
            jmp 8638;
            break;
        case 6:
            jmp 8658;
            break;
        case 7:
            jmp 8670;
            break;
        default:
        jmp 868c;
            break;  
    }

○4-○11是對case 0 –case 7這八種情況的具體判斷,其邏輯都是一樣的,所以在此只分析一種情況(由於必須要求第一個int大於2,所以分析爲3,4,5,6,7這五種情況)。現分析○7,首先將0x6b放入fp-5,然後將fp-12的值(即第三個傳入的int的值)與0xfb(十進制爲251)進行比較,如果相等則跳轉86b4,如果不是的話就會explode_bomb;然後相等的話跳轉86b4,我們發現從869c到86cc的邏輯都是先nop,什麼都不做,然後再b 86d0

    00008760 <phase_4>:
    8760:   e92d4800    push    {fp, lr}
    8764:   e28db004    add fp, sp, #4
    8768:   e24dd010    sub sp, sp, #16
    876c:   e50b0010    str r0, [fp, #-16]
    8770:   e51b1010    ldr r1, [fp, #-16]
    8774:   e59f2054    ldr r2, [pc, #84]   ; 87d0 <phase_4+0x70>  ○1
    8778:   e24b3008    sub r3, fp, #8
    877c:   e1a00001    mov r0, r1
    8780:   e1a01002    mov r1, r2
    8784:   e1a02003    mov r2, r3
    8788:   eb0008ec    bl  ab40 <_IO_sscanf>
    878c:   e1a03000    mov r3, r0
    8790:   e3530001    cmp r3, #1
    8794:   1a000002    bne 87a4 <phase_4+0x44>
    8798:   e51b3008    ldr r3, [fp, #-8]
    879c:   e3530000    cmp r3, #0
    87a0:   ca000000    bgt 87a8 <phase_4+0x48>  ○2 
    87a4:   eb000255    bl  9100 <explode_bomb>
    ////////////////////////////////////
    87a8:   e51b3008    ldr r3, [fp, #-8]
    87ac:   e1a00003    mov r0, r33 
    87b0:   ebffffd2    bl  8700 <func4>
    ///////////////////////////////////
    87b4:   e1a03000    mov r3, r0
    87b8:   e3530008    cmp r3, #8
    87bc:   0a000000    beq 87c4 <phase_4+0x64> ○8
    87c0:   eb00024e    bl  9100 <explode_bomb>
    87c4:   e24bd004    sub sp, fp, #4
    87c8:   e8bd4800    pop {fp, lr}
    87cc:   e12fff1e    bx  lr
    87d0:   0006485c    .word   0x0006485c

    00008700 <func4>:
    8700:   e92d4810    push    {r4, fp, lr}
    8704:   e28db008    add fp, sp, #8
    8708:   e24dd00c    sub sp, sp, #12
    870c:   e50b0010    str r0, [fp, #-16]
    8710:   e51b3010    ldr r3, [fp, #-16]
    8714:   e3530001    cmp r3, #1  ○4
    8718:   da00000b    ble 874c <func4+0x4c>
    ////////////////////////////////////////////
    871c:   e51b3010    ldr r3, [fp, #-16]
    8720:   e2433001    sub r3, r3, #1
    8724:   e1a00003    mov r0, r35
    8728:   ebfffff4    bl  8700 <func4>
    /////////////////////////////////////////////
    872c:   e1a04000    mov r4, r0
    8730:   e51b3010    ldr r3, [fp, #-16]
    8734:   e2433002    sub r3, r3, #2   ○6
    8738:   e1a00003    mov r0, r3
    873c:   ebffffef    bl  8700 <func4>
    8740:   e1a03000    mov r3, r0
    8744:   e0843003    add r3, r4, r3
    8748:   ea000000    b   8750 <func4+0x50>
    874c:   e3a03001    mov r3, #1
    8750:   e1a00003    mov r0, r3  
    8754:   e24bd008    sub sp, fp, #8   ○7
    8758:   e8bd4810    pop {r4, fp, lr}
    875c:   e12fff1e    bx  lr
  1. 反彙編分析

○1處是輸入的參數的形式,位於87d0處,利用IDA pro找到了87d0引用了0006485C數據段的數據,爲

即要求輸入一個數字。○2處判斷是否是輸入的參數是否大於0,如果大於0則繼續判斷,如果不是則explode_bomb。○3處將輸入的數傳入r0中作爲參數然後調用func4()。○4首先將傳入的參數存入fp-16中,然後判斷參數是否小於等於1,如果小於等於1的話就跳到○7處,○7處將返回值賦值爲1,然後pop返回值和參數;如果大於1的話就到○5,○5和○6的邏輯就是分別讓參數-1和-2,然後再分別調用func4,由此可以看出該bomb的邏輯是一個遞歸的調用。其c語言的僞代碼如下:

    func4(int i)
    {
        if(i < = 1)
            return 1;
        else
            return func4(i-1) + func4(i-2);
    }

然後看代碼塊○8,其將func4函數的返回值與8進行比較,如果等於8就通過,否則explode_bomb。所以通過計算可以得出輸入的值爲5。

  1. 密碼

5

Phase 5

  1. Arm指令
    000087d4 <phase_5>:
    87d4:   e92d4800    push    {fp, lr}
    87d8:   e28db004    add fp, sp, #4
    87dc:   e24dd018    sub sp, sp, #24
    87e0:   e50b0018    str r0, [fp, #-24]  ; 0xffffffe8
    87e4:   e51b0018    ldr r0, [fp, #-24]  ; 0xffffffe8
    87e8:   eb000144    bl  8d00 <string_length>
    87ec:   e1a03000    mov r3, r0
    87f0:   e3530006    cmp r3, #6  ○1
    87f4:   0a000000    beq 87fc <phase_5+0x28>
    87f8:   eb000240    bl  9100 <explode_bomb>
    ////////////////////////////////////////
    87fc:   e3a03000    mov r3, #0
    8800:   e50b3008    str r3, [fp, #-8]○2
    8804:   ea00000f    b   8848 <phase_5+0x74>
    ////////////////////////////////////////
    8808:   e51b1008    ldr r1, [fp, #-8]
    880c:   e51b3008    ldr r3, [fp, #-8]
    8810:   e51b2018    ldr r2, [fp, #-24]  ; 0xffffffe8
    8814:   e0823003    add r3, r2, r3○4
    8818:   e5d33000    ldrb    r3, [r3]
    881c:   e203300f    and r3, r3, #15
    ///////////////////////////////////////
    8820:   e59f2060    ldr r2, [pc, #96]   ; 8888 <phase_5+0xb4>
    8824:   e7d22003    ldrb    r2, [r2, r3]   ○5
    ///////////////////////////////////////
    8828:   e3e0300b    mvn r3, #11
    882c:   e24b0004    sub r0, fp, #4
    8830:   e0801001    add r1, r0, r1 ○6
    8834:   e0813003    add r3, r1, r3
    8838:   e5c32000    strb    r2, [r3]
    ////////////////////////////////////
    883c:   e51b3008    ldr r3, [fp, #-8]
    8840:   e2833001    add r3, r3, #1   ○7
    8844:   e50b3008    str r3, [fp, #-8]
    ////////////////////////////////////
    8848:   e51b3008    ldr r3, [fp, #-8]
    884c:   e3530005    cmp r3, #5  ○3
    8850:   daffffec    ble 8808 <phase_5+0x34>
    ///////////////////////////////////
    8854:   e3a03000    mov r3, #0
    8858:   e54b300a    strb    r3, [fp, #-10]
    885c:   e24b3010    sub r3, fp, #16 
    8860:   e1a00003    mov r0, r3  ○8
    8864:   e59f1020    ldr r1, [pc, #32]   ; 888c <phase_5+0xb8>
    8868:   eb000140    bl  8d70 <strings_not_equal>
    886c:   e1a03000    mov r3, r0
    8870:   e3530000    cmp r3, #0
    8874:   0a000000    beq 887c <phase_5+0xa8>
    8878:   eb000220    bl  9100 <explode_bomb>
    887c:   e24bd004    sub sp, fp, #4
    8880:   e8bd4800    pop {fp, lr}
    8884:   e12fff1e    bx  lr
    8888:   0008216c    .word   0x0008216c
    888c:   00064860    .word   0x00064860
  1. 反彙編分析

○1中代碼首先判斷讀入的字符串的長度,如果長度等於6則跳到代碼塊○2中去,如果不等於6則explode_bomb。在代碼塊○2中,首先將計數變量i置爲0,然後跳到代碼塊○3中去,在代碼塊○3中先判斷i是否小於等於5,如果小於等於5的話就跳入○4中,其中○4○5○6○7爲for循環的主體,我將其化成了這4部分。其中在○4的邏輯如下:取出字符串的第i個字符s[i],
然後將s[i]與0xF相與,其中一個char爲一個字節,由兩個16進制數組成,做相與運算後就只取出char的後4個b,將數值存入r3中。然後到代碼塊○5中,找到數據pc+96(8888)處的數據,根據IDA pro得出其引用的是0008216C處的數據,數據如圖:

,然後根據r3中的數值作爲索引取得相應的字符,將得到的字符存入r2中,然後到代碼塊○6中,其將r2的數據存入(fp-4-11)+i的地址處。代碼○7是將i++。所以該段代碼的僞代碼如下:

    for(i = 0;i <= 5;i++)
    {
        int a = (int)(s[i]&0xF);
        s1[i] = 0x0008216c+a;
    }

其中s爲輸入的字符串,s1爲找到的字符串。
for循環結束了之後,得到長度爲6的s1字符串,到了代碼塊○8中,該邏輯是將s1與(pc-32)即888c處的字符串進行比較,根據IDA pro得到引用了數據段00064860處的數據爲:

所以只有當s1爲”giants”時,才能通過,即索引順序爲0xF,0x0,0x5,0xB,0xD,0x1,查ascii表得到後4個b分別爲這些的十六進制的數的字符分別爲opeka(可能有多重情況,只要後4個b分別對應那五個十六進制數的字符即可)。

  1. 密碼

opeka

Phase 6

指令及邏輯分析:
由於該炸彈的指令及邏輯較長,所以指令分開了幾份分別進行分析。

00008890 :

1:讀入六個數

     8890:  e92d4800    push    {fp, lr}
    8894:   e28db004    add fp, sp, #4
    8898:   e24dd048    sub sp, sp, #72 ; 0x48
    889c:   e50b0048    str r0, [fp, #-72]  ; 0xffffffb8
    88a0:   e59f3234    ldr r3, [pc, #564]  ; 8adc <phase_6+0x24c>
    88a4:   e50b3010    str r3, [fp, #-16]
    88a8:   e24b3028    sub r3, fp, #40 ; 0x28
    88ac:   e51b0048    ldr r0, [fp, #-72]  ; 0xffffffb8
    88b0:   e1a01003    mov r1, r3
    88b4:   eb0000f0    bl  8c7c <read_six_numbers>

以上的指令的邏輯比較簡單,是首先讀入六個數字,並將其放入數組中,假設數組爲a。

2:對這六個數的值進行判定

        88b8:   e3a03000    mov r3, #0
    88bc:   e50b300c    str r3, [fp, #-12]
    88c0:   e51b200c    ldr r2, [fp, #-12]  ○1
    ////////////////////////////////////
    88c4:   e3e03023    mvn r3, #35 ; 0x23
    88c8:   e1a02102    lsl r2, r2, #2
    88cc:   e24b0004    sub r0, fp, #4
    88d0:   e0802002    add r2, r0, r2   ○2
    88d4:   e0823003    add r3, r2, r3
    88d8:   e5933000    ldr r3, [r3]
    ///////////////////////////////////
    88dc:   e2433001    sub r3, r3, #1
    88e0:   e3530005    cmp r3, #5   ○3
    88e4:   9a000000    bls 88ec <phase_6+0x5c>
    88e8:   eb000204    bl  9100 <explode_bomb>
    //////////////////////////////////
    88ec:   e51b300c    ldr r3, [fp, #-12]
    88f0:   e2833001    add r3, r3, #1   ○4
    88f4:   e50b3008    str r3, [fp, #-8]
    88f8:   ea000013    b   894c <phase_6+0xbc>
    //////////////////////////////////
    88fc:   e51b200c    ldr r2, [fp, #-12]
    8900:   e3e03023    mvn r3, #35 ; 0x23
    8904:   e1a02102    lsl r2, r2, #2
    8908:   e24b1004    sub r1, fp, #4  ○6
    890c:   e0812002    add r2, r1, r2 
    8910:   e0823003    add r3, r2, r3
    8914:   e5932000    ldr r2, [r3]
    //////////////////////////////////
    8918:   e51b1008    ldr r1, [fp, #-8]
    891c:   e3e03023    mvn r3, #35 ; 0x23
    8920:   e1a01101    lsl r1, r1, #2
    8924:   e24b0004    sub r0, fp, #4   ○7
    8928:   e0801001    add r1, r0, r1
    892c:   e0813003    add r3, r1, r3
    8930:   e5933000    ldr r3, [r3]
    /////////////////////////////////
    8934:   e1520003    cmp r2, r3
    8938:   1a000000    bne 8940 <phase_6+0xb0> 
    893c:   eb0001ef    bl  9100 <explode_bomb>
    8940:   e51b3008    ldr r3, [fp, #-8]○8
    8944:   e2833001    add r3, r3, #1
    8948:   e50b3008    str r3, [fp, #-8]
    ///////////////////////////////////
    894c:   e51b3008    ldr r3, [fp, #-8]
    8950:   e3530005    cmp r3, #5   ○5
    8954:   daffffe8    ble 88fc <phase_6+0x6c>
    //////////////////////////////////
    8958:   e51b300c    ldr r3, [fp, #-12]
    895c:   e2833001    add r3, r3, #1
    8960:   e50b300c    str r3, [fp, #-12]   ○9
    8964:   e51b300c    ldr r3, [fp, #-12]
    8968:   e3530005    cmp r3, #5
    896c:   daffffd3    ble 88c0 <phase_6+0x30>
    8970:   e3a03000    mov r3, #0
    8974:   e50b300c    str r3, [fp, #-12]

以上的指令爲兩個for循環的嵌套。
其中○1爲(fp-12)處存的變量假設爲i,把變量i的值存入r2,然後代碼段○2處爲取出a[i]的值並將其存入r3中,緊接着代碼段○3處判斷r3的值是否大於6,如果大於6就explode_bomb。然後進入代碼塊○4中,在此就進入了第二個for循環,首先初始化(fp-8)處的變量,設爲j,j = i+1;然後進入代碼段○5處對j的值進行判斷,如果大於5就進入代碼段○9,其中代碼○9是將i增1並進行判斷,如果i大於5就跳出for循環,如果小於5則跳至○1再進行一次for循環,對於代碼○5處的判斷如果j小於等於5的話,則跳入代碼○6處,其中邏輯爲取出a[i]的值將其放入r2中,然後進入○7中,取出a[j]的值將其放入r3中,然後進入○8,將r2和r3進行比較,如果相等的話就explode_bomb,不行等就進入○5,又進行了一次循環。其僞代碼如下:

    for(int i = 0;i <= 5;i++)
        {if(a[i]>6)
            explode_bomb();
        for(int j = i+1;j<=5;j++)
            {if(a[j] == a[i])
                explode_bomb();
    }
    }

3:根據輸入的6個數把鏈表的6個node進行索引排序

        8978:   e59f315c    ldr r3, [pc, #348]  ; 8adc <phase_6+0x24c>   
    897c:   e50b3010    str r3, [fp, #-16]
    8980:   e3a03001    mov r3, #1 ○1
    8984:   e50b3008    str r3, [fp, #-8]
    8988:   ea000005    b   89a4 <phase_6+0x114>
    /////////////////////////////////////////////
    898c:   e51b3010    ldr r3, [fp, #-16]
    8990:   e5933008    ldr r3, [r3, #8]
    8994:   e50b3010    str r3, [fp, #-16]  ○3
    8998:   e51b3008    ldr r3, [fp, #-8]
    899c:   e2833001    add r3, r3, #1
    89a0:   e50b3008    str r3, [fp, #-8]
    ////////////////////////////////////////
    89a4:   e51b200c    ldr r2, [fp, #-12]
    89a8:   e3e03023    mvn r3, #35 ; 0x23
    89ac:   e1a02102    lsl r2, r2, #2
    89b0:   e24b1004    sub r1, fp, #4
    89b4:   e0812002    add r2, r1, r2  ○2
    89b8:   e0823003    add r3, r2, r3
    89bc:   e5932000    ldr r2, [r3]
    89c0:   e51b3008    ldr r3, [fp, #-8]
    89c4:   e1520003    cmp r2, r3
    89c8:   caffffef    bgt 898c <phase_6+0xfc>
    ////////////////////////////////////////////
    89cc:   e51b200c    ldr r2, [fp, #-12]
    89d0:   e3e0303b    mvn r3, #59 ; 0x3b
    89d4:   e1a02102    lsl r2, r2, #2
    89d8:   e24b0004    sub r0, fp, #4  ○4
    89dc:   e0802002    add r2, r0, r2
    89e0:   e0823003    add r3, r2, r3
    89e4:   e51b2010    ldr r2, [fp, #-16]
    89e8:   e5832000    str r2, [r3]
    ///////////////////////////////////////////
    89ec:   e51b300c    ldr r3, [fp, #-12]
    89f0:   e2833001    add r3, r3, #1
    89f4:   e50b300c    str r3, [fp, #-12]   ○5
    89f8:   e51b300c    ldr r3, [fp, #-12]
    89fc:   e3530005    cmp r3, #5
    8a00:   daffffdc    ble 8978 <phase_6+0xe8>
    ///////////////////////////////////////////
    8a04:   e51b3040    ldr r3, [fp, #-64]  ; 0xffffffc0
    8a08:   e50b3010    str r3, [fp, #-16]○9
    8a0c:   e3a03001    mov r3, #1
    8a10:   e50b300c    str r3, [fp, #-12]
    /////////////////////////////////////////
    8a14:   e51b200c    ldr r2, [fp, #-12]
    8a18:   e3e0303b    mvn r3, #59 ; 0x3b
    8a1c:   e1a02102    lsl r2, r2, #2
    8a20:   e24b1004    sub r1, fp, #4  
    8a24:   e0812002    add r2, r1, r2○6
    8a28:   e0823003    add r3, r2, r3
    8a2c:   e5932000    ldr r2, [r3]
    8a30:   e51b3010    ldr r3, [fp, #-16]
    8a34:   e5832008    str r2, [r3, #8]
    ///////////////////////////////////////
    8a38:   e51b200c    ldr r2, [fp, #-12]
    8a3c:   e3e0303b    mvn r3, #59 ; 0x3b
    8a40:   e1a02102    lsl r2, r2, #2○7
    8a44:   e24b0004    sub r0, fp, #4
    8a48:   e0802002    add r2, r0, r2
    8a4c:   e0823003    add r3, r2, r3
    8a50:   e5933000    ldr r3, [r3]
    8a54:   e50b3010    str r3, [fp, #-16]
    ////////////////////////////////////
    8a58:   e51b300c    ldr r3, [fp, #-12]
    8a5c:   e2833001    add r3, r3, #1
    8a60:   e50b300c    str r3, [fp, #-12] ○8
    8a64:   e51b300c    ldr r3, [fp, #-12]
    8a68:   e3530005    cmp r3, #5
    8a6c:   daffffe8    ble 8a14 <phase_6+0x184>

該段代碼也有一個for循環的嵌套。
首先初始化,將(PC+348)的索引的數存入r3中,由ida pro得出具體數據爲

所以將node1的索引傳入r3,然後跳入到代碼塊○2,其邏輯是先取出a[i]的數據至r2,然後取出j至r3,比較這兩個數據的大小,如果r2 >r3,就跳到代碼段○3,該邏輯是將r3+0x8的數據存入fp-16中,有以上的數據可知該數據爲0x20A0,用IDA pro查找到爲:

以此類推,根據每個節點的第8個字節處的數據作爲下一個節點的地址,直到找到鏈表的a[i]個元素,就會跳出該內層的for循環,然後進入代碼塊○4,該邏輯是將該node的地址存入-0x3c+[R11] + 4 * i中,然後進入代碼塊○5,其邏輯是使變量i增1,然後判斷是否大於5,如果小於5再跳入○1中繼續循環。
其for循環的僞代碼如下:

    for(int i = 0;i <=5;i++)
    {
        node = 0x000820AC;
        for(int j = 1;j<a[i];j++)
            node = *(node+0x8);
        -0x3c+[R11] + 4 * i = node;
    }

所以經過上一個for循環的嵌套,從-0x3c+[R11]開始就有了這些節點的地址的索引,然後進入代碼段○9,其邏輯是先將fp-12處的變量i初始化爲1,目的是進入for循環。進入代碼段○6,其目的是將*((-0x3c+[R11]+i-1)+0x8) = (-0x3c+[R11]+i);然後進入代碼段○7,其目的是將當前節點設爲-0x3c+[R11]+i處的地址所指向的節點,進入代碼塊○8,使i增1並判斷和5的大小關係。

4:判斷鏈表的節點的數值是否是按從大到小的順序排列的

    8a70:   e51b3010    ldr r3, [fp, #-16]
    8a74:   e3a02000    mov r2, #0
    8a78:   e5832008    str r2, [r3, #8]
    8a7c:   e3a03000    mov r3, #0  ○1
    8a80:   e50b300c    str r3, [fp, #-12]
    8a84:   e51b3040    ldr r3, [fp, #-64]  ; 0xffffffc0
    8a88:   e50b3010    str r3, [fp, #-16]
    //////////////////////////////////////
    8a8c:   e51b3010    ldr r3, [fp, #-16]
    8a90:   e5932000    ldr r2, [r3]
    8a94:   e51b3010    ldr r3, [fp, #-16]
    8a98:   e5933008    ldr r3, [r3, #8] ○2
    8a9c:   e5933000    ldr r3, [r3]
    8aa0:   e1520003    cmp r2, r3
    8aa4:   aa000000    bge 8aac <phase_6+0x21c>
    8aa8:   eb000194    bl  9100 <explode_bomb>
    //////////////////////////////////////////
    8aac:   e51b3010    ldr r3, [fp, #-16]
    8ab0:   e5933008    ldr r3, [r3, #8]  ○3
    8ab4:   e50b3010    str r3, [fp, #-16]
    ///////////////////////////////////////
    8ab8:   e51b300c    ldr r3, [fp, #-12]
    8abc:   e2833001    add r3, r3, #1   
    8ac0:   e50b300c    str r3, [fp, #-12] ○4
    8ac4:   e51b300c    ldr r3, [fp, #-12]
    8ac8:   e3530004    cmp r3, #4
    8acc:   daffffee    ble 8a8c <phase_6+0x1fc>

首先進入○1進行初始化,將(fp-16)處的地址換爲鏈表的第一個node,並對(fp-12)的變量i初始化爲0。然後進入代碼塊○2,首先獲得當前node的地址,並將該node的數據存入r2中,地址存入r3中,然後通過[r3+8]獲得下一個node的地址,並將下一個node的地址存入r3中,然後比較r2和r3的值,如果r2小於r3,就explode_bomb,
如果不小於就進入代碼塊○3,該邏輯是將當前節點(fp-16)的地址改爲[r3+8]處的數值,即爲下一個節點的地址,然後進入代碼○4,對變量i進行增1操作,並判斷和4的大小。其僞代碼如下:
其中node的數據結構如下:

    struct node
     {
     int x, y;
     node *next; };
    //進行判斷:
    node a = firstNode;
       for(int i = 0; i < 5; i++)
    {
       node b = a->next;
       if (a->x >= b->x)
      a = b;
       else
      explode_bomb();
      }

所以根據邏輯,先找出每個節點的數據,然後再根據輸入的數進行排序,保證其是從大到小的順序排列的。根據IDA pro找到每個node所在的地址爲:
地址 數據 下個節點地址
0x820AC 0xFD 0x820A0
0x820A0 0x2D5 0x82094
0x82094 0x12D 0x82088
0x82088 0x3E5 0x8207C
0x8207C 0xD4 0x82070
0x82070 0x1B0

所以由大到小排列的話就爲4 2 6 3 1 5

  1. 密碼

    4 2 6 3 1 5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章