删除一个正在运行的程序?

game_sage 2002-11-23 04:30:03
#include "windows.h"
int main(int argc, char* argv[])
{
char buf[MAX_PATH];
HMODULE module;

module = GetModuleHandle(0);
GetModuleFileName(module, buf, MAX_PATH);
CloseHandle((HANDLE)4);

__asm
{
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push UnmapViewOfFile
push DeleteFile
ret
}

return 0;
}
//我试了一下,不行,是什么原因?????
//WIN98+BCB6
...全文
68 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Taiji02 2002-11-25
  • 打赏
  • 举报
回复
先转载一篇文章,来自lu0。


下面的代码由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系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:)

但是这段代码在C++Builder里不能通过编译,要做一下修改,如下。

#include <windows.h>

int main()
{
char buf[MAX_PATH];
HMODULE Hm1,Hm2;
HANDLE Ex,De,Un;
Hm2=GetModuleHandle(0);
GetModuleFileName(Hm2,buf,255);
Hm1=GetModuleHandle("Kernel32");
Ex=GetProcAddress(Hm1,"ExitProcess");
De=GetProcAddress(Hm1,"DeleteFileA");
Un=GetProcAddress(Hm1,"UnmapViewOfFile");
CloseHandle(HANDLE(4));
__asm {
LEA EAX,buf
PUSH 0
PUSH 0
PUSH EAX
PUSH Ex
PUSH Hm2
PUSH De
PUSH Un
RET
}
return 0;
}

以上是抄来的,后一种方法我没试,哪位仁兄有结果了请通知一声。
pzoon 2002-11-24
  • 打赏
  • 举报
回复
sjd163(sjd163)
你的东西怎么样了
game_sage 2002-11-24
  • 打赏
  • 举报
回复
程序是在别的的地方找来的,效果是运行之后,把自己删除,就是不知道原理!
IT-司马青衫 2002-11-23
  • 打赏
  • 举报
回复
unit Unit1;//关于隐藏桌面

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Registry,Dialogs, StdCtrls,tlhelp32 ;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
AppPath:String;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
ShellPath,ShellPathBack:String;
SysDire :array[1..255] of char;
WinDire :array[1..255] of char;

rValue:boolean;
pID:DWORD;
lppe:ProcessEntry32;
hSnapshot,pHandle:Thandle;
RegF:TRegistry;
delresult:longint;
begin
RegF:=TRegistry.Create;
RegF.RootKey := HKEY_LOCAL_MACHINE;
RegF.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run', true);
RegF.WriteString('多媒体智能终端', Application.ExeName);
RegF.CloseKey;

RegF.Free;

GetWindowsDirectory(WinDire,255);
ShellPath:=WinDire;
ShellPath:=ShellPath+'\explorer.exe';

GetSystemDirectory(SysDire,255);
ShellPathBack:=SysDire;
ShellPathBack:=ShellPathBack+'\dllcache'+'\explorer.exe';
AppPath:=ExtractFilePath(Application.ExeName)+'explorer.exe';

if (FileExists(ShellPath)) then
begin
hSnapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //因为桌面程序先运行其他程序之前
lppe.dwSize:= sizeof(lppe); //必须看看它是否在运行中
rValue:=Process32First(hSnapshot,@lppe);
while rValue=true do
begin
if(ExtractFilePath(lppe.szExeFile)='explorer.exe') then
begin
pID:=lppe.th32ProcessID; //如果在运行中就杀了它
pHandle:=OpenProcess(PROCESS_TERMINATE,false,pID);
delresult:=TerminateProcess(pHandle,9);

CopyFile(ShellPath.c_str(),AppPath.c_str(),1); //保存在ICT程序身边并灭了它
DeleteFile(ShellPath);
rValue:=false;
end
rValue:=Process32Next(hSnapshot,@lppe);
end
CloseHandle(hSnapshot);
end;

if (FileExists(ShellPathBack)) then
DeleteFile(ShellPathBack);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Handle,'Open',pchar(AppPath) ,0,0,SW_SHOW);
Application.Terminate;
end;

end.
sjd163 2002-11-23
  • 打赏
  • 举报
回复
例如你坐车正在跑,把车去掉。你怎么办。控制交给谁?
myy 2002-11-23
  • 打赏
  • 举报
回复
98不清楚,2k中运行中的程序可以改名,但不能直接删除。

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧