病毒的重定位技术学习笔记

时间:2021-03-31 18:50:10

原文:http://www.pediy.com/kssd/index.html -- 病毒技术 -- 病毒知识 -- Anti Virus专题

下面的代码都是内联汇编,较比较汇编会有些限制,可能写法上有时候会不一样。黑色是代码,红色是编译的汇编代码

int g_nTest;

__asm

{

                  call Dels

00401004 call 013C13A3 ; call指令会将下一句指令的地址入栈

              Dels:

                  pop ebx

00401009 pop ebx ; 将栈中保存的地址弹到ebx中

                  lea eax, g_nTest

0040100A lea eax,ds:[00401000h] ; 获得全局变量的地址

                 sub eax, Dels

00401010 sub eax,00401009h ; 获得全局变量和Dels的差值

                 lea edx, [ebx + eax]

00401006 lea edx,[ebx+eax] ; 用ebx即Dels的地址加上差值就得到了全局变量的地址

}

 

假如g_nTest的地址为00401000h,将上面的重定位代码感染到被感染的程序空间中的地址为00801004h的地方,g_nTest对应的地址就应为00801000h,就会是下面这种情况:

call指令执行后,将地址00801009h压入堆栈(应为call指令占用5个字节),然后pop给ebx,然后求得全局变量和Dels的差值,即00401000h - 00401009h,然后加到ebx(00801009h)上即可得到全局变量在被感染程序中的位置(00801000h)。其实意思也就说,在病毒本体的时候,全局变量和call指令的下一句指令的差和在被感染程序中是一样的,它是不变的,在被感染程序中获得call的下一句指令的地址,然后加上差值,即可找到全局变量

以下摘自原文,里面加了点自己的注释,括号里的

"比如我们的szText变量(也就是全局变量)相对于病毒起始位置的偏移是9h(这里的起始位置可以理解为一个点,同全局变量与call下一句指令的地址的差值,也即偏移是一样的), 那么只要通过求得病毒插入到被感染对象后的病毒起始位置 + 这个变量相对病毒起始位置的偏移 =  变量在被感染对象中的位置。"

 

还有一种方法是罗云彬的《Windows环境下32位汇编程序语言设计》第13章远程线程中说到的,代码如下:

int g_nTest;

__asm

{

                 call Dels

00401004 call 00401009 ; 保存下句指令地址到堆栈

            Dels:

                 pop ebx

00401009 pop ebx; 弹到ebx

                 sub ebx, Dels

0040100A sub ebx,00401009h; 减去Dels获得差值

                  lea edx, [ebx + g_nTest]

00401010 lea edx,[ebx+00401000h]; 差值加上全局变量

}

这个重定位方法是这样的:如果g_nTest的地址为00401000h,这个代码没有插入到别的程序中,将指令保存到堆栈弹到ebx后,ebx减去Dels为0,然后加上全局变量就等于lea edx, [g_nTest]

 

如果插入到别的程序地址为00801004h的位置,g_nTest地址变为00801000h,那么pop到ebx 的值即为00801009h,减去Dels为00801009h - 00401009h = 00400000h,然后加上全局变量就变成了lea edx, [00400000h + 00401000h],这样就获得了全局变量的地址