6.2.3 re CodegateCTF2017 angrybird
题目解析
$ file angrybird_org
angrybird: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=089c3a14bcd7ffb08e94645cea46f1162b171445, stripped$ ./angrybird_org
$[0x00400600]> pd 60 @ main
/ (fcn) main 18555
| main ();
| : ; DATA XREF from 0x0040061d (entry0)
| : 0x00400761 55 push rbp
| : 0x00400762 4889e5 mov rbp, rsp
| : 0x00400765 4883c480 add rsp, 0xffffffffffffff80
| : 0x00400769 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=-1 ; '(' ; 40
| : 0x00400772 488945f8 mov qword [local_8h], rax
| : 0x00400776 31c0 xor eax, eax ; 将 eax 置 0
| : 0x00400778 83f800 cmp eax, 0 ; 比较 eax 和 0
| `=< 0x0040077b 0f845ffeffff je sym.imp.exit ; eax == 0 时退出,所以需要将 je 换成 jne,或者把上一行的 0 换成 1
| 0x00400781 48c745901860. mov qword [local_70h], reloc.strncmp_24 ; 0x606018
| 0x00400789 48c745982060. mov qword [local_68h], reloc.puts_32 ; 0x606020
| 0x00400791 48c745a02860. mov qword [local_60h], reloc.__stack_chk_fail_40 ; 0x606028
| 0x00400799 48c745a83860. mov qword [local_58h], reloc.__libc_start_main_56 ; 0x606038
| 0x004007a1 b800000000 mov eax, 0
| 0x004007a6 e84bffffff call sub.you_should_return_21_not_1_:__6f6 ; 该函数中需要返回 21
| 0x004007ab 89458c mov dword [local_74h], eax ; [local_74] = 21
| 0x004007ae b800000000 mov eax, 0
| 0x004007b3 e854ffffff call sub.stack_check_70c ; 栈检查函数,直接 nop 掉,或者进入函数修改逻辑
| 0x004007b8 b800000000 mov eax, 0
| 0x004007bd e868ffffff call sub.hello_72a
| 0x004007c2 488b15a75820. mov rdx, qword [obj.stdin] ; [0x606070:8]=0 ; 从标准输入读入
| 0x004007c9 8b4d8c mov ecx, dword [local_74h]
| 0x004007cc 488d45b0 lea rax, [local_50h]
| 0x004007d0 89ce mov esi, ecx ; esi = 21
| 0x004007d2 4889c7 mov rdi, rax
| 0x004007d5 e8f6fdffff call sym.imp.fgets ; char *fgets(char *s, int size, FILE *stream) ; patch 成功后就能调用 fgets
| 0x004007da 0fb655b0 movzx edx, byte [local_50h] ; 读入的第一个字符
| 0x004007de 0fb645b1 movzx eax, byte [local_4fh] ; 读入的第二个字符
| 0x004007e2 31d0 xor eax, edx
| 0x004007e4 8845d0 mov byte [local_30h], al
| 0x004007e7 0fb645d0 movzx eax, byte [local_30h]
| 0x004007eb 3c0f cmp al, 0xf ; 15 ; 对处理后的输入字符做判断
| ,=< 0x004007ed 7f14 jg 0x400803 ; 若不满足条件,跳转失败,程序退出
| | 0x004007ef bf94504000 mov edi, str.melong ; 0x405094 ; "melong"
| | 0x004007f4 e897fdffff call sym.imp.puts ; int puts(const char *s)
| | 0x004007f9 bf01000000 mov edi, 1
| | 0x004007fe e8ddfdffff call sym.imp.exit ; void exit(int status)
| | ; JMP XREF from 0x004007ed (main)
| `-> 0x00400803 0fb655b0 movzx edx, byte [local_50h] ; 第二轮运算
| 0x00400807 0fb645b1 movzx eax, byte [local_4fh]
| 0x0040080b 21d0 and eax, edx
| 0x0040080d 8845d0 mov byte [local_30h], al
| 0x00400810 0fb645d0 movzx eax, byte [local_30h]
| 0x00400814 3c50 cmp al, 0x50 ; 'P' ; 80
| ,=< 0x00400816 7e14 jle 0x40082c
| | 0x00400818 bf94504000 mov edi, str.melong ; 0x405094 ; "melong"
| | 0x0040081d e86efdffff call sym.imp.puts ; int puts(const char *s)
| | 0x00400822 bf01000000 mov edi, 1
| | 0x00400827 e8b4fdffff call sym.imp.exit ; void exit(int status)
| | ; JMP XREF from 0x00400816 (main)
| `-> 0x0040082c c645d000 mov byte [local_30h], 0 ; 第三轮运算
| 0x00400830 0fb645d0 movzx eax, byte [local_30h]
| 0x00400834 3c01 cmp al, 1 ; 1
| ,=< 0x00400836 7e14 jle 0x40084c
| | 0x00400838 bf94504000 mov edi, str.melong ; 0x405094 ; "melong"
| | 0x0040083d e84efdffff call sym.imp.puts ; int puts(const char *s)
| | 0x00400842 bf01000000 mov edi, 1
| | 0x00400847 e894fdffff call sym.imp.exit ; void exit(int status)
| | ; JMP XREF from 0x00400836 (main)
| `-> 0x0040084c 0fb655c2 movzx edx, byte [local_3eh] ; 第 n 轮运算
| 0x00400850 0fb645b1 movzx eax, byte [local_4fh]
| 0x00400854 21d0 and eax, edx
| 0x00400856 8845d0 mov byte [local_30h], al
| 0x00400859 0fb645d0 movzx eax, byte [local_30h]
参考资料
Last updated