1、简介
本文讨论了一个修改ELF文件实现共享库调用重定向的方法。修改可执行文件的程序连接表(Procedure Linkage Table)可以使被感染的文件调用外部的函数。这要比修改LD_PRELOAD环境变量实现调用的重定向优越的多,首先不牵扯到环境变量的修改,其次是更为隐蔽。本文将提供一个基于x86/Linux的实现。如果你对UNIX系统 病毒比较感兴趣请参考以下网址:
http://virus.beergrave.net/ (UNIX病毒邮件列表)
http://www.big.net.au/~silvio (作者主页)
2、程序连接表(Procedure Linkage Table)
下面是ELF规范中,关于程序连接表的叙述:
程序连接表(PLT)
在ELF文件中,全局偏移表(Global Offset Table,GOT)能够把位置无关的地址定位到绝对地址,程序连接表也有类似的作用,它能够把位置无关的函数调用定向到绝对地址。连接编辑器(link editor)不能解决程序从一个可执行文件或者共享库目标到另外一个的执行转移。结果,连接编辑器只能把包含程序转移控制的一些入口安排到程序连接表(PLT)中。在system V体系中,程序连接表位于共享正文中,但是它们使用私有全局偏移表(private global offset table)中的地址。动态连接器(例如:ld-2.2.2.so)会决定目标的绝对地址并且修改全局偏移表在内存中的影象。因而,动态连接器能够重定向这些入口,而勿需破坏程序正文的位置无关性和共享特性。可执行文件和共享目标文件有各自的程序连接表。
.PLT0ushl got_plus_4
jmp *got_plus_8
nop; nop
nop; nop
.PLT1:jmp *name1_in_GOT
pushl $offset
jmp .PLT0@PC
.PLT2:jmp *name2_in_GOT
pushl $offset
jmp .PLT0@PC
.......
.PLT0ushl 4(%ebx)
jmp *8(%ebx)
nop; nop
nop; nop
.PLT1:jmp *name1@GOT(%ebx)
pushl $offset
jmp .PLT0@PC
.PLT2:jmp name2@GOT(%ebx)
pushl $offset
jmp .PLT0@PC
....