radareorg / radare2

UNIX-like reverse engineering framework and command-line toolset
https://www.radare.org/
GNU Lesser General Public License v3.0
20.39k stars 2.98k forks source link

Setting asm.cpu=cortex from inside r2 doesn't work as expected in some situations #7736

Closed JamesHagerman closed 7 years ago

JamesHagerman commented 7 years ago

I am disassembling an ARM, 16bit, Cortex binary. Zipped version of it: miniblink.zip

If I set asm.cpu=cortex from the command line, it works as expected. This issue is about what happens when that variable is set inside r2 once it's launched.

I can get r2 to correctly spit out a disassembly of this binary using the following commands. I've included the disassembly output as well. Effectively, this string of commands (as far as I know) is the aaa command expanded... but with asm.cpu being set after different analysis commands are run.

% r2 -a arm -b 16 miniblink.bin

[0x00000000]> aa;aav;aar;e asm.cpu=cortex;aac;aan
[x] Analyze all flags starting with sym. and entry0 (aa)
aav: Cannot find section at this address
[0x00000000]> pdf @0x1ac
/ (fcn) fcn.000001ac 56
|   fcn.000001ac ();
|              ; CALL XREF from 0x000001fa (fcn.000001f8)
|           0x000001ac      10b5           push {r4, lr}
|           0x000001ae      40f20260       movw r0, 0x602              ; 1538
|           0x000001b2      00f06af8       bl fcn.0000028a
|           0x000001b6      0022           movs r2, 0
|           0x000001b8      0223           movs r3, 2
|           0x000001ba      1146           mov r1, r2
|           0x000001bc      0948           ldr r0, [0x000001e4]        ; [0x1e4:4]=0x40020800
|           0x000001be      00f042f8       bl fcn.00000246
|           0x000001c2      094b           ldr r3, [0x000001ea]        ; [0x1e8:4]=0x40020810
|           0x000001c4      1b68           ldr r3, [r3]
|           0x000001c6      13f00203       ands r3, r3, 2
|       ,=< 0x000001ca      0ad1           bne 0x1e2
|       |   0x000001cc      074a           ldr r2, [0x000001ec]        ; [0x1ec:4]=0xe000ed08
|       |   0x000001ce      1360           str r3, [r2]
|       |   0x000001d0      074b           ldr r3, [0x000001f0]        ; [0x1f0:4]=0x1fff0000
|       |   0x000001d2      1b68           ldr r3, [r3]
|       |   0x000001d4      83f30888       msr msp, r3
|       |   0x000001d8      064b           ldr r3, [0x000001f4]        ; [0x1f4:4]=0x1fff0004
|       |   0x000001da      bde81040       pop.w {r4, lr}
|       |   0x000001de      1b68           ldr r3, [r3]
|       |   0x000001e0      1847           bx r3
\       `-> 0x000001e2      10bd           pop {r4, pc}
[0x00000000]>

However, the following does not work:

% r2 -a arm -b 16 miniblink.bin

[0x00000000]> aa;aav;aar;aac;e asm.cpu=cortex;aan
[x] Analyze all flags starting with sym. and entry0 (aa)
aav: Cannot find section at this address
[0x00000000]> pdf @0x1ac
/ (fcn) fcn.000001ac 42
|   fcn.000001ac ();
|              ; CALL XREF from 0x000001fa (fcn.000001f8)
|           0x000001ac      10b5           push {r4, lr}
|           0x000001ae      40f20260       movw r0, 0x602              ; 1538
|           0x000001b2      00f06af8       bl fcn.0000028a
|           0x000001b6      0022           movs r2, 0
|           0x000001b8      0223           movs r3, 2
|           0x000001ba      1146           mov r1, r2
|           0x000001bc      0948           ldr r0, [0x000001e4]        ; [0x1e4:4]=0x40020800
|           0x000001be      00f042f8       bl fcn.00000246
|           0x000001c2      094b           ldr r3, [0x000001ea]        ; [0x1e8:4]=0x40020810
|           0x000001c4      1b68           ldr r3, [r3]
|           0x000001c6      13f00203       ands r3, r3, 2
|       ,=< 0x000001ca      0ad1           bne 0x1e2
|       |   0x000001cc      074a           ldr r2, [0x000001ec]        ; [0x1ec:4]=0xe000ed08
|       |   0x000001ce      1360           str r3, [r2]
|       |   0x000001d0      074b           ldr r3, [0x000001f0]        ; [0x1f0:4]=0x1fff0000
|       |   0x000001d2      1b68           ldr r3, [r3]
\       |   0x000001d4      83f3           invalid
[0x00000000]>

The invalid opcode at the end of that disassembly makes me think that there is some dependency in the aac command that requires asm.cpu to be correct by that point.

I'm new to radare2 though. Let me know if this is just me not understanding what's going on!

radare commented 7 years ago

if you dont set asm.cpu BEFORE any analysis command what do you expect?

On 13 Jun 2017, at 20:54, James Hagerman notifications@github.com wrote:

I am disassembling an ARM, 16bit, Cortex binary. Zipped version of it: miniblink.zip https://github.com/radare/radare2/files/1072459/miniblink.zip If I set asm.cpu=cortex from the command line, it works as expected. This issue is about what happens when that variable is set inside r2 once it's launched.

I can get r2 to correctly spit out a disassembly of this binary using the following commands. I've included the disassembly output as well. Effectively, this string of commands (as far as I know) is the aaa command expanded... but with asm.cpu being set after different analysis commands are run.

% r2 -a arm -b 16 miniblink.bin

[0x00000000]> aa;aav;aar;e asm.cpu=cortex;aac;aan [x] Analyze all flags starting with sym. and entry0 (aa) aav: Cannot find section at this address [0x00000000]> pdf @0x1ac / (fcn) fcn.000001ac 56 | fcn.000001ac (); | ; CALL XREF from 0x000001fa (fcn.000001f8) | 0x000001ac 10b5 push {r4, lr} | 0x000001ae 40f20260 movw r0, 0x602 ; 1538 | 0x000001b2 00f06af8 bl fcn.0000028a | 0x000001b6 0022 movs r2, 0 | 0x000001b8 0223 movs r3, 2 | 0x000001ba 1146 mov r1, r2 | 0x000001bc 0948 ldr r0, [0x000001e4] ; [0x1e4:4]=0x40020800 | 0x000001be 00f042f8 bl fcn.00000246 | 0x000001c2 094b ldr r3, [0x000001ea] ; [0x1e8:4]=0x40020810 | 0x000001c4 1b68 ldr r3, [r3] | 0x000001c6 13f00203 ands r3, r3, 2 | ,=< 0x000001ca 0ad1 bne 0x1e2 | | 0x000001cc 074a ldr r2, [0x000001ec] ; [0x1ec:4]=0xe000ed08 | | 0x000001ce 1360 str r3, [r2] | | 0x000001d0 074b ldr r3, [0x000001f0] ; [0x1f0:4]=0x1fff0000 | | 0x000001d2 1b68 ldr r3, [r3] | | 0x000001d4 83f30888 msr msp, r3 | | 0x000001d8 064b ldr r3, [0x000001f4] ; [0x1f4:4]=0x1fff0004 | | 0x000001da bde81040 pop.w {r4, lr} | | 0x000001de 1b68 ldr r3, [r3] | | 0x000001e0 1847 bx r3 \ `-> 0x000001e2 10bd pop {r4, pc} [0x00000000]> However, the following does not work:

% r2 -a arm -b 16 miniblink.bin

[0x00000000]> aa;aav;aar;aac;e asm.cpu=cortex;aan [x] Analyze all flags starting with sym. and entry0 (aa) aav: Cannot find section at this address [0x00000000]> pdf @0x1ac / (fcn) fcn.000001ac 42 | fcn.000001ac (); | ; CALL XREF from 0x000001fa (fcn.000001f8) | 0x000001ac 10b5 push {r4, lr} | 0x000001ae 40f20260 movw r0, 0x602 ; 1538 | 0x000001b2 00f06af8 bl fcn.0000028a | 0x000001b6 0022 movs r2, 0 | 0x000001b8 0223 movs r3, 2 | 0x000001ba 1146 mov r1, r2 | 0x000001bc 0948 ldr r0, [0x000001e4] ; [0x1e4:4]=0x40020800 | 0x000001be 00f042f8 bl fcn.00000246 | 0x000001c2 094b ldr r3, [0x000001ea] ; [0x1e8:4]=0x40020810 | 0x000001c4 1b68 ldr r3, [r3] | 0x000001c6 13f00203 ands r3, r3, 2 | ,=< 0x000001ca 0ad1 bne 0x1e2 | | 0x000001cc 074a ldr r2, [0x000001ec] ; [0x1ec:4]=0xe000ed08 | | 0x000001ce 1360 str r3, [r2] | | 0x000001d0 074b ldr r3, [0x000001f0] ; [0x1f0:4]=0x1fff0000 | | 0x000001d2 1b68 ldr r3, [r3] \ | 0x000001d4 83f3 invalid [0x00000000]> The invalid opcode at the end of that disassembly makes me think that there is some dependency in the aac command that requires asm.cpu to be correct by that point.

I'm new to radare2 though. Let me know if this is just me not understanding what's going on!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/7736, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-ljD4JIZBZ2GzWjpTpyObK_SCpfsIks5sDtrjgaJpZM4N47Nm.

JamesHagerman commented 7 years ago

I would expect to see a more complete disassembly with just the invalid opcodes marked as such:

r2 -a arm -b 16 -e asm.cpu=cortex miniblink.bin
 -- Invert the block bytes using the 'I' key in visual mode
[0x00000000]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[ ] 
[aav: Cannot find section at this address
aav: Cannot find section at this address
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[ ] [*] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan))
[0x00000000]> e asm.cpu=v8
[0x00000000]> pdf @0x1ac
/ (fcn) fcn.000001ac 56
|   fcn.000001ac ();
|              ; CALL XREF from 0x000001fa (fcn.000001f8)
|           0x000001ac      10b5           push {r4, lr}
|           0x000001ae      40f20260       movw r0, 0x602              ; 1538
|           0x000001b2      00f06af8       bl fcn.0000028a
|           0x000001b6      0022           movs r2, 0
|           0x000001b8      0223           movs r3, 2
|           0x000001ba      1146           mov r1, r2
|           0x000001bc      0948           ldr r0, [0x000001e4]        ; [0x1e4:4]=0x40020800
|           0x000001be      00f042f8       bl fcn.00000246
|           0x000001c2      094b           ldr r3, [0x000001ea]        ; [0x1e8:4]=0x40020810
|           0x000001c4      1b68           ldr r3, [r3]
|           0x000001c6      13f00203       ands r3, r3, 2
|       ,=< 0x000001ca      0ad1           bne 0x1e2
|       |   0x000001cc      074a           ldr r2, [0x000001ec]        ; [0x1ec:4]=0xe000ed08
|       |   0x000001ce      1360           str r3, [r2]
|       |   0x000001d0      074b           ldr r3, [0x000001f0]        ; [0x1f0:4]=0x1fff0000
|       |   0x000001d2      1b68           ldr r3, [r3]
|       |   0x000001d4      83f30888       invalid
|       |   0x000001d8      064b           ldr r3, [0x000001f4]        ; [0x1f4:4]=0x1fff0004
|       |   0x000001da      bde81040       pop.w {r4, lr}
|       |   0x000001de      1b68           ldr r3, [r3]
|       |   0x000001e0      1847           bx r3
\       `-> 0x000001e2      10bd           pop {r4, pc}
[0x00000000]>

Note the invalid @ 0x1d4...

JamesHagerman commented 7 years ago

Shoot. Maybe this is an issue with capstone after all. It also stops disassembly when it hits an invalid code. I'll get back to you on this.

EDIT:

Okay I figured it out. radare2 stops decompiling because Capstone stops decompiling when it encounters a broken instruction.

However, radare2 could configure Capstone to "skip" the broken instruction as is described on this page: http://www.capstone-engine.org/skipdata.html

With Capstone set to skip, it spits out the following disassembly:

0x1ac:  push    {r4, lr}
0x1ae:  movw    r0, #0x602
0x1b2:  bl  #0x28a
0x1b6:  movs    r2, #0
0x1b8:  movs    r3, #2
0x1ba:  mov r1, r2
0x1bc:  ldr r0, [pc, #0x24]
0x1be:  bl  #0x246
0x1c2:  ldr r3, [pc, #0x24]
0x1c4:  ldr r3, [r3]
0x1c6:  ands    r3, r3, #2
0x1ca:  bne #0x1e2
0x1cc:  ldr r2, [pc, #0x1c]
0x1ce:  str r3, [r2]
0x1d0:  ldr r3, [pc, #0x1c]
0x1d2:  ldr r3, [r3]
0x1d4:  .byte   0x83, 0xf3
0x1d6:  ldrh    r0, [r1]
0x1d8:  ldr r3, [pc, #0x18]
0x1da:  pop.w   {r4, lr}
0x1de:  ldr r3, [r3]
0x1e0:  bx  r3
0x1e2:  pop {r4, pc}

Unfortunately, without know anything about that opcode, skipping is pretty arbitrary. Every line after the failed instruction (0x1d4) is just plain wrong because Capstone didn't jump far enough.

JamesHagerman commented 7 years ago

I'll close this for now. I'll just be more careful about what I'm disassembling.

radare commented 7 years ago

yeah the thumb disassembly can be improved a lot still, any hint or fix is welcome

On 14 Jun 2017, at 00:12, James Hagerman notifications@github.com wrote:

I'll close this for now. I'll just be more careful about what I'm disassembling.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/7736#issuecomment-308263992, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lqAnUXP5TzAeHfnF5xHEYv_gMPBXks5sDwlNgaJpZM4N47Nm.