在PROCESS没有结束前就将启动PROCESS的EXE文件删除

原创 2001年02月12日 14:57:00
下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段代码.
这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了.

int 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
    }
    return 0;
}
现在,我们先看一下堆栈中的东西

偏移 内容
24   0
20   0
16   offset buf
12   address of ExitProcess
8    module
4    address of DeleteFile
0    address of UnmapViewOfFile

调用RET返回到了UnmapViewOfFile,也就是栈里的偏移0所指的地方.当进入UnmapViewOfFile的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitProcess的函数入口.并且参数为0而返回地址也是0.0是个非法地址.如果返回到地址0则会出错.而调用ExitProcess则应该不会返回.
这段代码的精妙之处在于:
1.如果有文件的HANDLE打开,文件删除就会失败,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬编码,对应于EXE的IMAGE.在缺省情况下,OS假定没有任何调用会关闭IMAGE SECTION的HANDLE,而现在,该HANDLE被关闭了.删除文件就解除了文件对应的一个句柄.
2.由于UnmapViewOfFile解除了另外一个对应IMAGE的HANDLE,而且解除了IMAGE在内存的映射.所以,后面的任何代码都不可以引用IMAGE映射地址内的任何代码.否则就OS会报错.而现在的代码在UnmapViewOfFile后则刚好没有引用到任何IMAGE内的代码.
3.在ExitProcess之前,EXE文件就被删除了.也就是说,进程尚在,而主线程所在的EXE文件已经没了.(WINNT/9X都保护这些被映射到内存的WIN32 IMAGE不被删除.)

Gary Nebbett果然是WIN系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:)

BTW,此文章在转贴前没有得到陆麟的同意,在此表示抱歉。不过要跟大家说一声,他的主页里的内容真的很不错,喜欢研究低层的朋友们应该去看看lu0.126.com

C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)

防止程序运行多个实例的方法有多种,如:通过使用互斥量和进程名等.而我想要实现的是:在程序运行多个实例时激活的是第一个实例,使其获得焦点,并在前端显示. 主要用到两个API 函数: ShowW...
  • dyllove98
  • dyllove98
  • 2013年03月29日 13:30
  • 4557

WPF 利用Process.Start()方法启动指定路径下的exe文件并传递参数

简单来说就是实现一个程序A 打开程序B,并且在打开的时候传递一些参数给B,最后在B窗口上显示出参数,这个小功能也是折腾了我半天。现在把我的过程整理记录下来。 1.首先我们得有一个被调用的程序,新建一个...
  • u012046379
  • u012046379
  • 2016年03月01日 21:39
  • 4253

C#做服务使用Process启动外部程序没窗体

最近想写一个进程守护程序并把它做成服务,结果发现在服务中启动带窗体的应用程序,只有进程看不到窗体。 找了很多文章,最后选择了一个答案: 网上也有叫session0穿透的,具体的大家可以找找。 (我...
  • finish_dream
  • finish_dream
  • 2017年03月03日 11:00
  • 2078

一次PEDIY---修改Windows自带的calc.exe (Unable to read memory of debugged process......”错误提示)

标 题: 【原创】一次PEDIY---修改Windows自带的calc.exe 作 者: stalker 时 间: 2008-07-08,11:06:15 链 接: http://bbs.ped...
  • kendyhj9999
  • kendyhj9999
  • 2011年12月30日 22:56
  • 1750

Tip: Run process in system account (sc.exe)

I have recently been doing some research on windows services, and have been working on some command ...
  • killer000777
  • killer000777
  • 2011年05月06日 08:48
  • 845

调用和关闭指定的程序,C#源代码,System.Diagnostics.Process.Start("notepad.exe");

  • 2008年12月23日 13:05
  • 37KB
  • 下载

Process Lasso 9.x.x Patch.exe

  • 2017年04月10日 18:54
  • 603KB
  • 下载

Process Explorer超强进程管理工具.exe

  • 2008年03月25日 15:31
  • 536KB
  • 下载

进程管理器Process Explorer v11_13.exe

  • 2008年05月07日 11:14
  • 3.35MB
  • 下载

Win7/Win10 x64 中VC6 安装卡死、无法单步调试、调试退出进程没有结束

  • 2017年10月11日 19:40
  • 169KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在PROCESS没有结束前就将启动PROCESS的EXE文件删除
举报原因:
原因补充:

(最多只允许输入30个字)