实验三:逆向工程实验 1.理解程序(控制语句、函数、返回值、堆栈结构)是如何运行的 2.掌握GDB调试工具 3.掌握objdump反汇编工具
实验介绍: 本实验设计为一个黑客拆解二进制炸弹的游戏。我们仅给黑客(同学)提供一个二进制可执行文件bomb_64和主函数所在的源程序bomb.c,不提供每个关卡的源代码。程序运行中有6个关卡(6个phase),每个关卡需要用户输入正确的字符串或数字才能通关,否则会引爆炸弹(打印出一条错误信息,并导致评分下降)! 要求同学运用GDB调试工具和objdump反汇编工具,通过分析汇编代码,找到在每个phase程序段中,引导程序跳转到“explode_bomb”程序段的地方,并分析其成功跳转的条件,以此为突破口寻找应该在命令行输入何种字符串来通关。
实验说明
•6个关卡,难度随关卡升级而提升; •通过解读汇编代码来推断其对应的函数结构(推断过程不唯一),某些关卡答案不唯一; •尽力而为,能通几关就几关。 •提示: ①第一关(知识点:string,函数调用,栈) ②第二关(知识点:循环语句,数组) ③第三关(知识点: switch语句) ④第四关(知识点:递归) ⑤第五关(知识点:字串变换,ascii转换,寻址) ⑥第六关(知识点:寻址)
(第1-5关,各15分。第6关10分。实验总结15分。)
实验步骤
1.输入反汇编命令查看汇编代码(保存在1.txt文件中) $ objdump -d bomb_64 > 1.txt 2.首先找到main函数,发现它调用了从phase1到phase6这六个函数。再找到phase1,代码如下:(举例分析) 0000000000400e70 <phase_1>: 400e70: 48 83 ec 08 sub $0x8,%rsp 400e74: be f8 1a 40 00 mov $0x401af8,%esi 400e79: e8 bf 03 00 00 callq 40123d <strings_not_equal> 400e7e: 85 c0 test %eax,%eax 400e80: 74 05 je 400e87 <phase_1+0x17> 400e82: e8 b6 07 00 00 callq 40163d <explode_bomb> 400e87: 48 83 c4 08 add $0x8,%rsp 400e8b: c3 retq
实验过程及内容: 当前用户可能对bomb文件没有执行权限,建议先用ls查看文件权限,若没有执行权限,请用chmod +x bomb命令增加当前用户对bomb文件的执行权限。
注2: 若用命令./bomb执行该文件提示no such file时,请先用 su szu 切换到szu账户,然后输入命令sudo apt-get install lib32z1,等待下载安装完毕即可。
PHASE 1:
分析对 phase_1 函数对应的 Pseudo-code:
void phase_1(const char *str) { if (!string_not_equal(“…..”, str) == 1) { explode_bomb(); } }
容易猜到我们应该找出 "...."中的值。
故,确认了PHASE1中进行了字符串比较操作,显示数据后发现相关内容。 0x401af8 "Science isn't about why, it's about why not?"
故正确答案为: Science isn't about why, it's about why not?
PHASE2:分析代码可知: 0000000000401743 <read_six_numbers>: read_six_numbers(): ;; char *enteredString ;; int array[6] 401743: 48 83 ec 18 sub $0x18,%rsp 401747: 48 89 f2 mov %rsi,%rdx 40174a: 48 8d 4e 04 lea 0x4(%rsi),%rcx 40174e: 48 8d 46 14 lea 0x14(%rsi),%rax ; $(rsp+8) := 0x14 + $rsp 401752: 48 89 44 24 08 mov %rax,0x8(%rsp) ; 401757: 48 8d 46 10 lea 0x10(%rsi),%rax 40175b: 48 89 04 24 mov %rax,(%rsp) 40175f: 4c 8d 4e 0c lea 0xc(%rsi),%r9 401763: 4c 8d 46 08 lea 0x8(%rsi),%r8 401767: be b2 1e 40 00 mov $0x401eb2,%esi 40176c: b8 00 00 00 00 mov $0x0,%eax ;; int *var1 = &arr[0]; ;; int *var2 = &arr[1]; ;; int *var3 = &arr[2]; ;; int *var4 = &arr[3]; ;; int *var5 = &arr[4]; ;; int *var6 = &arr[5]; ;; int ret = sscanf (str, "%d %d %d %d %d %d", var1, var2, var3, ...); 401771: e8 3a f3 ff ff callq 400ab0 <__isoc99_sscanf@plt> 401776: 83 f8 05 cmp $0x5,%eax ;; if (ret != 5) explode_bomb(); /*No-Exit*/ 401779: 7f 05 jg 401780 <read_six_numbers+0x3d> 40177b: e8 bd fe ff ff callq 40163d <explode_bomb> 401780: 48 83 c4 18 add $0x18,%rsp ;; return 5; 401784: c3 retq
可知read_six_numbers函数实际上就是
Phase_2 这一方法则是
循环判断读入的数字是否为 arr[x] == (arr[x+3] >> 32) 即判断是否符合下列格式 X Y Z X Y Z 举例一组正确答案: 1 2 3 1 2 3
PHASE 3:0000000000400ef9 <phase_3>: phase_3(): 400ef9: 48 83 ec 18 sub $0x18,%rsp 400efd: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx 400f02: 48 8d 54 24 0c lea 0xc(%rsp),%rdx 400f07: be be 1e 40 00 mov $0x401ebe,%esi 400f0c: b8 00 00 00 00 mov $0x0,%eax ;; if( scanf ("%d %d", &var1, &var2) <= 1) explode_bomb(); 400f11: e8 9a fb ff ff callq 400ab0 <__isoc99_sscanf@plt> 400f16: 83 f8 01 cmp $0x1,%eax 400f19: 7f 05 jg 400f20 <phase_3+0x27> 400f1b: e8 1d 07 00 00 callq 40163d <explode_bomb> ;; switch (var1) { 400f20: 83 7c 24 0c 07 cmpl $0x7,0xc(%rsp) 400f25: 77 3c ja 400f63 <phase_3+0x6a> 400f27: 8b 44 24 0c mov 0xc(%rsp),%eax 400f2b: ff 24 c5 60 1b 40 00 jmpq *0x401b60(,%rax,8) ;; --------- below is a jump table ---------- ;; case 1 : tmp = 0x217; break; ;; case 2 : tmp = 0xd6; break; ;; case 3 : tmp = 0x153; break; ;; case 4 : tmp = 0x77; break; ;; case 5 : tmp = 0x160; break; ;; case 6 : tmp = 0x397; break; ;; case 7 : tmp = 0x19c; break; 400f32: b8 17 02 00 00 mov $0x217,%eax 400f37: eb 3b jmp 400f74 <phase_3+0x7b> 400f39: b8 d6 00 00 00 mov $0xd6,%eax 400f3e: eb 34 jmp 400f74 <phase_3+0x7b> 400f40: b8 53 01 00 00 |
拆炸弹问题 - CS项目 - 计算机系统小实验
最新推荐文章于 2025-05-21 01:40:29 发布