0x804843d 0x804843f 0x8048442 0x8048447 0x8048449 0x804844b 0x804844c 0x804844d End of assembler dump。
(gdb) b *0x8048430
Breakpoint 1 at 0x8048430
(gdb) r
Starting program: /home/wujian/share/elf_door/test
Breakpoint 1, 0x08048430 in __gmon_start__ ()
(gdb) disas
Dump of assembler code for function __gmon_start__:
0x8048430 <__gmon_start__>: push %ebp
0x8048431 <__gmon_start__+1>: mov %esp,%ebp
0x8048433 <__gmon_start__+3>: mov $0x0,%eax
0x8048438 <__gmon_start__+8>: pop %ebp
0x8048439 <__gmon_start__+9>: ret
0x804843a <__gmon_start__+10>: mov %esi,%esi
End of assembler dump。
(gdb) x/x 0x80494f8 ---〉got偏移地址offset处的入口值修改为该符号的地址
0x80494f8 <_GLOBAL_OFFSET_TABLE_+28>: 0x08048430
综上所述,推断出结论了吧;(
这个修改很简单通过遍历section,我们先寻找节类型sh_type==SHT_DYNSYM的动态符号节。dynsym节,同时这个节关联这。dynstr节(看图三)sh_link=[5]。dynstr,我们把dynstr节缓存,然后寻找符号的st_name(偏移索引)是否等同于__gmon_start__,然后修改,以上修改结束,并且我们得到了index索引的偏移;然后添加DT_RPATH这个entry,上面说过的我们寻找第一个NULL入口,我们通过遍历。dynamic数组找到第一个NULL入口结构然后修改d_tag为DT_RPATH,然后把上面的到的index添入d_un。val中,至此修改elf文件完毕。至此我们任务a完毕。
现在我们来看问题b:
为啥"能够"截获__libc_start_main()?
这就要涉及到符号解析和plt的概念
我们还用上面的test。c演示;
[wujian@redhat72 elf_door]$ gdb -q test
(gdb) disas _start
Dump of assembler code for function _start:
0x8048330 <_start>: xor %ebp,%ebp
0x8048332 <_start+2>: pop %esi
0x8048333 <_start+3>: mov %esp,%ecx
0x8048335 <_start+5>: and $0xfffffff0,%esp
0x8048338 <_start+8>: push %eax
0x8048339 <_start+9>: push %esp
0x804833a <_start+10>: push %edx
0x804833b <_start+11>: push $0x8048490
0x8048340 <_start+16>: push $0x80482bc
0x8048345 <_start+21>: push %ecx
0x8048346 <_start+22>: push %esi
0x8048347 <_start+23>: push $0x804843c
0x804834c <_start+28>: call 0x8048304 <__libc_start_main> ---〉(实际也是需要重定位的,最关键的)
0x8048351 <_start+33>: hlt
0x8048352 <_start+34>: mov %esi,%esi
End of assembler dump。
(gdb) b *0x8048304
Breakpoint 1 at 0x8048304
(gdb) r
Starting program: /home/wujian/share/elf_door/test
Breakpoint 1 at 0x8048304: file 。。/sysdeps/generic/libc-start。c, line 53。
Breakpoint 1, 0x08048304 in __libc_start_main () at 。。/sysdeps/generic/libc-start。c:53
53 。。/sysdeps/generic/libc-start。c: No such file or directory。
in 。。/sysdeps/generic/libc-start。c
(gdb) disas
Dump of assembler code for function __libc_start_main:
0x8048304 <__libc_start_main>: jmp *0x80494f0 0x8048304 plt中的entry 0x80494f0是got的地址
0x804830a <__libc_start_main+6>: push $0x10
0x804830f <__libc_start_main+11>: jmp 0x80482d4 <_init+24>
End of assembler dump。
(gdb)
下面关于符号解析的问题请参考alert7大侠的
上一篇:Linux系统调用的执行过程是怎么样的? 下一篇:Linux系统中实现内部进程通信的方法
