实验内容
修改phase4.o相应节中的内容,使其与main.o链接后运行能够输出自己的学号:
$ gcc -o linkbomb main.o phase4.o
$ ./linkbomb
$学号
实验提示
掌握switch语句的机器语言表示及其跳转表的实现。
找出跳转表
反汇编phase4.o,看看里面干了些什么内容。
粗略一看,那么长;看到中间,猜到是switch;看看头尾,和phase3一模一样。
头尾我还是一字一句的看了一遍,真的完全一样。细节略。
找到这里就是跳转表了。在56位置重定位,看看重定位到哪了。
如下图,重定位到rodata节去了。
看rodata节,跳转表就是这里。
插一句
我做的时候是先链接的,这样似乎不用查重定位表,比较不用动脑子。
找到0x8048734位置,还是只读数据节。
分析跳转表
对照写出ax是几时跳到哪,如下。
53: 8b 04 85 00 00 00 00 mov 0x0(,%eax,4),%eax5a: ff e0 jmp *%eax5c: c6 45 e3 33 movb $0x33,-0x1d(%ebp)——————————060: e9 9e 00 00 00 jmp 103 <do_phase+0x103>65: c6 45 e3 34 movb $0x34,-0x1d(%ebp)——————————169: e9 95 00 00 00 jmp 103 <do_phase+0x103>6e: c6 45 e3 74 movb $0x74,-0x1d(%ebp)——————————272: e9 8c 00 00 00 jmp 103 <do_phase+0x103>77: c6 45 e3 36 movb $0x36,-0x1d(%ebp)——————————37b: e9 83 00 00 00 jmp 103 <do_phase+0x103>80: c6 45 e3 6d movb $0x6d,-0x1d(%ebp)——————————484: eb 7d jmp 103 <do_phase+0x103>86: c6 45 e3 38 movb $0x38,-0x1d(%ebp)——————————58a: eb 77 jmp 103 <do_phase+0x103>8c: c6 45 e3 62 movb $0x62,-0x1d(%ebp)——————————690: eb 71 jmp 103 <do_phase+0x103>92: c6 45 e3 30 movb $0x30,-0x1d(%ebp)——————————796: eb 6b jmp 103 <do_phase+0x103>98: c6 45 e3 79 movb $0x79,-0x1d(%ebp)——————————89c: eb 65 jmp 103 <do_phase+0x103>9e: c6 45 e3 3b movb $0x3b,-0x1d(%ebp)——————————9a2: eb 5f jmp 103 <do_phase+0x103>a4: c6 45 e3 37 movb $0x37,-0x1d(%ebp)——————————aa8: eb 59 jmp 103 <do_phase+0x103>aa: c6 45 e3 47 movb $0x47,-0x1d(%ebp)——————————bae: eb 53 jmp 103 <do_phase+0x103>b0: c6 45 e3 4d movb $0x4d,-0x1d(%ebp)——————————cb4: eb 4d jmp 103 <do_phase+0x103>b6: c6 45 e3 5a movb $0x5a,-0x1d(%ebp)——————————dba: eb 47 jmp 103 <do_phase+0x103>bc: c6 45 e3 3f movb $0x3f,-0x1d(%ebp)——————————ec0: eb 41 jmp 103 <do_phase+0x103>c2: c6 45 e3 39 movb $0x39,-0x1d(%ebp)——————————fc6: eb 3b jmp 103 <do_phase+0x103>c8: c6 45 e3 40 movb $0x40,-0x1d(%ebp)——————————10cc: eb 35 jmp 103 <do_phase+0x103>ce: c6 45 e3 6b movb $0x6b,-0x1d(%ebp)——————————11d2: eb 2f jmp 103 <do_phase+0x103>d4: c6 45 e3 70 movb $0x70,-0x1d(%ebp)——————————12d8: eb 29 jmp 103 <do_phase+0x103>da: c6 45 e3 32 movb $0x32,-0x1d(%ebp)——————————13de: eb 23 jmp 103 <do_phase+0x103>e0: c6 45 e3 31 movb $0x31,-0x1d(%ebp)——————————14e4: eb 1d jmp 103 <do_phase+0x103>e6: c6 45 e3 7c movb $0x7c,-0x1d(%ebp)——————————15ea: eb 17 jmp 103 <do_phase+0x103>ec: c6 45 e3 40 movb $0x40,-0x1d(%ebp)——————————16f0: eb 11 jmp 103 <do_phase+0x103>f2: c6 45 e3 6e movb $0x6e,-0x1d(%ebp)——————————17f6: eb 0b jmp 103 <do_phase+0x103>f8: c6 45 e3 35 movb $0x35,-0x1d(%ebp)——————————18fc: eb 05 jmp 103 <do_phase+0x103>fe: c6 45 e3 5e movb $0x5e,-0x1d(%ebp)——————————19102: 90 nop
然后看当什么都不改时,程序的输出
第一个字符的ascii码是0x4f,减去0x41就是0xe,
11: c7 45 e9 4f 58 59 44 movl $0x4459584f,-0x17(%ebp)18: c7 45 ed 4b 50 56 47 movl $0x4756504b,-0x13(%ebp)1f: 66 c7 45 f1 46 5a movw $0x5a46,-0xf(%ebp)25: c6 45 f3 00 movb $0x0,-0xd(%ebp)29: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp)
跟phase3一模一样,局部变量字符串放在起始位置为-0x17(%ebp)处
跳到这里,那么第一个打印的字符的ascii码就是3f,即一个问号("?"),对照输出结果,的确是。以此类推,后续9个字符也是如此。
bc: c6 45 e3 3f movb $0x3f,-0x1d(%ebp)——————————ec0: eb 41 jmp 103 <do_phase+0x103>
那么只需要修改phase4.o的text节,将跳转之后的语句改为我们学号的ascii码即可。例如第一个字符那里就把3f改为30(如果学号第一位是0的话)。
完成。
后记
阶段四几乎跟阶段三一模一样。十分简单。