Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

Linux系统下解析Elf文件DT_RPATH后门

来源: 作者: 时间:2007-04-11 点击: [收藏] [投稿]

(gdb) disas main

Dump of assembler code for function main:

0x804843c

: push %ebp

0x804843d : mov %esp,%ebp

0x804843f : sub $0x8,%esp

0x8048442 : call 0x8048430 <__gmon_start__>

0x8048447 : mov %eax,%eax

0x8048449 : mov %eax,%eax

0x804844b : leave

0x804844c : ret

0x804844d : lea 0x0(%esi),%esi

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系统中实现内部进程通信的方法

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号