前言
这是一道考察arm汇编的题目,很简单。
分析
还是先贴出源码: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
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;
}
1 | (gdb) disass main |
获取flag的关键就是求得三个key
函数的返回值的和。其实只要学过arm汇编就迎刃而解了,唯一要注意的是arm中PC寄存器指向的是当前指令下面的第二条指令。而x86下PC指向的是当前指令。
通过反汇编代码,可以发现1
2
3
4key1 = 0x00008ce4;
key2 = 0x00008d08;
key3 = 0x00008d80+4=0x00008d84;
key = key1+key2+key3 = 108400;
1 | / $ ./leg |
总结
做这一题其实我复习了一下arm汇编,有的指令和寄存器还是不太清楚,以后找时间总结一下arm汇编并记录下来。