对Gary Nebbet的经典自我删除代码的读后心得

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 liond8 的 blog

 

对gary nebbet的经典自我删除代码的读后心得

liond8 随笔 2004-3-14 qq:10415468

以下是gary nebbet的经典源码

#include "windows.h"

void main(int argc, char *argv[])

{

hmodule module = getmodulehandle(0);

char buf[max_path];

getmodulefilename(module, buf, sizeof(buf));

closehandle((handle)4);

__asm

{

lea eax, buf

push 0

push 0

push eax

push exitprocess

push module

push deletefile

push unmapviewoffile

ret

}

}

代码的前3排就不说了。从closehandle((handle)4)开始讲起。

在网上查找了很多资料查到handle4是os的硬编码,closehandle((handle)4)用于关闭文件语柄。

要删除一个文件必须要删除打开文件的语柄,如果有文件语柄打开将会失败。在上面已经关闭了。

下面重点分析 __asm { } 里面的内容。

经过一连串的push过后。 堆栈里面的内容形成了这样的形式。

以下是在win2000 sp3 vc6.0下测试结果。

esp         栈内的值     栈内地址

0012fe28     0           0012fe28

0012fe24     0           0012fe24

0012fe20    0012fe78     0012fe20 文件全路径

0012fe1c    77e7cf5c     0012fe1c exitprocess入口

0012fe18    00040000     0012fe18 module的值

0012fe14    77e6e3a6     0012fe14 deletefile入口

0012fe10    77e6d2bd     0012fe10 unmapviewoffile

接下来就ret我们知道ret是在函数返回的时候调用的。它的功能就是从当前的esp指向的堆栈中取出函数的返回地址。对于上面的代码来说现在的esp=0012fe10,现在取出栈地址0012fe10里面的值77e6d2bd,然后跳转到77e6d2bd,这就到了unmapviewoffile的函数入口。为什么0012fe10后面是deletefile?参数module为什么又到了0012fe18这些以后我们马上解决。

我们先自己编写一个代码

void main ()

{

unmapviewoffile(null);

}

然后反汇编看看汇编命令是怎么的。如下:

6: unmapviewoffile(null);

00401028 mov esi,esp

0040102a push 0

0040102c call dword ptr [__imp__unmapviewoffile@4 (004241ac)]

00401032 cmp esi,esp

首先是参数0入栈,然后我们追到[__imp__unmapviewoffile@4 (004241ac)]

里面去。看看现在的栈是什么样子的。如下:

栈内地址     栈内值

0012ff30     0         参数

0012ff2c     00401032  返回地址

00401032是call函数系统帮我们入栈的我们并没有手工添加。但是对于ret我们在转移到unmapviewoffile入口的时候并没有一个返回地址的入栈,也就是说push deletefile就成了unmapviewoffile函数的返回地址。再上面push module才是unmapviewoffile的参数。有一点烦琐好好想一想。好的当我们的unmapviewoffile函数调用完毕,现在eip已经到了77e6e3a6,deletefile入口。

但是esp现在在什么位置?应该在0012fe1c栈内的值为77e7cf5c,同样的道理

在deletefile返回后程序应该跳转到77e7cf5c也就是exitprocess的入口。

那么(0012fe1c+4)才是deletefile的参数。也就是0012fe78。push eax。

当我们的deletefile返回的时候,程序跳转到了77e7cf5c,exitprocess的入口。现在的esp=0012fe24。一样的道理

push 0 这个是exitprocess的参数

push 0 这个是exitprocess的返回地址

由于exitprocess还没有返回进程就结束了 所以exitprocess的返回地址是0也不会发生内存错误。

参考文献:

gary nebbet的经典源码

以上是本人的一点个人愚见希望对您有所帮助。如果有什么意见,更好的见解欢迎与本人讨论。

=====================

www.rohu.com

虎盟网络安全小组

本文关键:对Gary Nebbet的经典自我删除代码的读后心得
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top