现在的位置: 首页 > 综合 > 正文

WinXP程序删除自身的方法

2013年08月07日 ⁄ 综合 ⁄ 共 2165字 ⁄ 字号 评论关闭

    大家都知道,一般的程序运行的时候,可执行文件本身是被操作系统保护的,不能用改写的方式访问,更别提在本身还在运行的时侯删除自己了。
    网上流传了一些删除自己的代码,但基本上是在win9x的系统下才可行,2000/XP下这样的代码基本没有,因为window2000/XP对这方面进行修补。所以甚至有人放言,2000/XP(Ring3下)下不可能删除自己(当然不是采取批处理,也不是机器重启后删除的办法),真的是这样吗?没有任何办法吗?笔者经过一段时间的研究,终于获得了解决,方法是来自Windows编程的经典之作《Windows核心编程》的启发。
    实现代码难度不大,研习过《Windows核心编程》的读者均可理解。基本方法是采用创建远程线程的方法实现。首先为explorer.exe创建远程线程,来执行DeleteFile函数,程序自己立即退出,这时可执行文件已经不被操作系统保护,联系方式:yinwei_88@sina.com

    本程序全部源代码如下:(win9x下无效,xp上运行成功)
// EXIT.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

//获取explorer.exe进程的ID
DWORD GetWinProcessID()
{
    HANDLE hProcessSnap=NULL;
    PROCESSENTRY32 pe32={0};
    hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hProcessSnap==INVALID_HANDLE_VALUE) return 0;
    pe32.dwSize=sizeof(PROCESSENTRY32);
    if(Process32First(hProcessSnap,&pe32))
    {
        MODULEENTRY32 me32={0};
        do
        {
   if(strcmp(pe32.szExeFile,"explorer.exe")==0)
   {
    CloseHandle(hProcessSnap);
    return pe32.th32ProcessID;
   }
        }
        while(Process32Next(hProcessSnap,&pe32));
    }
    CloseHandle(hProcessSnap);
    return 0;
}

//删除文件
//dwProcessId --- 创建远程线程的目标进程ID
//filename    --- 要删除文件的完整文件名
void DeleteSelf(DWORD dwProcessId,char *filename)

 HANDLE hProcess=NULL,hThread=NULL;
 char *add=NULL;//为目标进程分配的地址
 hProcess=OpenProcess(
  PROCESS_QUERY_INFORMATION |
  PROCESS_CREATE_THREAD     |   // 为 CreateRemoteThread
  PROCESS_VM_OPERATION      |   // 为 VirtualAllocEx/VirtualFreeEx
  PROCESS_VM_WRITE          ,   // 为 WriteProcessMemory
  FALSE,dwProcessId);//打开进程
 int strnum=strlen(filename)+1;//文件名长度
 add=(char *)VirtualAllocEx(hProcess,NULL,strnum,MEM_COMMIT,PAGE_READWRITE);//为将要写入的文件名分配空间
 WriteProcessMemory(hProcess,add,(PVOID)filename,strnum,NULL);//将文件名写入目标进程的地址空间
 PTHREAD_START_ROUTINE pfnThreadRtn=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"DeleteFileA");//获得DeleteFileA函数的地址
 hThread=CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn,add,0,NULL);//为目标创建远程线程 
 exit(0);//进程强制结束(既然已经结束,当然也无法释放空间、关闭句柄了)
}

int main(int argc, char* argv[])
{
 DWORD WinID=GetWinProcessID();
 char filename[256];
 GetModuleFileName(NULL,filename,256);//获取本可执行文件名
 DeleteSelf(WinID,filename);
 return 0;

抱歉!评论已关闭.