NJU ICS4 Linklab

NJU ICS4 Linklab

mooc上的好像是阉割版,作为一个被pwn噶过腰子的男人(bu shi),怎么能放过这种hack性质的lab,就去找了貌似是完整的lab:)

链接:https://pan.baidu.com/s/1_tPhDGhKaF4HZ94oayqnMw
提取码:fbex

实验文件都是x86-32的

阶段 1:静态数据对象与 ELF 数据节
阶段 2:指令与 ELF 代码节
阶段 3:符号解析
阶段 4:switch 语句与重定位
阶段 5:可重定位目标文件
阶段 6:位置无关代码(Position-Independent Code,PIC)

phase1

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main) [1]> gcc -m32 -no-pie -o linkbomb main.o phase1.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
ddURHzFnm2mcxbehqVcVufpd68LdEePs lYPCnZfPLLbMLzV3iM1A97QVLg7j8zcmDlD0clCtKV0kgLRshaBQ3kCaGG YMbr9ELE31xt2fau4zX7bEMCVf qXOdnQ igVJcDsac1d9N7kSla5VLXAKDtjxAoNjW2tonwDzyASqLn5JKSf32EqapXP83B03NmDqUx
 grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> objdump -d phase1.o

phase1.o: file format elf32-i386


Disassembly of section .text:

00000000 <do_phase>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 08 sub $0x8,%esp
6: b8 9a 00 00 00 mov $0x9a,%eax
b: 83 ec 0c sub $0xc,%esp
e: 50 push %eax
f: e8 fc ff ff ff call 10 <do_phase+0x10>
14: 83 c4 10 add $0x10,%esp
17: 90 nop
18: c9 leave
19: c3 ret

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase1.o

Relocation section '.rel.text' at offset 0x354 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000007 00000301 R_386_32 00000000 .data
00000010 00000e02 R_386_PC32 00000000 puts

.rel.text给text做重定位,offset 10处为puts,所以0x9a处的数据压栈做puts参数,这里猜测就是.data的偏移了

image-20230506171613189

直接改掉

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase1.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
grxer

phase2

00000061 <kfSvKnbh>:
61: 55 push %ebp
62: 89 e5 mov %esp,%ebp
64: 83 ec 08 sub $0x8,%esp
67: 83 ec 08 sub $0x8,%esp
6a: 68 02 00 00 00 push $0x2
6f: ff 75 08 push 0x8(%ebp)
72: e8 fc ff ff ff call 73 <kfSvKnbh+0x12>
77: 83 c4 10 add $0x10,%esp
7a: 85 c0 test %eax,%eax
7c: 75 10 jne 8e <kfSvKnbh+0x2d>
7e: 83 ec 0c sub $0xc,%esp
81: ff 75 0c push 0xc(%ebp)
84: e8 fc ff ff ff call 85 <kfSvKnbh+0x24>
89: 83 c4 10 add $0x10,%esp
8c: eb 01 jmp 8f <kfSvKnbh+0x2e>
8e: 90 nop
8f: c9 leave
90: c3 ret
00000091 <do_phase>:
91: 55 push %ebp
92: 89 e5 mov %esp,%ebp
94: 90 nop
95: 90 nop
96: 90 nop
97: 90 nop
98: 90 nop
...一堆nop
d5: 5d pop %ebp
d6: c3 ret
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase1.ogrxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase2.o

Relocation section '.rel.text' at offset 0x308 contains 4 entries:
Offset Info Type Sym.Value Sym. Name
00000035 00000c02 R_386_PC32 00000000 strlen
0000006b 00000501 R_386_32 00000000 .rodata
00000073 00000d02 R_386_PC32 00000000 strcmp
00000085 00000e02 R_386_PC32 00000000 puts

Relocation section '.rel.text' at offset 0x354 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000007 00000301 R_386_32 00000000 .data
00000010 00000e02 R_386_PC32 00000000 puts

do_phase里的都是nop,肯定要利用puts函数来输出,他的重定位信息只有在00000085有,所以我们可以在do_phase里布置好栈帧,然后e9 jmp相对跳转到这个puts就可以输出

先布置栈帧把

sub esp,0x30
mov dword ptr [ebp-0x10],72h
mov dword ptr [ebp-0x14],65787267h
lea eax, [ebp-0x18]
push eax

image-20230506223216046

用ida patch了一下,接下来就是jmp到84

**intel手册 64-ia-32-architectures-software-developer-instruction-set-reference-manual-第2卷 **

image-20230506221626593

为什么没有选择 相对地址的e8 call是因为如果是e8 call过去会把返回地址先push栈里,会把call puts的参数给破环掉

image-20230506213529559

我们只能自己做重定位,call指令布置在a9处,占5个字节(一字节的操作码,四字节的偏移),下一条指令在ae处,所以偏移为84-ae即FFFF FFD6

所以字节码为e9 d6 ff ff ff,用010改下

image-20230506223052595

00000091 <do_phase>:
91: 55 push %ebp
92: 89 e5 mov %esp,%ebp
94: 83 ec 30 sub $0x30,%esp
97: c7 45 f0 72 00 00 00 movl $0x72,-0x10(%ebp)
9e: c7 45 ec 67 72 78 65 movl $0x65787267,-0x14(%ebp)
a5: 8d 45 ec lea -0x14(%ebp),%eax
a8: 50 push %eax
a9: e9 d6 ff ff ff jmp 84 <kfSvKnbh+0x23>

kfSvKnbh里的 leave ret会帮我们平栈后返回到main里调用do_phase的下一条指令处

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase2.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
grxer

phase3

gcc -m32 -no-pie -o linkbomb main.o phase3.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb

什么也没输出

看下汇编

080491c6 <do_phase>:
80491c6: 55 push %ebp
80491c7: 89 e5 mov %esp,%ebp
80491c9: 83 ec 18 sub $0x18,%esp
80491cc: c7 45 ea 79 7a 67 69 movl $0x69677a79,-0x16(%ebp);从这里开始就是一种到 80491da都是在赋值给ebp-0x16处的局部变量cookie
80491d3: c7 45 ee 75 68 6e 62 movl $0x626e6875,-0x12(%ebp)
80491da: 66 c7 45 f2 65 00 movw $0x65,-0xe(%ebp);赋值cookie结束
80491e0: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) ;ebp-c这个地方存的就是计数器
80491e7: eb 28 jmp 8049211 <do_phase+0x4b>

80491e9: 8d 55 ea lea -0x16(%ebp),%edx
80491ec: 8b 45 f4 mov -0xc(%ebp),%eax
80491ef: 01 d0 add %edx,%eax
80491f1: 0f b6 00 movzbl (%eax),%eax;拿出cookie[计数器]里的值
80491f4: 0f b6 c0 movzbl %al,%eax
80491f7: 0f b6 80 60 c0 04 08 movzbl 0x804c060(%eax),%eax;0x804c060处是一个叫做NQqPQyqUth的变量符号,所以eax就是NQqPQyqUth+cookie[计数器]地址里的值
80491fe: 0f be c0 movsbl %al,%eax
8049201: 83 ec 0c sub $0xc,%esp
8049204: 50 push %eax
8049205: e8 56 fe ff ff call 8049060 <putchar@plt>
804920a: 83 c4 10 add $0x10,%esp
804920d: 83 45 f4 01 addl $0x1,-0xc(%ebp);计数器加1

8049211: 8b 45 f4 mov -0xc(%ebp),%eax
8049214: 83 f8 08 cmp $0x8,%eax;计数器大于8之后就输出换行结束了
8049217: 76 d0 jbe 80491e9 <do_phase+0x23>
8049219: 83 ec 0c sub $0xc,%esp
804921c: 6a 0a push $0xa ;最后输出一个换行
804921e: e8 3d fe ff ff call 8049060 <putchar@plt>
8049223: 83 c4 10 add $0x10,%esp
8049226: 90 nop
8049227: c9 leave
8049228: c3 ret

看一下符号表

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -s phase3.o

Symbol table '.symtab' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS phase3.c
2: 00000000 0 SECTION LOCAL DEFAULT 1 .text
3: 00000000 0 SECTION LOCAL DEFAULT 3 .data
4: 00000000 0 SECTION LOCAL DEFAULT 5 .bss
5: 00000000 0 SECTION LOCAL DEFAULT 6 .rodata
6: 00000000 0 SECTION LOCAL DEFAULT 8 .note.GNU-stack
7: 00000000 0 SECTION LOCAL DEFAULT 9 .eh_frame
8: 00000000 0 SECTION LOCAL DEFAULT 7 .comment
9: 00000000 4 OBJECT GLOBAL DEFAULT 3 phase_id
10: 00000020 256 OBJECT GLOBAL DEFAULT COM NQqPQyqUth
11: 00000000 99 FUNC GLOBAL DEFAULT 1 do_phase
12: 00000000 0 NOTYPE GLOBAL DEFAULT UND putchar
13: 00000004 4 OBJECT GLOBAL DEFAULT 3 phase

经过上面的分析,逆向为c代码大致就是

char NQqPQyqUth[256];
do_phase{
char cookie[10]={ 79 7a 67 69 75 68 6e 62 65 00};//懒得加逗号了
for(int i = 0; i <= 9 ; i++)
putchar(NQqPQyqUth[cookie[i]]);
return putchar('\n');
}

NQqPQyqUth在COMMon块,数据都为0,所以没有输出,由于属于是弱符号,链接时会被强符号给挤掉, https://grxer.github.io/2023/04/28/static-link/ 里有分析过

所以我们定义一个强符号NQqPQyqUth,并按照cookie赋值就可以输出了

//phase3_patch.c
char NQqPQyqUth[256]="0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x0e00000000000r000gr";
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie  -c phase3_patch.c
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase3.o phase3_patch.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
grxer0000

phase4

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase4.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
B9[wL:Nec
00000029 <do_phase>:
29: 55 push %ebp
2a: 89 e5 mov %esp,%ebp
2c: 83 ec 28 sub $0x28,%esp
2f: c7 45 e6 53 4e 58 47 movl $0x47584e53,-0x1a(%ebp)
36: c7 45 ea 4a 54 43 46 movl $0x4643544a,-0x16(%ebp)
3d: 66 c7 45 ee 50 00 movw $0x50,-0x12(%ebp);从ebp-0x1a处开始的cookie赋值结束
43: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp);ebp-0x10处计数器置零
4a: e9 e0 00 00 00 jmp 12f <do_phase+0x106>

4f: 8d 55 e6 lea -0x1a(%ebp),%edx
52: 8b 45 f0 mov -0x10(%ebp),%eax
55: 01 d0 add %edx,%eax
57: 0f b6 00 movzbl (%eax),%eax;eax=cookie[计数器]
5a: 88 45 f7 mov %al,-0x9(%ebp)
5d: 0f be 45 f7 movsbl -0x9(%ebp),%eax
61: 83 e8 41 sub $0x41,%eax;cookie[计数器]-0x41 相当于我们的case值
64: 83 f8 19 cmp $0x19,%eax;cookie[计数器]-0x41和19比较
67: 0f 87 b0 00 00 00 ja 11d <do_phase+0xf4>;大于跳转类似于我们switch的default
6d: 8b 04 85 04 00 00 00 mov 0x4(,%eax,4),%eax;从下面的重定位信息来看,这里有一个需要重定位的地址.rodata,eax=*(eax*4+.rodata+4)
74: ff e0 jmp *%eax;switch的跳转,这里和我平时见的switch都不太一样,就去实验了一下,发现当case情况过多时,就会采用这种jmp *eax的跳转方式,会有一张跳转表
76: c6 45 f7 38 movb $0x38,-0x9(%ebp)
7a: e9 9e 00 00 00 jmp 11d <do_phase+0xf4>
7f: c6 45 f7 65 movb $0x65,-0x9(%ebp)
83: e9 95 00 00 00 jmp 11d <do_phase+0xf4>
88: c6 45 f7 35 movb $0x35,-0x9(%ebp)
8c: e9 8c 00 00 00 jmp 11d <do_phase+0xf4>
91: c6 45 f7 39 movb $0x39,-0x9(%ebp)
95: e9 83 00 00 00 jmp 11d <do_phase+0xf4>
9a: c6 45 f7 6d movb $0x6d,-0x9(%ebp)
9e: eb 7d jmp 11d <do_phase+0xf4>
a0: c6 45 f7 6d movb $0x6d,-0x9(%ebp)
a4: eb 77 jmp 11d <do_phase+0xf4>
a6: c6 45 f7 4c movb $0x4c,-0x9(%ebp)
aa: eb 71 jmp 11d <do_phase+0xf4>
ac: c6 45 f7 73 movb $0x73,-0x9(%ebp)
b0: eb 6b jmp 11d <do_phase+0xf4>
b2: c6 45 f7 45 movb $0x45,-0x9(%ebp)
b6: eb 65 jmp 11d <do_phase+0xf4>
b8: c6 45 f7 37 movb $0x37,-0x9(%ebp)
bc: eb 5f jmp 11d <do_phase+0xf4>
be: c6 45 f7 42 movb $0x42,-0x9(%ebp)
c2: eb 59 jmp 11d <do_phase+0xf4>
c4: c6 45 f7 77 movb $0x77,-0x9(%ebp)
c8: eb 53 jmp 11d <do_phase+0xf4>
ca: c6 45 f7 36 movb $0x36,-0x9(%ebp)
ce: eb 4d jmp 11d <do_phase+0xf4>
d0: c6 45 f7 3a movb $0x3a,-0x9(%ebp)
d4: eb 47 jmp 11d <do_phase+0xf4>
d6: c6 45 f7 5b movb $0x5b,-0x9(%ebp)
da: eb 41 jmp 11d <do_phase+0xf4>
dc: c6 45 f7 63 movb $0x63,-0x9(%ebp)
e0: eb 3b jmp 11d <do_phase+0xf4>
e2: c6 45 f7 5b movb $0x5b,-0x9(%ebp)
e6: eb 35 jmp 11d <do_phase+0xf4>
e8: c6 45 f7 33 movb $0x33,-0x9(%ebp)
ec: eb 2f jmp 11d <do_phase+0xf4>
ee: c6 45 f7 55 movb $0x55,-0x9(%ebp)
f2: eb 29 jmp 11d <do_phase+0xf4>
f4: c6 45 f7 77 movb $0x77,-0x9(%ebp)
f8: eb 23 jmp 11d <do_phase+0xf4>
fa: c6 45 f7 32 movb $0x32,-0x9(%ebp)
fe: eb 1d jmp 11d <do_phase+0xf4>
100: c6 45 f7 4e movb $0x4e,-0x9(%ebp)
104: eb 17 jmp 11d <do_phase+0xf4>
106: c6 45 f7 30 movb $0x30,-0x9(%ebp)
10a: eb 11 jmp 11d <do_phase+0xf4>
10c: c6 45 f7 31 movb $0x31,-0x9(%ebp)
110: eb 0b jmp 11d <do_phase+0xf4>
112: c6 45 f7 34 movb $0x34,-0x9(%ebp)
116: eb 05 jmp 11d <do_phase+0xf4>
118: c6 45 f7 67 movb $0x67,-0x9(%ebp)
11c: 90 nop

11d: 8d 55 dc lea -0x24(%ebp),%edx
120: 8b 45 f0 mov -0x10(%ebp),%eax
123: 01 c2 add %eax,%edx;edx=ebp-0x24+计数器
125: 0f b6 45 f7 movzbl -0x9(%ebp),%eax
129: 88 02 mov %al,(%edx);*(ebp-0x24+计数器)=*(ebp-9)
12b: 83 45 f0 01 addl $0x1,-0x10(%ebp);计数器+1

12f: 8b 45 f0 mov -0x10(%ebp),%eax
132: 83 f8 08 cmp $0x8,%eax
135: 0f 86 14 ff ff ff jbe 4f <do_phase+0x26>;计数器>9直接结束

13b: 8d 55 dc lea -0x24(%ebp),%edx
13e: 8b 45 f0 mov -0x10(%ebp),%eax
141: 01 d0 add %edx,%eax
143: c6 00 00 movb $0x0,(%eax)
146: 83 ec 0c sub $0xc,%esp
149: 8d 45 dc lea -0x24(%ebp),%eax
14c: 50 push %eax;ebp-0x24做puts参数
14d: e8 fc ff ff ff call 14e <do_phase+0x125>;puts函数
152: 83 c4 10 add $0x10,%esp
155: 90 nop
156: c9 leave
157: c3 ret
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase4.o

Relocation section '.rel.text' at offset 0x3e0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000070 00000701 R_386_32 00000000 .rodata
0000014e 00000d02 R_386_PC32 00000000 puts

Relocation section '.rel.data' at offset 0x3f0 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000030 00000701 R_386_32 00000000 .rodata
00000034 00000c01 R_386_32 00000029 do_phase

Relocation section '.rel.rodata' at offset 0x400 contains 26 entries:
Offset Info Type Sym.Value Sym. Name
00000004 00000201 R_386_32 00000000 .text
00000008 00000201 R_386_32 00000000 .text
0000000c 00000201 R_386_32 00000000 .text
00000010 00000201 R_386_32 00000000 .text
00000014 00000201 R_386_32 00000000 .text
00000018 00000201 R_386_32 00000000 .text
0000001c 00000201 R_386_32 00000000 .text
00000020 00000201 R_386_32 00000000 .text
00000024 00000201 R_386_32 00000000 .text
00000028 00000201 R_386_32 00000000 .text
0000002c 00000201 R_386_32 00000000 .text
00000030 00000201 R_386_32 00000000 .text
00000034 00000201 R_386_32 00000000 .text
00000038 00000201 R_386_32 00000000 .text
0000003c 00000201 R_386_32 00000000 .text
00000040 00000201 R_386_32 00000000 .text
00000044 00000201 R_386_32 00000000 .text
00000048 00000201 R_386_32 00000000 .text
0000004c 00000201 R_386_32 00000000 .text
00000050 00000201 R_386_32 00000000 .text
00000054 00000201 R_386_32 00000000 .text
00000058 00000201 R_386_32 00000000 .text
0000005c 00000201 R_386_32 00000000 .text
00000060 00000201 R_386_32 00000000 .text
00000064 00000201 R_386_32 00000000 .text
00000068 00000201 R_386_32 00000000 .text

分析过后逆出大致c代码

do_phase{
char cookie[10]={ 53 4e 58 47 4a 54 43 46 50 00};
char answer[10];
char tmp;
for(int i=0;i<=8;i++){
switch (tmp=cookie[i]-0x41){
case 0:
tmp=xxx;
break;
.....
case 26:
tmp=xxx;
break;
default:
break;
}
answer[i]=tmp;
}
answer[10]=0;
return puts(answer);
}

多个swith会在.rodata里生成一张跳转表,跳转表在链接时需要重定位,.rel.rodata里有大量的重定位信息,都是绝对寻址修正,offset表示要修正的位置距离.rel.rodata的值,Sym. Name表示要把修正位置加上.text符号的地址,重定位是在符号表里的地址确定后进行的, https://grxer.github.io/2023/04/28/static-link/ 里分析过

比如说我们的cookie第一个为53,0x53-0x41=0x12,

根据 6d: 8b 04 85 04 00 00 00 mov 0x4(,%eax,4),%eax;在.rodata的偏移为0x12*4+4=0x4c

image-20230507173942701

jmp *%eax所以跳转到0be,即 be: c6 45 f7 42 movb $0x42,-0x9(%ebp)

image-20230507174043686

所以第一个输出了B,我们只需要把跳转表里得值根据cookie跳转到把对应数字送入ebp-9处即可

我把它都改为6吧哈

image-20230507174600892

懒得查第几个,所以都改了。。。。。

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase4.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
666666666

phase5

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase5.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
fish: Job 1, './linkbomb' terminated by signal SIGILL (Illegal instruction)
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase5.o

Relocation section '.rel.text' at offset 0x7f8 contains 23 entries:
Offset Info Type Sym.Value Sym. Name
00000066 00000d01 R_386_32 00000020 yAnKQn
00000075 00000501 R_386_32 00000000 .rodata
00000086 00000d01 R_386_32 00000020 yAnKQn
00000000 00000000 R_386_NONE
00000000 00000000 R_386_NONE
000000bd 00000d01 R_386_32 00000020 yAnKQn
000000cc 00000d01 R_386_32 00000020 yAnKQn
00000000 00000000 R_386_NONE
000000f9 00000e01 R_386_32 0000010c aQSEth
00000107 00000e01 R_386_32 0000010c aQSEth
00000000 00000000 R_386_NONE
00000118 00000e01 R_386_32 0000010c aQSEth
00000138 00001302 R_386_PC32 00000000 strlen
00000000 00000000 R_386_NONE
00000162 00000e01 R_386_32 0000010c aQSEth
000001c0 00001302 R_386_PC32 00000000 strlen
000001e4 00001101 R_386_32 00000080 AycPNh
000001ea 00000e01 R_386_32 0000010c aQSEth
00000246 00001002 R_386_PC32 000000ef generate_code
00000000 00000000 R_386_NONE
00000256 00000c01 R_386_32 00000100 tqdzfNje
00000000 00000000 R_386_NONE
00000268 00001702 R_386_PC32 00000000 puts

可以看到有7个重定位信息被抹除了

贴一下符号表信息,后面要用

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -s phase5.o

Symbol table '.symtab' contains 25 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS phase5.c
2: 00000000 0 SECTION LOCAL DEFAULT 1 .text
3: 00000000 0 SECTION LOCAL DEFAULT 3 .data
4: 00000000 0 SECTION LOCAL DEFAULT 5 .bss
5: 00000000 0 SECTION LOCAL DEFAULT 6 .rodata
6: 00000000 0 SECTION LOCAL DEFAULT 9 .note.GNU-stack
7: 00000000 0 SECTION LOCAL DEFAULT 10 .eh_frame
8: 00000000 0 SECTION LOCAL DEFAULT 8 .comment
9: 00000000 250 OBJECT GLOBAL DEFAULT 3 ohMkhV
10: 00000000 93 FUNC GLOBAL DEFAULT 1 OOtZxJJdNH
11: 000000fc 4 OBJECT GLOBAL DEFAULT 3 phase_id
12: 00000100 10 OBJECT GLOBAL DEFAULT 3 tqdzfNje
13: 00000020 52 OBJECT GLOBAL DEFAULT 6 yAnKQn
14: 0000010c 4 OBJECT GLOBAL DEFAULT 3 aQSEth
15: 0000005d 146 FUNC GLOBAL DEFAULT 1 transform_code
16: 000000ef 60 FUNC GLOBAL DEFAULT 1 generate_code
17: 00000080 128 OBJECT GLOBAL DEFAULT 6 AycPNh
18: 0000012b 136 FUNC GLOBAL DEFAULT 1 encode_1
19: 00000000 0 NOTYPE GLOBAL DEFAULT UND strlen
20: 000001b3 135 FUNC GLOBAL DEFAULT 1 encode_2
21: 00000110 8 OBJECT GLOBAL DEFAULT 3 encoder
22: 0000023a 56 FUNC GLOBAL DEFAULT 1 do_phase
23: 00000000 0 NOTYPE GLOBAL DEFAULT UND puts
24: 00000118 4 OBJECT GLOBAL DEFAULT 3 phase

gdb调试一个一个改吧

image-20230507200104767

generate_code

第一个错误发生在generate_code里

image-20230507200258182

确实没有做重定位

void generate_code( int cookie ) {
... = cookie;
for( i=0; i<...; i++ ) {
... = transform_code( ..., i );
}
}

从框架里看出是调用了transform_code函数

000000ef <generate_code>:
ef: 55 push %ebp
f0: 89 e5 mov %esp,%ebp
f2: 83 ec 10 sub $0x10,%esp
f5: 8b 45 08 mov 0x8(%ebp),%eax
f8: a3 00 00 00 00 mov %eax,0x0
fd: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
104: eb 1a jmp 120 <generate_code+0x31>
106: a1 00 00 00 00 mov 0x0,%eax
10b: ff 75 fc push -0x4(%ebp)
10e: 50 push %eax
10f: e8 fc ff ff ff call 110 <generate_code+0x21>
114: 83 c4 08 add $0x8,%esp
117: a3 00 00 00 00 mov %eax,0x0
11c: 83 45 fc 01 addl $0x1,-0x4(%ebp)
120: 8b 45 fc mov -0x4(%ebp),%eax
123: 83 f8 0c cmp $0xc,%eax
126: 76 de jbe 106 <generate_code+0x17>
128: 90 nop
129: c9 leave
12a: c3 ret
10f:    e8 fc ff ff ff       	call   110 <generate_code+0x21>

这是我们要重定位得地方,怎么重定位可以看 https://grxer.github.io/2023/04/28/static-link/

typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Word;
typedef struct
{
Elf32_Addr r_offset; /* Address */
Elf32_Word r_info; /* Relocation type and symbol index */
} Elf32_Rel;

r_offset表示要修正的位置第一个字节相对于这个段的偏移

r_info 低8位表示要重定位类型,高24位是符号在符号表里的下标

r_offset为110,相对重定位类型 02 ,符号表里的下标 15即f

10 01 00 00 02 0f 00 00

image-20230507202240463

ok了

image-20230507202423749

transform_code

接下来错误发生在transform_code里

image-20230507202626683

image-20230507202705410

很熟悉的指令8b 04 85,我们上一个switch刚碰到过…

int transform_code( int code, int mode ) {
switch ( yAnKQn[mode] ... )
{
case 0: ......
case 1: ......
......
default: ......
}
return code;
}
0000005d <transform_code>:
5d: 55 push %ebp
5e: 89 e5 mov %esp,%ebp
60: 8b 45 0c mov 0xc(%ebp),%eax
63: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
6a: 83 e0 07 and $0x7,%eax
6d: 83 f8 07 cmp $0x7,%eax
70: 77 74 ja e6 <transform_code+0x89>
72: 8b 04 85 54 00 00 00 mov 0x54(,%eax,4),%eax
79: ff e0 jmp *%eax
7b: f7 55 08 notl 0x8(%ebp)
7e: eb 6a jmp ea <transform_code+0x8d>
80: 8b 45 0c mov 0xc(%ebp),%eax
83: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
8a: 83 e0 03 and $0x3,%eax
8d: 89 c1 mov %eax,%ecx
8f: d3 7d 08 sarl %cl,0x8(%ebp)
92: eb 56 jmp ea <transform_code+0x8d>
94: 8b 45 0c mov 0xc(%ebp),%eax
97: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
9e: f7 d0 not %eax
a0: 21 45 08 and %eax,0x8(%ebp)
a3: eb 45 jmp ea <transform_code+0x8d>
a5: 8b 45 0c mov 0xc(%ebp),%eax
a8: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
af: c1 e0 08 shl $0x8,%eax
b2: 09 45 08 or %eax,0x8(%ebp)
b5: eb 33 jmp ea <transform_code+0x8d>
b7: 8b 45 0c mov 0xc(%ebp),%eax
ba: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
c1: 31 45 08 xor %eax,0x8(%ebp)
c4: eb 24 jmp ea <transform_code+0x8d>
c6: 8b 45 0c mov 0xc(%ebp),%eax
c9: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
d0: f7 d0 not %eax
d2: 09 45 08 or %eax,0x8(%ebp)
d5: eb 13 jmp ea <transform_code+0x8d>
d7: 8b 45 0c mov 0xc(%ebp),%eax
da: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax
e1: 01 45 08 add %eax,0x8(%ebp)
e4: eb 04 jmp ea <transform_code+0x8d>
e6: f7 5d 08 negl 0x8(%ebp)
e9: 90 nop
ea: 8b 45 08 mov 0x8(%ebp),%eax
ed: 5d pop %ebp
ee: c3 ret

5d+58(十进制)=0x97

97:    8b 04 85 00 00 00 00 	mov    0x0(,%eax,4),%eax

这里应该是.rodata数据yAnKQn的重定位了

r_offset 97+3=9a 类型 01 yAnKQn符号下标13即d

9A 00 00 00  01 0D 00 00

image-20230507205421832

下一个错误

image-20230507205323580

image-20230507205344052

还是一样的

0x5d+75(十进制)=0xA8

a8:    8b 04 85 00 00 00 00 	mov    0x0(,%eax,4),%eax

offset =a8+3=AB 其余和上面一样

AB 00 00 00  01 0D 00 00 

image-20230507205815532

后面又改了一个一样的

da:    8b 04 85 00 00 00 00 	mov    0x0(,%eax,4),%eax
DD 00 00 00  01 0D 00 00

image-20230507210127236

do_phase

image-20230507210234694

image-20230507210250054

void do_phase() {
generate_code(...);
......; // Call one encoder here
printf("%s\n", ...);
}
0000023a <do_phase>:
23a: 55 push %ebp
23b: 89 e5 mov %esp,%ebp
23d: 83 ec 08 sub $0x8,%esp
240: 68 f3 00 00 00 push $0xf3
245: e8 fc ff ff ff call 246 <do_phase+0xc>//call 的是generate_code
24a: 83 c4 04 add $0x4,%esp
24d: a1 04 00 00 00 mov 0x4,%eax
252: 83 ec 0c sub $0xc,%esp
255: 68 00 00 00 00 push $0x0
25a: ff d0 call *%eax
25c: 83 c4 10 add $0x10,%esp
25f: 83 ec 0c sub $0xc,%esp
262: 68 00 00 00 00 push $0x0
267: e8 fc ff ff ff call 268 <do_phase+0x2e>//框架里虽然是printf,被编译器优化为了puts
26c: 83 c4 10 add $0x10,%esp
26f: 90 nop
270: c9 leave
271: c3 ret
24d:    a1 04 00 00 00       	mov    0x4,%eax

结合框架和call *%eax,这里应该重定位一个encoder函数,

offset 24d+1=24e,他的初始偏移为4估计是绝对地址重定位 01 encoder符号下标21即0x15

4E 02 00 00  01 15 00 00

下一个错误

image-20230507212648240

push了0做参数,puts必报错,这里就是我们的空指针指向的地方

262:    68 00 00 00 00       	push   $0x0

那push什么呢

可以看到encoder函数参数,是tqdzfNje

image-20230507213134515

输出的想必就是encode后的内容

63 02 00 00  01 0C 00 00

image-20230507214005609

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
UuUHH[[!?

有输出但结果不太对,tmd

image-20230507220450148

看来一下encoder调用的是encode_2

image-20230507220550289

发现他是一个指针数组,确实他在符号表里的size显示的也是8

那肯定encode_1是正确答案了,由于是call *%eaxcall的eax里的内容所以不能直接把 encode_1的函数符号写到重定位信息里

Relocation section '.rel.data' at offset 0x8b0 contains 4 entries:
Offset Info Type Sym.Value Sym. Name
000000fc 00000501 R_386_32 00000000 .rodata
00000110 00001201 R_386_32 0000012b encode_1
00000114 00001401 R_386_32 000001b3 encode_2
00000118 00001601 R_386_32 0000023a do_phase

那就直接把他encode_2的重定位信息改成encode_1就好了,这样调用encode_2的也就是encode_1了

image-20230507222739182

image-20230507222657681

欧克了

encode_1

运行一下,额,encode_1报错了,不过也说明方向对了

image-20230507223022320

不过重定位什么呢

看了下encode_2

image-20230507223526485

image-20230507223541678

他填了AycPNh,我们也填这个试试看把

159:    0f b6 80 00 00 00 00 	movzbl 0x0(%eax),%eax

0x159+3=15C 17=0x11

5C 01 00 00  01 11 00 00
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase5.
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
%?%00##Y?

额,后面我试光了所以变量符号,都没有和pdf里一样的输出,就这样把,反正已经重定位了7处

重定位完后的重定位表

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -r phase5.o

Relocation section '.rel.text' at offset 0x7f8 contains 23 entries:
Offset Info Type Sym.Value Sym. Name
00000066 00000d01 R_386_32 00000020 yAnKQn
00000075 00000501 R_386_32 00000000 .rodata
00000086 00000d01 R_386_32 00000020 yAnKQn
00000110 00000f02 R_386_PC32 0000005d transform_code
0000009a 00000d01 R_386_32 00000020 yAnKQn
000000bd 00000d01 R_386_32 00000020 yAnKQn
000000cc 00000d01 R_386_32 00000020 yAnKQn
000000ab 00000d01 R_386_32 00000020 yAnKQn
000000f9 00000e01 R_386_32 0000010c aQSEth
00000107 00000e01 R_386_32 0000010c aQSEth
000000dd 00000d01 R_386_32 00000020 yAnKQn
00000118 00000e01 R_386_32 0000010c aQSEth
00000138 00001302 R_386_PC32 00000000 strlen
0000024e 00001501 R_386_32 00000110 encoder
00000162 00000e01 R_386_32 0000010c aQSEth
000001c0 00001302 R_386_PC32 00000000 strlen
000001e4 00001101 R_386_32 00000080 AycPNh
000001ea 00000e01 R_386_32 0000010c aQSEth
00000246 00001002 R_386_PC32 000000ef generate_code
00000263 00000c01 R_386_32 00000100 tqdzfNje
00000256 00000c01 R_386_32 00000100 tqdzfNje
0000015c 00001101 R_386_32 00000080 AycPNh
00000268 00001702 R_386_PC32 00000000 puts

phase6

主要用到的知识 https://grxer.github.io/2023/05/04/ELF%20Dynamical-link/

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase6.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
fish: Job 1, './linkbomb' terminated by signal SIGSEGV (Address boundary error)
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main) [SIGSEGV]> readelf -r phase6.o

Relocation section '.rel.text' at offset 0x9e0 contains 35 entries:
Offset Info Type Sym.Value Sym. Name
00000007 00001902 R_386_PC32 00000000 __x86.get_pc_thunk.ax
00000000 00000000 R_386_NONE
0000005c 00001902 R_386_PC32 00000000 __x86.get_pc_thunk.ax
00000000 00000000 R_386_NONE
00000067 00001d2b R_386_GOT32X 00000020 yAnKQn
00000083 00000509 R_386_GOTOFF 00000000 .rodata
00000000 00000000 R_386_NONE
00000000 00000000 R_386_NONE
000000bb 00001d2b R_386_GOT32X 00000020 yAnKQn
00000000 00000000 R_386_NONE
000000e0 00001d2b R_386_GOT32X 00000020 yAnKQn
000000f3 00001d2b R_386_GOT32X 00000020 yAnKQn
00000113 00002102 R_386_PC32 00000000 __x86.get_pc_thunk.bx
00000000 00000000 R_386_NONE
00000000 00000000 R_386_NONE
00000000 00000000 R_386_NONE
00000141 00001f04 R_386_PLT32 00000058 transform_code
0000014c 00001e2b R_386_GOT32X 000000ac aQSEth
0000016c 00002102 R_386_PC32 00000000 __x86.get_pc_thunk.bx
......

符号表

grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> readelf -s phase6.o

Symbol table '.symtab' contains 42 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS phase6.c
2: 00000000 0 SECTION LOCAL DEFAULT 3 .text
3: 00000000 0 SECTION LOCAL DEFAULT 5 .data
4: 00000000 0 SECTION LOCAL DEFAULT 6 .bss
5: 00000000 0 SECTION LOCAL DEFAULT 7 .rodata
6: 00000000 0 SECTION LOCAL DEFAULT 9 .data.rel.local
7: 00000000 0 SECTION LOCAL DEFAULT 11 .data.rel
8: 00000000 0 SECTION LOCAL DEFAULT 13 .text.__x86.get_[...]
9: 00000000 0 SECTION LOCAL DEFAULT 14 .text.__x86.get_[...]
10: 00000000 0 SECTION LOCAL DEFAULT 16 .note.GNU-stack
11: 00000102 0 NOTYPE LOCAL DEFAULT 3 .L6
12: 00000000 0 SECTION LOCAL DEFAULT 17 .eh_frame
13: 0000008b 0 NOTYPE LOCAL DEFAULT 3 .L14
14: 00000090 0 NOTYPE LOCAL DEFAULT 3 .L13
15: 000000a6 0 NOTYPE LOCAL DEFAULT 3 .L12
16: 000000b9 0 NOTYPE LOCAL DEFAULT 3 .L11
17: 000000cd 0 NOTYPE LOCAL DEFAULT 3 .L10
18: 000000de 0 NOTYPE LOCAL DEFAULT 3 .L9
19: 000000f1 0 NOTYPE LOCAL DEFAULT 3 .L7
20: 00000000 0 SECTION LOCAL DEFAULT 15 .comment
21: 00000000 0 SECTION LOCAL DEFAULT 1 .group
22: 00000000 0 SECTION LOCAL DEFAULT 2 .group
23: 00000000 158 OBJECT GLOBAL DEFAULT 5 cjHQHR
24: 00000000 88 FUNC GLOBAL DEFAULT 3 OOtZxJJdNH
25: 00000000 0 FUNC GLOBAL HIDDEN 13 __x86.get_pc_thunk.ax
26: 00000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
27: 00000000 4 OBJECT GLOBAL DEFAULT 9 phase_id
28: 000000a0 10 OBJECT GLOBAL DEFAULT 5 tqdzfNje
29: 00000020 52 OBJECT GLOBAL DEFAULT 7 yAnKQn
30: 000000ac 4 OBJECT GLOBAL DEFAULT 5 aQSEth
31: 00000058 179 FUNC GLOBAL DEFAULT 3 transform_code
32: 0000010b 89 FUNC GLOBAL DEFAULT 3 generate_code
33: 00000000 0 FUNC GLOBAL HIDDEN 14 __x86.get_pc_thunk.bx
34: 00000080 128 OBJECT GLOBAL DEFAULT 7 AycPNh
35: 00000164 156 FUNC GLOBAL DEFAULT 3 encode_1
36: 00000000 0 NOTYPE GLOBAL DEFAULT UND strlen
37: 00000200 155 FUNC GLOBAL DEFAULT 3 encode_2
38: 00000000 8 OBJECT GLOBAL DEFAULT 11 encoder
39: 0000029b 82 FUNC GLOBAL DEFAULT 3 do_phase
40: 00000000 0 NOTYPE GLOBAL DEFAULT UND puts
41: 00000008 4 OBJECT GLOBAL DEFAULT 11 phase

首先呢他的getpc函数都是nop,所以需要先修复这个

Disassembly of section .text.__x86.get_pc_thunk.ax:

00000000 <__x86.get_pc_thunk.ax>:
0: 90 nop
1: 90 nop
2: 90 nop
3: 90 nop

Disassembly of section .text.__x86.get_pc_thunk.bx:

00000000 <__x86.get_pc_thunk.bx>:
0: 90 nop
1: 90 nop
2: 90 nop
3: 90 nop

修复后

Disassembly of section .text.__x86.get_pc_thunk.ax:

00000000 <__x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret

Disassembly of section .text.__x86.get_pc_thunk.bx:

00000000 <__x86.get_pc_thunk.bx>:
0: 8b 1c 24 mov (%esp),%ebx
3: c3 ret

generate_code

第一个错误

image-20230507232413843

image-20230507232536405

image-20230507233555928

0000010b <generate_code>:
10b: 55 push %ebp
10c: 89 e5 mov %esp,%ebp
10e: 53 push %ebx
10f: 83 ec 14 sub $0x14,%esp
112: e8 fc ff ff ff call 113 <generate_code+0x8> //__x86.get_pc_thunk.bx
117: 81 c3 02 00 00 00 add $0x2,%ebx
11d: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
123: 8b 55 08 mov 0x8(%ebp),%edx
126: 89 10 mov %edx,(%eax)
128: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
12f: eb 25 jmp 156 <generate_code+0x4b>
131: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
137: 8b 00 mov (%eax),%eax
139: 83 ec 08 sub $0x8,%esp
13c: ff 75 f4 push -0xc(%ebp)
13f: 50 push %eax
140: e8 fc ff ff ff call 141 <generate_code+0x36>
145: 83 c4 10 add $0x10,%esp
148: 89 c2 mov %eax,%edx
14a: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
150: 89 10 mov %edx,(%eax)
152: 83 45 f4 01 addl $0x1,-0xc(%ebp)
156: 8b 45 f4 mov -0xc(%ebp),%eax
159: 83 f8 0c cmp $0xc,%eax
15c: 76 d3 jbe 131 <generate_code+0x26>
15e: 90 nop
15f: 8b 5d fc mov -0x4(%ebp),%ebx
162: c9 leave
163: c3 ret
126:    89 10                	mov    %edx,(%eax)

失败的原因是eax里的内容是0x2,往上溯源,通过之前在动态链接里的学习,能够发现下面两句是关键

117:    81 c3 02 00 00 00    	add    $0x2,%ebx
11d: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax

117: 81 c3 02 00 00 00 add $0x2,%ebx这句肯定是在找重定位got表的位置

11d: 8b 83 00 00 00 00 mov 0x0(%ebx)是在根据偏移找变量在got表里的位置

下面这句也一样

131:    8b 83 00 00 00 00    	mov    0x0(%ebx),%eax

仿照下面去写got重定位就行

000002a9  00001a0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
19 01 00 00  0A 1A 00 00

在got里找偏移的就根据下面这个去改写

14a: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax这句已经被重定位过了

0000014c  00001e2b R_386_GOT32X      000000ac   aQSEth
1F 01 00 00  2B 1E 00 00 
33 01 00 00 2B 1E 00 00

transform_code

image-20230508011418971

00000058 <transform_code>:
58: 55 push %ebp
59: 89 e5 mov %esp,%ebp
5b: e8 fc ff ff ff call 5c <transform_code+0x4>//__x86.get_pc_thunk.ax
60: 05 01 00 00 00 add $0x1,%eax
65: 8b 90 00 00 00 00 mov 0x0(%eax),%edx
6b: 8b 4d 0c mov 0xc(%ebp),%ecx
6e: 8b 14 8a mov (%edx,%ecx,4),%edx
71: 83 e2 07 and $0x7,%edx
74: 83 fa 07 cmp $0x7,%edx
77: 0f 87 85 00 00 00 ja 102 <.L6>
7d: c1 e2 02 shl $0x2,%edx
80: 8b 94 02 54 00 00 00 mov 0x54(%edx,%eax,1),%edx
87: 01 c2 add %eax,%edx
89: ff e2 jmp *%edx

0000008b <.L14>:
8b: f7 55 08 notl 0x8(%ebp)
8e: eb 76 jmp 106 <.L6+0x4>

00000090 <.L13>:
90: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
96: 8b 55 0c mov 0xc(%ebp),%edx
99: 8b 04 90 mov (%eax,%edx,4),%eax
9c: 83 e0 03 and $0x3,%eax
9f: 89 c1 mov %eax,%ecx
a1: d3 7d 08 sarl %cl,0x8(%ebp)
a4: eb 60 jmp 106 <.L6+0x4>

000000a6 <.L12>:
a6: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
ac: 8b 55 0c mov 0xc(%ebp),%edx
af: 8b 04 90 mov (%eax,%edx,4),%eax
b2: f7 d0 not %eax
b4: 21 45 08 and %eax,0x8(%ebp)
b7: eb 4d jmp 106 <.L6+0x4>

000000b9 <.L11>:
b9: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
bf: 8b 55 0c mov 0xc(%ebp),%edx
c2: 8b 04 90 mov (%eax,%edx,4),%eax
c5: c1 e0 08 shl $0x8,%eax
c8: 09 45 08 or %eax,0x8(%ebp)
cb: eb 39 jmp 106 <.L6+0x4>

000000cd <.L10>:
cd: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
d3: 8b 55 0c mov 0xc(%ebp),%edx
d6: 8b 04 90 mov (%eax,%edx,4),%eax
d9: 31 45 08 xor %eax,0x8(%ebp)
dc: eb 28 jmp 106 <.L6+0x4>

000000de <.L9>:
de: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
e4: 8b 55 0c mov 0xc(%ebp),%edx
e7: 8b 04 90 mov (%eax,%edx,4),%eax
ea: f7 d0 not %eax
ec: 09 45 08 or %eax,0x8(%ebp)
ef: eb 15 jmp 106 <.L6+0x4>

000000f1 <.L7>:
f1: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
f7: 8b 55 0c mov 0xc(%ebp),%edx
fa: 8b 04 90 mov (%eax,%edx,4),%eax
fd: 01 45 08 add %eax,0x8(%ebp)
100: eb 04 jmp 106 <.L6+0x4>

00000102 <.L6>:
102: f7 5d 08 negl 0x8(%ebp)
105: 90 nop
106: 8b 45 08 mov 0x8(%ebp),%eax
109: 5d pop %ebp
10a: c3 ret

getpc后

5b:    e8 fc ff ff ff       	call   5c <transform_code+0x4>//__x86.get_pc_thunk.ax
60: 05 01 00 00 00 add $0x1,%eax

基本上下一句都是获取got表位置的重定位,直接把00000007 00001902 R_386_PC32 00000000 __x86.get_pc_thunk.ax这一个一块改了

61 00 00 00  0A 1A 00 00
0C 00 00 00 0A 1A 00 00

switch case需要重定位的地方

90:    8b 80 00 00 00 00    	mov    0x0(%eax),%eax
a6: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
cd: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
92 00 00 00  2B 1D 00 00  
A8 00 00 00 2B 1D 00 00
CF 00 00 00 2B 1D 00 00

修正后重定位表

Relocation section '.rel.text' at offset 0x9e0 contains 35 entries:
Offset Info Type Sym.Value Sym. Name
00000007 00001902 R_386_PC32 00000000 __x86.get_pc_thunk.ax
00000119 00001a0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
0000005c 00001902 R_386_PC32 00000000 __x86.get_pc_thunk.ax
0000011f 00001e2b R_386_GOT32X 000000ac aQSEth
00000067 00001d2b R_386_GOT32X 00000020 yAnKQn
00000083 00000509 R_386_GOTOFF 00000000 .rodata
00000133 00001e2b R_386_GOT32X 000000ac aQSEth
0000000c 00001a0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
000000bb 00001d2b R_386_GOT32X 00000020 yAnKQn
00000061 00001a0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
000000e0 00001d2b R_386_GOT32X 00000020 yAnKQn
000000f3 00001d2b R_386_GOT32X 00000020 yAnKQn
00000113 00002102 R_386_PC32 00000000 __x86.get_pc_thunk.bx
00000092 00001d2b R_386_GOT32X 00000020 yAnKQn
000000a8 00001d2b R_386_GOT32X 00000020 yAnKQn
000000cf 00001d2b R_386_GOT32X 00000020 yAnKQn
00000141 00001f04 R_386_PLT32 00000058 transform_code
0000014c 00001e2b R_386_GOT32X 000000ac aQSEth
0000016c 00002102 R_386_PC32 00000000 __x86.get_pc_thunk.bx
00000172 00001a0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_
0000017d 00002404 R_386_PLT32 00000000 strlen
000001a0 0000222b R_386_GOT32X 00000080 AycPNh
000001aa 00001e2b R_386_GOT32X 000000ac aQSEth
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> gcc -m32 -no-pie -o linkbomb main.o phase6.o
grxer@ubuntu22-wsl ~/s/N/NJU-ICS-linklab (main)> ./linkbomb
a*aTTgg-K