Arm register usage

https://dreamhack.io/wargame/challenges/861

이 문제를 풀면서 겪은 문제를 다룬다.

이 문제에서 가젯들을 제공해주는데

Python
                             *************************************************************
                             *                           FUNCTION                          
                             *************************************************************
                             undefined  gadget2 ()
             undefined         r0:1           <RETURN>
                             gadget2                                         XREF[1]:     Entry Point (*)   
        000105ac 00  48  2d  e9    stmdb      sp!,{r11 ,lr}
        000105b0 04  b0  8d  e2    add        r11 ,sp,#0x4
        000105b4 10  30  9f  e5    ldr        r3,[DAT_000105cc ]                               = 0002103Ch
        000105b8 00  30  93  e5    ldr        r3=>s_/bin/sh_000106a4 ,[r3,#0x0 ]=>sh            = "/bin/sh"
                                                                                             = 000106A4h
        000105bc 03  00  a0  e1    cpy        r0=>s_/bin/sh_000106a4 ,r3                       = "/bin/sh"
        000105c0 8a  ff  ff  eb    bl         <EXTERNAL>::puts                                 int puts(char * __s)
        000105c4 00  00  a0  e1    cpy        r0,r0
        000105c8 00  88  bd  e8    ldmia      sp!,{r11 ,pc}

여기서 보면 r3 레지스터에 “/bin/sh” 이라는 문자열이 저장된채로

puts 함수에 들어간다. 그래서 나는 당연히 함수에서 나올때도 “/bin/sh” 문자열이 보존된채로 나올 것이라고 생각하고 익스를 짜서 많이 고생했다.

그런데 …

Python
Dump of assembler code for function gadget2:
   0x000105ac <+0>:     push    {r11, lr}
   0x000105b0 <+4>:     add     r11, sp, #4
   0x000105b4 <+8>:     ldr     r3, [pc, #16]   ; 0x105cc <gadget2+32>
   0x000105b8 <+12>:    ldr     r3, [r3]
   0x000105bc <+16>:    mov     r0, r3
   0x000105c0 <+20>:    bl      0x103f0 <puts@plt>
=> 0x000105c4 <+24>:    nop                     ; (mov r0, r0)
   0x000105c8 <+28>:    pop     {r11, pc}
   0x000105cc <+32>:    andeq   r1, r2, r12, lsr r0
End of assembler dump.
(gdb) reg
Undefined command: "reg".  Try "help".
(gdb) info reg
r0             0x8                 8
r1             0x0                 0
r2             0x409c8794          1084000148
r3             0x1                 1
r4             0x409c7000          1083994112
r5             0x1                 1
r6             0x20f14             134932
r7             0x4083c058          1082376280

보시다시피 함수 이후에 r3 0x1 1 으로 완전 깔끔히 없어져서 나온다. 이는arm에서 r0 ~ r3는 “caller-saved” 레지스터이기 때문이다.

따라서 이런 실수를 다신 하지 말자!