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, #48454:   e24dd008    sub sp, sp, #88458:   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, r0846c:   e3530000    cmp r3, #08470:   0a000000    beq 8478 <phase_1+0x2c>8474:   eb000321    bl  9100 <explode_bomb>8478:   e24bd004    sub sp, fp, #4847c:   e8bd4800    pop {fp, lr}8480:   e12fff1e    bx  lr8484:   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, #48490:   e24dd028    sub sp, sp, #40 ; 0x288494:   e50b0028    str r0, [fp, #-40]  ; 0xffffffd88498:   e24b3020    sub r3, fp, #32849c:   e51b0028    ldr r0, [fp, #-40]  ; 0xffffffd884a0:   e1a01003    mov r1, r384a4:   eb0001f4    bl  8c7c <read_six_numbers>            ○184a8:   e51b3020    ldr r3, [fp, #-32]  ; 0xffffffe0 84ac:   e3530001    cmp r3, #184b0:   0a000000    beq 84b8 <phase_2+0x30> ○284b4:   eb000311    bl  9100 <explode_bomb>84b8:   e3a03001    mov r3, #184bc:   e50b3008    str r3, [fp, #-8]84c0:   e51b3008    ldr r3, [fp, #-8]84c4:   e2432001    sub r2, r3, #184c8:   e3e0301b    mvn r3, #2784cc:   e1a02102    lsl r2, r2, #284d0:   e24b0004    sub r0, fp, #484d4:   e0802002    add r2, r0, r284d8:   e0823003    add r3, r2, r384dc:   e5933000    ldr r3, [r3]84e0:   e51b2008    ldr r2, [fp, #-8]84e4:   e2421001    sub r1, r2, #1 ○384e8:   e0020391    mul r2, r1, r384ec:   e51b1008    ldr r1, [fp, #-8]84f0:   e3e0301b    mvn r3, #2784f4:   e1a01101    lsl r1, r1, #284f8:   e24b0004    sub r0, fp, #484fc:   e0801001    add r1, r0, r18500:   e0813003    add r3, r1, r3  ○48504:   e5933000    ldr r3, [r3]//8508:   e1520003    cmp r2, r3850c:   0a000000    beq 8514 <phase_2+0x8c>   ○58510:   eb0002fa    bl  9100 <explode_bomb>//8514:   e51b3008    ldr r3, [fp, #-8]8518:   e2833001    add r3, r3, #1851c:   e50b3008    str r3, [fp, #-8]8520:   e51b3008    ldr r3, [fp, #-8]8524:   e3530005    cmp r3, #58528:   daffffe4    ble 84c0 <phase_2+0x38>852c:   e24bd004    sub sp, fp, #48530:   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, #48540:   e24dd020    sub sp, sp, #328544:   e50b0018    str r0, [fp, #-24]  ; 0xffffffe88548:   e51b0018    ldr r0, [fp, #-24]  ; 0xffffffe8854c:   e59f119c    ldr r1, [pc, #412]  ; 86f0 <phase_3+0x1b8>○18550:   e24b2014    sub r2, fp, #208554:   e24b300d    sub r3, fp, #138558:   e24bc00c    sub ip, fp, #12855c:   e58dc000    str ip, [sp]8560:   eb000976    bl  ab40 <_IO_sscanf>8564:   e1a03000    mov r3, r08568:   e3530002    cmp r3, #2856c:   ca000000    bgt 8574 <phase_3+0x3c> ○2  8570:   eb0002e2    bl  9100 <explode_bomb>///8574:   e51b3014    ldr r3, [fp, #-20]  ; 0xffffffec8578:   e3530007    cmp r3, #7857c:   979ff103    ldrls   pc, [pc, r3, lsl #2]8580:   ea000041    b   868c <phase_3+0x154>8584:   000085a4    .word   0x000085a48588:   000085c4    .word   0x000085c4858c:   000085e0    .word   0x000085e0   ○38590:   00008600    .word   0x00008600  8594:   0000861c    .word   0x0000861c 8598:   00008638    .word   0x00008638859c:   00008658    .word   0x0000865885a0:   00008670    .word   0x00008670/85a4:   e3a03071    mov r3, #113    ; 0x71   ○485a8:   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, r385b8:   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○585c8:   e54b3005    strb    r3, [fp, #-5]85cc:   e51b300c    ldr r3, [fp, #-12]85d0:   e35300d6    cmp r3, #214    ; 0xd685d4:   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○685e4:   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, r385f4:   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   ○78604:   e54b3005    strb    r3, [fp, #-5]8608:   e51b300c    ldr r3, [fp, #-12]860c:   e35300fb    cmp r3, #251    ; 0xfb8610:   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○88620:   e54b3005    strb    r3, [fp, #-5]8624:   e51b300c    ldr r3, [fp, #-12]8628:   e35300a0    cmp r3, #160    ; 0xa0862c:   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○9863c:   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, r3864c:   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○10865c:   e54b3005    strb    r3, [fp, #-5]8660:   e51b300c    ldr r3, [fp, #-12]8664:   e3530fc3    cmp r3, #780    ; 0x30c8668:   0a000000    beq 8670 <phase_3+0x138>866c:   eb0002a3    bl  9100 <explode_bomb>8670:   e3a03062    mov r3, #98 ; 0x62○118674:   e54b3005    strb    r3, [fp, #-5]8678:   e51b300c    ldr r3, [fp, #-12]867c:   e3530f83    cmp r3, #524    ; 0x20c8680:   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 ○128690:   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,r3○1386dc:   0a000000    beq 86e4 <phase_3+0x1ac>86e0:   eb000286    bl  9100 <explode_bomb>86e4:   e24bd004    sub sp, fp, #486e8:   e8bd4800    pop {fp, lr}86ec:   e12fff1e    bx  lr86f0:   00064850    .word   0x0006485086f4:   00000309    .word   0x0000030986f8:   000002f3    .word   0x000002f386fc:   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, #48768:   e24dd010    sub sp, sp, #16876c:   e50b0010    str r0, [fp, #-16]8770:   e51b1010    ldr r1, [fp, #-16]8774:   e59f2054    ldr r2, [pc, #84]   ; 87d0 <phase_4+0x70>  ○18778:   e24b3008    sub r3, fp, #8877c:   e1a00001    mov r0, r18780:   e1a01002    mov r1, r28784:   e1a02003    mov r2, r38788:   eb0008ec    bl  ab40 <_IO_sscanf>878c:   e1a03000    mov r3, r08790:   e3530001    cmp r3, #18794:   1a000002    bne 87a4 <phase_4+0x44>8798:   e51b3008    ldr r3, [fp, #-8]879c:   e3530000    cmp r3, #087a0:   ca000000    bgt 87a8 <phase_4+0x48>  ○2 87a4:   eb000255    bl  9100 <explode_bomb>87a8:   e51b3008    ldr r3, [fp, #-8]87ac:   e1a00003    mov r0, r3 ○3 87b0:   ebffffd2    bl  8700 <func4>///87b4:   e1a03000    mov r3, r087b8:   e3530008    cmp r3, #887bc:   0a000000    beq 87c4 <phase_4+0x64> ○887c0:   eb00024e    bl  9100 <explode_bomb>87c4:   e24bd004    sub sp, fp, #487c8:   e8bd4800    pop {fp, lr}87cc:   e12fff1e    bx  lr87d0:   0006485c    .word   0x0006485c00008700 <func4>:8700:   e92d4810    push    {r4, fp, lr}8704:   e28db008    add fp, sp, #88708:   e24dd00c    sub sp, sp, #12870c:   e50b0010    str r0, [fp, #-16]8710:   e51b3010    ldr r3, [fp, #-16]8714:   e3530001    cmp r3, #1  ○48718:   da00000b    ble 874c <func4+0x4c>871c:   e51b3010    ldr r3, [fp, #-16]8720:   e2433001    sub r3, r3, #18724:   e1a00003    mov r0, r3   ○58728:   ebfffff4    bl  8700 <func4>/872c:   e1a04000    mov r4, r08730:   e51b3010    ldr r3, [fp, #-16]8734:   e2433002    sub r3, r3, #2   ○68738:   e1a00003    mov r0, r3873c:   ebffffef    bl  8700 <func4>8740:   e1a03000    mov r3, r08744:   e0843003    add r3, r4, r38748:   ea000000    b   8750 <func4+0x50>874c:   e3a03001    mov r3, #18750:   e1a00003    mov r0, r3  8754:   e24bd008    sub sp, fp, #8   ○78758:   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;elsereturn 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, #487dc:   e24dd018    sub sp, sp, #2487e0:   e50b0018    str r0, [fp, #-24]  ; 0xffffffe887e4:   e51b0018    ldr r0, [fp, #-24]  ; 0xffffffe887e8:   eb000144    bl  8d00 <string_length>87ec:   e1a03000    mov r3, r087f0:   e3530006    cmp r3, #6  ○187f4:   0a000000    beq 87fc <phase_5+0x28>87f8:   eb000240    bl  9100 <explode_bomb>////////////////////////////////////////87fc:   e3a03000    mov r3, #08800:   e50b3008    str r3, [fp, #-8]○28804:   ea00000f    b   8848 <phase_5+0x74>////////////////////////////////////////8808:   e51b1008    ldr r1, [fp, #-8]880c:   e51b3008    ldr r3, [fp, #-8]8810:   e51b2018    ldr r2, [fp, #-24]  ; 0xffffffe88814:   e0823003    add r3, r2, r3○48818:   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, #11882c:   e24b0004    sub r0, fp, #48830:   e0801001    add r1, r0, r1 ○68834:   e0813003    add r3, r1, r38838:   e5c32000    strb    r2, [r3]////////////////////////////////////883c:   e51b3008    ldr r3, [fp, #-8]8840:   e2833001    add r3, r3, #1   ○78844:   e50b3008    str r3, [fp, #-8]////////////////////////////////////8848:   e51b3008    ldr r3, [fp, #-8]884c:   e3530005    cmp r3, #5  ○38850:   daffffec    ble 8808 <phase_5+0x34>///////////////////////////////////8854:   e3a03000    mov r3, #08858:   e54b300a    strb    r3, [fp, #-10]885c:   e24b3010    sub r3, fp, #16 8860:   e1a00003    mov r0, r3  ○88864:   e59f1020    ldr r1, [pc, #32]   ; 888c <phase_5+0xb8>8868:   eb000140    bl  8d70 <strings_not_equal>886c:   e1a03000    mov r3, r08870:   e3530000    cmp r3, #08874:   0a000000    beq 887c <phase_5+0xa8>8878:   eb000220    bl  9100 <explode_bomb>887c:   e24bd004    sub sp, fp, #48880:   e8bd4800    pop {fp, lr}8884:   e12fff1e    bx  lr8888:   0008216c    .word   0x0008216c888c:   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, #48898:   e24dd048    sub sp, sp, #72 ; 0x48889c:   e50b0048    str r0, [fp, #-72]  ; 0xffffffb888a0:   e59f3234    ldr r3, [pc, #564]  ; 8adc <phase_6+0x24c>88a4:   e50b3010    str r3, [fp, #-16]88a8:   e24b3028    sub r3, fp, #40 ; 0x2888ac:   e51b0048    ldr r0, [fp, #-72]  ; 0xffffffb888b0:   e1a01003    mov r1, r388b4:   eb0000f0    bl  8c7c <read_six_numbers>

以上的指令的逻辑比较简单,是首先读入六个数字,并将其放入数组中,假设数组为a。

2:对这六个数的值进行判定

        88b8:   e3a03000    mov r3, #088bc:   e50b300c    str r3, [fp, #-12]88c0:   e51b200c    ldr r2, [fp, #-12]  ○1////////////////////////////////////88c4:   e3e03023    mvn r3, #35 ; 0x2388c8:   e1a02102    lsl r2, r2, #288cc:   e24b0004    sub r0, fp, #488d0:   e0802002    add r2, r0, r2   ○288d4:   e0823003    add r3, r2, r388d8:   e5933000    ldr r3, [r3]///////////////////////////////////88dc:   e2433001    sub r3, r3, #188e0:   e3530005    cmp r3, #5   ○388e4:   9a000000    bls 88ec <phase_6+0x5c>88e8:   eb000204    bl  9100 <explode_bomb>//////////////////////////////////88ec:   e51b300c    ldr r3, [fp, #-12]88f0:   e2833001    add r3, r3, #1   ○488f4:   e50b3008    str r3, [fp, #-8]88f8:   ea000013    b   894c <phase_6+0xbc>//////////////////////////////////88fc:   e51b200c    ldr r2, [fp, #-12]8900:   e3e03023    mvn r3, #35 ; 0x238904:   e1a02102    lsl r2, r2, #28908:   e24b1004    sub r1, fp, #4  ○6890c:   e0812002    add r2, r1, r2 8910:   e0823003    add r3, r2, r38914:   e5932000    ldr r2, [r3]//////////////////////////////////8918:   e51b1008    ldr r1, [fp, #-8]891c:   e3e03023    mvn r3, #35 ; 0x238920:   e1a01101    lsl r1, r1, #28924:   e24b0004    sub r0, fp, #4   ○78928:   e0801001    add r1, r0, r1892c:   e0813003    add r3, r1, r38930:   e5933000    ldr r3, [r3]/////////////////////////////////8934:   e1520003    cmp r2, r38938:   1a000000    bne 8940 <phase_6+0xb0> 893c:   eb0001ef    bl  9100 <explode_bomb>8940:   e51b3008    ldr r3, [fp, #-8]○88944:   e2833001    add r3, r3, #18948:   e50b3008    str r3, [fp, #-8]///////////////////////////////////894c:   e51b3008    ldr r3, [fp, #-8]8950:   e3530005    cmp r3, #5   ○58954:   daffffe8    ble 88fc <phase_6+0x6c>//////////////////////////////////8958:   e51b300c    ldr r3, [fp, #-12]895c:   e2833001    add r3, r3, #18960:   e50b300c    str r3, [fp, #-12]   ○98964:   e51b300c    ldr r3, [fp, #-12]8968:   e3530005    cmp r3, #5896c:   daffffd3    ble 88c0 <phase_6+0x30>8970:   e3a03000    mov r3, #08974:   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 ○18984:   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]  ○38998:   e51b3008    ldr r3, [fp, #-8]899c:   e2833001    add r3, r3, #189a0:   e50b3008    str r3, [fp, #-8]////////////////////////////////////////89a4:   e51b200c    ldr r2, [fp, #-12]89a8:   e3e03023    mvn r3, #35 ; 0x2389ac:   e1a02102    lsl r2, r2, #289b0:   e24b1004    sub r1, fp, #489b4:   e0812002    add r2, r1, r2  ○289b8:   e0823003    add r3, r2, r389bc:   e5932000    ldr r2, [r3]89c0:   e51b3008    ldr r3, [fp, #-8]89c4:   e1520003    cmp r2, r389c8:   caffffef    bgt 898c <phase_6+0xfc>////////////////////////////////////////////89cc:   e51b200c    ldr r2, [fp, #-12]89d0:   e3e0303b    mvn r3, #59 ; 0x3b89d4:   e1a02102    lsl r2, r2, #289d8:   e24b0004    sub r0, fp, #4  ○489dc:   e0802002    add r2, r0, r289e0:   e0823003    add r3, r2, r389e4:   e51b2010    ldr r2, [fp, #-16]89e8:   e5832000    str r2, [r3]///////////////////////////////////////////89ec:   e51b300c    ldr r3, [fp, #-12]89f0:   e2833001    add r3, r3, #189f4:   e50b300c    str r3, [fp, #-12]   ○589f8:   e51b300c    ldr r3, [fp, #-12]89fc:   e3530005    cmp r3, #58a00:   daffffdc    ble 8978 <phase_6+0xe8>///////////////////////////////////////////8a04:   e51b3040    ldr r3, [fp, #-64]  ; 0xffffffc08a08:   e50b3010    str r3, [fp, #-16]○98a0c:   e3a03001    mov r3, #18a10:   e50b300c    str r3, [fp, #-12]/////////////////////////////////////////8a14:   e51b200c    ldr r2, [fp, #-12]8a18:   e3e0303b    mvn r3, #59 ; 0x3b8a1c:   e1a02102    lsl r2, r2, #28a20:   e24b1004    sub r1, fp, #4  8a24:   e0812002    add r2, r1, r2○68a28:   e0823003    add r3, r2, r38a2c:   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 ; 0x3b8a40:   e1a02102    lsl r2, r2, #2○78a44:   e24b0004    sub r0, fp, #48a48:   e0802002    add r2, r0, r28a4c:   e0823003    add r3, r2, r38a50:   e5933000    ldr r3, [r3]8a54:   e50b3010    str r3, [fp, #-16]////////////////////////////////////8a58:   e51b300c    ldr r3, [fp, #-12]8a5c:   e2833001    add r3, r3, #18a60:   e50b300c    str r3, [fp, #-12] ○88a64:   e51b300c    ldr r3, [fp, #-12]8a68:   e3530005    cmp r3, #58a6c:   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, #08a78:   e5832008    str r2, [r3, #8]8a7c:   e3a03000    mov r3, #0  ○18a80:   e50b300c    str r3, [fp, #-12]8a84:   e51b3040    ldr r3, [fp, #-64]  ; 0xffffffc08a88:   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] ○28a9c:   e5933000    ldr r3, [r3]8aa0:   e1520003    cmp r2, r38aa4:   aa000000    bge 8aac <phase_6+0x21c>8aa8:   eb000194    bl  9100 <explode_bomb>//////////////////////////////////////////8aac:   e51b3010    ldr r3, [fp, #-16]8ab0:   e5933008    ldr r3, [r3, #8]  ○38ab4:   e50b3010    str r3, [fp, #-16]///////////////////////////////////////8ab8:   e51b300c    ldr r3, [fp, #-12]8abc:   e2833001    add r3, r3, #1   8ac0:   e50b300c    str r3, [fp, #-12] ○48ac4:   e51b300c    ldr r3, [fp, #-12]8ac8:   e3530004    cmp r3, #48acc:   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;elseexplode_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

二进制炸弹(arm)相关推荐

  1. 计算机系统二进制炸弹实验报告,二进制拿炸弹实验报告完整版.doc

    课程名称:计算机系统原理实验 实验课时:32课时 实验项目名称:BombLab二进制炸弹 实验材料:可执行文件bomb.源代码bomb.c.说明README 实验环境:Linux操作系统(安装虚拟机和 ...

  2. 计算机系统原理实验之BombLab二进制炸弹1、2关

    实验目的: 通过二进制炸弹实验,熟悉汇编语言,反汇编工具objdump以及gdb调试工具. 实验过程: 实验包里有三个文件,分别是二进制可执行文件bomb,C语言源程序文件bomb.c以及一个READ ...

  3. CSAPP实验二:二进制炸弹(Bomb Lab)

    本系列文章为中国科学技术大学计算机专业学科基础课<计算机系统>布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第二个实验--二进制炸弹( ...

  4. 二进制拆弹实验详解linux,拆解二进制炸弹

    拆解二进制炸弹 一.实验目的 1.理解C语言程序的机器级表示. 2.初步掌握GDB调试器的用法. 3.阅读C编译器生成的x86-64机器代码,理解不同控制结构生成的基本指令模式,过程的实现. 二. 实 ...

  5. CS:APP二进制炸弹phase2

    写在前面 在前文<CS:APP二进制炸弹phase1>中成功"破解"了phase_1,毕竟是第一个阶段,非常简单.本篇来破解第二阶段.let's go!!! 分析 反汇 ...

  6. 【计组】二进制炸弹bomblab Phase1-6

    实验目的 通过二进制炸弹实验,熟悉汇编语言 熟悉GDB调试工具 算法思路 编译环境 gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) GNU gdb (U ...

  7. 作业_二进制炸弹_手把手教学讲解

    简单的前言 最近的作业有个二进制炸弹问题,具体点说就是使用汇编语言完成一些小问题,形式比较有趣,一起看看吧. 题目描述 实验目的 通过对一个二进制可执行程序(称为"二进制炸弹")的 ...

  8. 计算机系统实验:二进制炸弹+缓冲区炸弹 (自我学习笔记)

    本来没想写个博客,结果得知还要验收,发现自己全忘了,那就趁着复习的功夫再捋一遍吧>-< 一.使用工具:IDA-pro 简单使用方式: 1.打开IDA,open需要反汇编的exe. 选则wi ...

  9. 哈工大 计算机系统 二进制炸弹实验报告

    实验报告 实 验(三) 题     目 Binary Bomb 二进制炸弹 专       业 计算机学院 学    号 班    级 学       生 指 导 教 师 实 验 地 点 实 验 日 ...

最新文章

  1. 使嵌入式系统调试更容易:有用的硬件和软件提示
  2. 利用CVE-2019-1040 - 结合RCE和Domain Admin的中继漏洞
  3. python爬酷狗音乐_良心推荐!一个Python高手必读的库,真香!
  4. mysql status关键字 数据表设计中慎重使用
  5. 带有第三方工具的Spring Boot Initilizr
  6. [Unity-24] Unity的四种载入场景的方法
  7. PASCAL VOC2012数据集下载地址
  8. 南琼考试系统APP服务器,南琼考试系统
  9. JAVA 如何反编译JAR文件
  10. 2019第五届美亚杯全国电子数据取证大赛团队赛wp
  11. Android美女拼图游戏
  12. 电脑云便签怎么在桌面日历月视图上新增便签记录事情?
  13. Xdebug中文文档-安装
  14. Scratch3.0创意编程(基础篇):第9课 大鱼吃小鱼
  15. stm32 cubemx 新建项目一直报错的问题终于解决了
  16. SCX-4521F一体机MAC驱动
  17. 引脚、GPIO、串口、端口的区别
  18. 北京邮电大学计算机网络课件,北京邮电大学计算机网络课件第一章:物理层.ppt...
  19. 超好用的图片管理软件:ImageRanger Mac版
  20. 我不曾忘记的初心-愿天堂没有代码

热门文章

  1. 微信吸粉技巧:“傻逼”的毅力
  2. 计算机专业面向的职业,职业面向及职业能力要求
  3. 新手如何实现自媒体盈利,我把自媒体变现的套路都总结出来
  4. 详述Deep Learning中的各种卷积(二)
  5. python matplotlib自定义colorbar颜色条-以及matplotlib中的内置色条
  6. 12_OSR模块和空间参考系
  7. 彻底卸载 Visual Studio 2019【完整版】
  8. 简析客户流失的原因及解决办法
  9. 腾讯云数据库产品介绍第四章-
  10. 航空票务中的月份和星期缩写