实验内容:修改二进制可重定位目标文件“phase1.o”中相关节的内容(注意不允许修改.text节和重定位节的内容),使其与main.o模块如下链接后运行时输出目标字符串“123456789”
gcc -no-pie -o linkbomb main.o phase1.o
./linkbomb
目标字符串
实验步骤:
1. 使用objdump工具获得目标文件的汇编代码,使用readelf工具获得其重定位记录。
2.结合汇编代码和重定位信息,推断目标文件的汇编代码中各函数的功能作用,定位出其中负责输出的函数。
3.构造调用输出函数的指令代码。
4.使用构造的调用输出函数的指令代码,替换目标文件中的do_phase过程中的nop指令,实现目标字符串的输出。
实验验证:
1.查看反汇编代码
objdump -d phase1.o > phase1.s
cat phase1.s
00000028 <do_phase>:
28: 55 push %ebp
29: 89 e5 mov %esp,%ebp
2b: 83 ec 28 sub $0x28,%esp
2e: c7 45 e6 47 43 5a 56 movl $0x565a4347,-0x1a(%ebp)
35: c7 45 ea 49 50 48 58 movl $0x58485049,-0x16(%ebp)
3c: 66 c7 45 ee 42 00 movw $0x42,-0x12(%ebp)
42: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
49: e9 e0 00 00 00 jmp 12e <do_phase+0x106>
4e: 8d 55 e6 lea -0x1a(%ebp),%edx
51: 8b 45 f0 mov -0x10(%ebp),%eax
54: 01 d0 add %edx,%eax
56: 0f b6 00 movzbl (%eax),%eax
59: 88 45 f7 mov %al,-0x9(%ebp)
5c: 0f be 45 f7 movsbl -0x9(%ebp),%eax
60: 83 e8 41 sub $0x41,%eax
63: 83 f8 19 cmp $0x19,%eax
66: 0f 87 b0 00 00 00 ja 11c <do_phase+0xf4>
6c: 8b 04 85 04 00 00 00 mov 0x4(,%eax,4),%eax
73: ff e0 jmp *%eax
75: c6 45 f7 56 movb $0x56,-0x9(%ebp)
79: e9 9e 00 00 00 jmp 11c <do_phase+0xf4>
7e: c6 45 f7 39 movb $0x39,-0x9(%ebp)
82: e9 95 00 00 00 jmp 11c <do_phase+0xf4>
87: c6 45 f7 6e movb $0x6e,-0x9(%ebp)
8b: e9 8c 00 00 00 jmp 11c <do_phase+0xf4>
90: c6 45 f7 40 movb $0x40,-0x9(%ebp)
94: e9 83 00 00 00 jmp 11c <do_phase+0xf4>
99: c6 45 f7 78 movb $0x78,-0x9(%ebp)
9d: eb 7d jmp 11c <do_phase+0xf4>
9f: c6 45 f7 34 movb $0x34,-0x9(%ebp)
a3: eb 77 jmp 11c <do_phase+0xf4>
a5: c6 45 f7 3f movb $0x3f,-0x9(%ebp)
a9: eb 71 jmp 11c <do_phase+0xf4>
ab: c6 45 f7 76 movb $0x76,-0x9(%ebp)
af: eb 6b jmp 11c <do_phase+0xf4>
b1: c6 45 f7 49 movb $0x49,-0x9(%ebp)
b5: eb 65 jmp 11c <do_phase+0xf4>
b7: c6 45 f7 5b movb $0x5b,-0x9(%ebp)
bb: eb 5f jmp 11c <do_phase+0xf4>
bd: c6 45 f7 6b movb $0x6b,-0x9(%ebp)
c1: eb 59 jmp 11c <do_phase+0xf4>
c3: c6 45 f7 6b movb $0x6b,-0x9(%ebp)
c7: eb 53 jmp 11c <do_phase+0xf4>
c9: c6 45 f7 30 movb $0x30,-0x9(%ebp)
cd: eb 4d jmp 11c <do_phase+0xf4>
cf: c6 45 f7 65 movb $0x65,-0x9(%ebp)
d3: eb 47 jmp 11c <do_phase+0xf4>
d5: c6 45 f7 67 movb $0x67,-0x9(%ebp)
d9: eb 41 jmp 11c <do_phase+0xf4>
db: c6 45 f7 5a movb $0x5a,-0x9(%ebp)
df: eb 3b jmp 11c <do_phase+0xf4>
e1: c6 45 f7 32 movb $0x32,-0x9(%ebp)
e5: eb 35 jmp 11c <do_phase+0xf4>
e7: c6 45 f7 38 movb $0x38,-0x9(%ebp)
eb: eb 2f jmp 11c <do_phase+0xf4>
ed: c6 45 f7 77 movb $0x77,-0x9(%ebp)
f1: eb 29 jmp 11c <do_phase+0xf4>
f3: c6 45 f7 3f movb $0x3f,-0x9(%ebp)
f7: eb 23 jmp 11c <do_phase+0xf4>
f9: c6 45 f7 37 movb $0x37,-0x9(%ebp)
fd: eb 1d jmp 11c <do_phase+0xf4>
ff: c6 45 f7 33 movb $0x33,-0x9(%ebp)
103: eb 17 jmp 11c <do_phase+0xf4>
105: c6 45 f7 35 movb $0x35,-0x9(%ebp)
109: eb 11 jmp 11c <do_phase+0xf4>
10b: c6 45 f7 59 movb $0x59,-0x9(%ebp)
10f: eb 0b jmp 11c <do_phase+0xf4>
111: c6 45 f7 31 movb $0x31,-0x9(%ebp)
115: eb 05 jmp 11c <do_phase+0xf4>
117: c6 45 f7 36 movb $0x36,-0x9(%ebp)
11b: 90 nop
11c: 8d 55 dc lea -0x24(%ebp),%edx
11f: 8b 45 f0 mov -0x10(%ebp),%eax
122: 01 c2 add %eax,%edx
124: 0f b6 45 f7 movzbl -0x9(%ebp),%eax
128: 88 02 mov %al,(%edx)
12a: 83 45 f0 01 addl $0x1,-0x10(%ebp)
12e: 8b 45 f0 mov -0x10(%ebp),%eax
131: 83 f8 08 cmp $0x8,%eax
134: 0f 86 14 ff ff ff jbe 4e <do_phase+0x26>
13a: 8d 55 dc lea -0x24(%ebp),%edx
13d: 8b 45 f0 mov -0x10(%ebp),%eax
140: 01 d0 add %edx,%eax
142: c6 00 00 movb $0x0,(%eax)
145: 83 ec 0c sub $0xc,%esp
148: 8d 45 dc lea -0x24(%ebp),%eax
14b: 50 push %eax
14c: e8 fc ff ff ff call 14d <do_phase+0x125>
151: 83 c4 10 add $0x10,%esp
154: 90 nop
155: c9 leave
156: c3 ret
类似一个9层循环,思路如下
2.修改跳转表(因为不允许修改.text节和重定位节),存放在.rodata节。
readelf -S phase1.o
在这,我们可以看到.rodata节的偏移量为2a8, 然后我们再寻找跳转表相对.rodata的偏移量。
所以跳转表的位置为 2a8+0x4=2ac
3.修改跳转表
hexedit phase1.o
以0✖56为例,它在地址为2ac+4*(56-41)=300,我们找到300
可以看到它的绝对跳转地址为9F ,我们把它改为0×34的绝对地址也是9F,其他的修改方法也是如此。