病毒技术一:程序的重定位
--------程序的重定位--------病毒为何要重定位?了解汇编的一定明白,编译器在编译程序的时候分配给变量的是一个偏移地址,例如:
MOV [DATA],EAX ;我们假设DATA位于偏移100H
最终编译出的指令将会是:
MOV [0100H],EAX
病毒本体在执行这段代码时当然没有问题,因为病毒是被正确的加载到了一个内存段中;举个比方:我们假设病毒被加载到了0X7C00H处(别在意这些细节),那么:
MOV [0100H],EAX将会往0X7C00H+0100H处写入数据
病毒的一大目的就是感染其他程序,说白了就是把自己的代码插入到其他程序里。思考一下,假如上面的内存操作指令是病毒里的某条指令,然后被插入到了其他内存中,会产生什么结果?
答案:除非病毒被放在了宿主的入口处,不然[DATA]的地址会无法对上病毒原本的[DATA]地址:
我们假设宿主被加载到了8200H段地址处(别在意这些细节):
PUSH ECX ;宿主代码入口,偏移量(OFFSET)为0000H
CALL ....
MOV [1200],EAX
................
XOR EAX,EAX ;宿主代码被程序代码重写,此处为病毒代码入口,假设偏移量为0700H
................
MOV [DATA],EAX ;实际上是MOV [0100H],EAX。总该发现错误了吧,此处写入的位置为8200H+0100H处,然而病毒的入口在8200H+0700H处,正确的[DATA]地址应该为8200H+0700H+0100H,本来应该写 ............... ;病毒内部的内存区域,却写到宿主主代码的某处去(8200H+0100H)了
--------重定位的方法--------
我们都知道,CALL指令会把其下一条指令的地址入栈,并调用一个子过程,利用这一个特性,我们很容易就可以获得偏移量变化值,及病毒偏移量和宿主程序偏移量的差别。看看下面的代码:
我们假设宿主被加载到8200H段地址处(别在意这些细节):
...... ;宿主的代码,偏移量为0000HH,
......
......
CALL GETDELTA ;我们假设这是病毒的入口处,偏移为0700H
GETDELTA:
POP EBP ;EBP此时为这条指令的物理地址,是“真正”的地址,此时即8200H+0700H+0005H = 8905H(最后的5H是CALL占用的字节,加上它就是它下条指令的地址了)。如果在病毒自身里调用的话它的物理地址会是:(病毒入口段地址)+0005H的偏
;移量
SUB EBP,OFFSET GETDELTA ;我们这里减去GETDELTA在病毒自身里的偏移(编译器编译出的这条指令会是SUB EBP,5 因为GETDELTA在病毒里的偏移为5),那么好了,我们看下此时EBP的值:0705H-0005H = 700H,这就是偏移变化量了
........ ;下一步我们对我们原来的MOV [DATA],EAX指令加上偏移变化量即可
MOV [EBP+DATA],EAX ;此时编译出来的指令为:MOV [EBP+0100H],EAX,即往8200H+0700H+0100H处写入数据(和之前的8200H+0700H+0100H一样),也就是病毒代码里[DATA]的正确地址了
[此贴子已经被作者于2016-5-28 13:15编辑过]