1 2 3 4 5 6 7
| Daddy told me I should study arm. But I prefer to study my leg!
Download : http://pwnable.kr/bin/leg.c Download : http://pwnable.kr/bin/leg.asm
ssh leg@pwnable.kr -p2222 (pw:guest)
|
leg.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <stdio.h> #include <fcntl.h> int key1(){ asm("mov r3, pc\n"); } int key2(){ asm( "push {r6}\n" "add r6, pc, $1\n" "bx r6\n" ".code 16\n" "mov r3, pc\n" "add r3, $0x4\n" "push {r3}\n" "pop {pc}\n" ".code 32\n" "pop {r6}\n" ); } int key3(){ asm("mov r3, lr\n"); } int main(){ int key=0; printf("Daddy has very strong arm! : "); scanf("%d", &key); if( (key1()+key2()+key3()) == key ){ printf("Congratz!\n"); int fd = open("flag", O_RDONLY); char buf[100]; int r = read(fd, buf, 100); write(0, buf, r); } else{ printf("I have strong leg :P\n"); } return 0; }
|
arm是r0存放函数返回值,pc寄存器指向当前运行指令的后两条指令的地址;
如下是函数key1,
1 2 3 4 5 6 7 8 9 10
| (gdb) disass key1 Dump of assembler code for function key1: 0x00008cd4 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008cd8 <+4>: add r11, sp, #0 0x00008cdc <+8>: mov r3, pc 0x00008ce0 <+12>: mov r0, r3 0x00008ce4 <+16>: sub sp, r11, #0 0x00008ce8 <+20>: pop {r11} ; (ldr r11, [sp], #4) 0x00008cec <+24>: bx lr End of assembler dump.
|
r0 = r3 = pc = 0x00008ce4
如下是函数key2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Dump of assembler code for function key2: 0x00008cf0 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008cf4 <+4>: add r11, sp, #0 0x00008cf8 <+8>: push {r6} ; (str r6, [sp, #-4]!) 0x00008cfc <+12>: add r6, pc, #1 0x00008d00 <+16>: bx r6 0x00008d04 <+20>: mov r3, pc 0x00008d06 <+22>: adds r3, #4 0x00008d08 <+24>: push {r3} 0x00008d0a <+26>: pop {pc} 0x00008d0c <+28>: pop {r6} ; (ldr r6, [sp], #4) 0x00008d10 <+32>: mov r0, r3 0x00008d14 <+36>: sub sp, r11, #0 0x00008d18 <+40>: pop {r11} ; (ldr r11, [sp], #4) 0x00008d1c <+44>: bx lr End of assembler dump.
|
r0= r3 = 0x00008d08 + 4 = 0x00008d0c
此处需要说明一下,bx指令的地址,如果最低位是1,说明应当切换到thumb模式。可以看到从0x00008d04后,每条指令的长度都变成了两个字节
如下是key3
1 2 3 4 5 6 7 8 9
| Dump of assembler code for function key3: 0x00008d20 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008d24 <+4>: add r11, sp, #0 0x00008d28 <+8>: mov r3, lr 0x00008d2c <+12>: mov r0, r3 0x00008d30 <+16>: sub sp, r11, #0 0x00008d34 <+20>: pop {r11} ; (ldr r11, [sp], #4) 0x00008d38 <+24>: bx lr End of assembler dump.
|
r0 = r3 = lr = 0x00008d80
lr寄存器保存了函数的返回地址,也就是函数main中调用函数key3处的后一条地址。
因此:key = 0x00008ce4 + 0x00008d0c + 0x00008d80 = 0x0001A770 = 108400
登录上去,看打印出来的log可能是绑定了qemu虚拟机。
1 2 3 4
| / $ ./leg Daddy has very strong arm! : 108400 Congratz! My daddy has a lot of ARMv5te muscle!
|
涉及的知识点
- arm函数特点
- arm的thumb和arm模式切换