当一个可执行程序exe在执行过程中,程序文件无法删除,这是因为系统将每个正在运行的程序对应的硬盘文件映射到内存,即虚拟内存,要实现自删除,关键一点在程序退出前将程序从内存映射中解放出来,然后再调用文件操作函数删除程序文件!
typedef int (WINAPI *PFClose)(LPVOID); OSVERSIONINFO os_info; os_info.dwOSVersionInfoSize=sizeof(os_info); LPVOID PBuffer=NULL; PFClose pClose,pDelete; char fn[4096]; HINSTANCE hins=GetModuleHandle(NULL); // 得到本程序句柄 GetModuleFileName(NULL,fn,4096); // 得到本程序名称 if(!GetVersionEx(&os_info)) // 得到当前Windows系统版本 return FALSE; switch(os_info.dwPlatformId) { case VER_PLATFORM_WIN32_NT: // 当前系统为WinNT平台系统 __try { while(CloseHandle((HANDLE)4)); } __except(1) { } CloseHandle((HANDLE)4); pClose=PFClose(UnmapViewOfFile); break; case VER_PLATFORM_WIN32_WINDOWS: // 当前系统为Win9X平台系统 pClose=PFClose(FreeLibrary); break; default: return FALSE; } pDelete=PFClose(DeleteFile); pBuffer=VirtualAlloc(NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE); _asm { call _delete_end } _asm // 尝试关闭并删除程序 { _test_close: push hins call [pClose] // 关闭程序 or eax,eax jz _test_close lea eax,fn push eax call [pDelete] // 删除程序 or eax,eax jz _Exit_Process call eax _Exit_Process: // 退出进程 push 0 push MEM_RELEASE push 0 push pBuffer push ExitProcess // 退出进程 push VirtualFree ret } _delete_end: // 删除准备工作 _asm { pop ebx push 128 push ebx push [pBuffer] call memcpy jmp pBuffer }