請問大家,程序運行時莫名失蹤,非正常退出,沒有任何錯誤提示,這一般是什麼原因造成的啊? 請問大家,程序運行時莫名失蹤,非正常退出,沒有任何錯誤提示,這一般是什麼原因造成的啊? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 本文出在 老罗的缤纷天地「 http://www.luocong.com/ 」 程序的自删除已经不是什么新鲜的话题了,它广泛运用于木马、病毒中。试想想,当你的程序还在运行中(通常是完成了驻留、感染模块),它就自动地把自己从磁盘中删掉,这样一来,就做到了神不知鬼不觉,呵呵,是不是很cool呢? 自删除(Self Deleting)最早的方法是由 Gary Nebbett 大虾写的,太经典了,不能不提。程序如下:#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 DeleteFile push UnmapViewOfFile ret } return 0;} 试试编译它,运行。怎么样?从你的眼皮底下消失了吧?是不是很神奇?Gary Nebbett 钻了系统的一个漏洞,他的程序是关闭了 exe 文件的 IMAGE(硬编码为4),然后用 UnmapViewOfFile 解除了 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除。Gary Nebbett 果然不愧为 WIN 系统下顶尖的底层高手。那么是否还有其他的方法实现程序的自删除呢?答案是肯定的。在 Win9x/ME 下,还可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一个节 [[Rename]] ,只要在里面写入要 “Nul=要删除的文件”,那么下次系统重新启动的时候,该文件就会被自动删除了。以下是一个例子:[[Rename]]NUL=c:\SelfDelete.exe 利用这个特性,我们就可以在程序中对这个 ini 文件进行操作。值得注意的是,当需要自删除的文件多于一个的时候,就不能使用 WritePrivateProfileString 来实现,因为这个 API 会阻止多于一个“NUL=”这样的入口在同一个节里面出现,所以最好还是自己手动实现。第三种方法是利用批处理文件。先让我们做一个试验:创建一个 a.bat ,给它写入以下内容:del %0.bat 现在运行它吧,屏幕一闪而过,最后留下一串字符:“The batch file cannot be found”。这时候它已经从你的硬盘中消失了。这说明,批处理文件是可以删除自己的,于是我们可以把这个小技巧运用在自己的程序当中::Repeatdel "C:\MYDIR\SelfDelete.exe"if exist "SelfDelete.exe" goto Repeatrmdir "C:\MYDIR"del "\DelUS.bat" 它会重复不断地搜索是否有 SelfDelete.exe 这个文件,直到删除了它为止;当删除完毕后,这个批处理文件就会把自己删除。(注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)用批处理文件的方法有一个缺陷,就是会突然弹出一个 DOS 窗,冷不防的吓人一跳,不过据我所知这是目前唯一可以在 WinXP 下起作用的方法。当然,最理想的方法是用 Gary Nebbett 的那种,不过它的缺陷是没法在 WinXP 下起作用。(注:Gary Nebbett 的方法,hume已经给出了例子,所以我就不重复了,请到他的网站 http://humeasm.yeah.net/ 下载。)以上的方法都是前辈高人的研究总结,可不是我原创的,不过最后我给出一个 Win32ASM 例子,演示一下用批处理文件删除程序自身的方法。;******************************************************;程序名称:程序自删除示例,适用于Win9x/WinMe/Win2000/WinXP;作者:罗聪;日期:2002-10-23;出处:http://www.luocong.com/(老罗的缤纷天地);注意事项:如欲转载,请保持本程序的完整,并注明:;转载自“老罗的缤纷天地”(http://www.luocong.com/);******************************************************.386.model flat, stdcalloption casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incinclude \masm32\include\shell32.incinclude \masm32\include\user32.incincludelib \masm32\lib\user32.libincludelib \masm32\lib\kernel32.libincludelib \masm32\lib\shell32.libDeleteExecutableBF PROTO.codemain: invoke DeleteExecutableBF invoke ExitProcess, NULL;********************************************; 模块功能:用批处理文件删除自身; 入口参数:无; 出口参数:无;********************************************DeleteExecutableBF proc LOCAL hFile :DWORD LOCAL len :DWORD LOCAL hHeap :DWORD LOCAL pszUnsetupPathname :DWORD LOCAL pszUnsetupPath :DWORD LOCAL pszBatFilePathname :DWORD LOCAL pBatFile :DWORD jmp nextcode szBatFileName BYTE "DelUS.bat", 0 szOpen BYTE "open", 0 szBKSlash BYTE "\", 0 L1 BYTE ":Repeat", 13, 10, 0 L2A BYTE "del """, 0 L2B BYTE """", 0 L3A BYTE 13, 10, "if exist """, 0 L3B BYTE """ goto Repeat", 13, 10, 0 L4 BYTE "rmdir """, 0 L5 BYTE """",13, 10, "del """, 0 L6 BYTE """",13, 10, 0 nextcode: ; 为字符串分配堆: invoke GetProcessHeap mov hHeap, eax invoke HeapAlloc, hHeap, NULL, 4 * MAX_PATH + 1000 mov pszUnsetupPath, eax add eax, MAX_PATH mov pszUnsetupPath, eax add eax, MAX_PATH mov pszUnsetupPathname, eax add eax, MAX_PATH mov pszBatFilePathname, eax add eax, MAX_PATH mov pBatFile, eax ; 创建一个批处理文件,用于删除我们的exe文件。当exe文件被删除后,这个批处理文件会自动删除自己,以及它所在的目录。 ; 得到 temp 目录的路径: invoke GetTempPath, MAX_PATH, pszBatFilePathname invoke lstrcat, pszBatFilePathname, addr szBatFileName invoke CreateFile, pszBatFilePathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL mov hFile, eax .if (hFile != INVALID_HANDLE_value) ; 得到我们的 exe 文件的全路径(包括文件名): invoke GetModuleFileName, NULL, pszUnsetupPathname, MAX_PATH ; 得到我们的 exe 文件的路径(不包括文件名): invoke lstrcpy, pszUnsetupPath, pszUnsetupPathname ; 找到路径最后的 ’\’ 并把它改成0 mov edx, pszUnsetupPath mov ecx, edx .repeat mov al, byte ptr [edx] .if al == 92 ; "\" mov ecx, edx .endif inc edx .until al == 0 mov byte ptr [ecx+1], 0 ; Bat 文件的内容: ; :Repeat ; del "C:\Win95ADG\DelSelf.exe" ; if exist "DelSelf.exe" goto Repeat ; rmdir "C:\Win95ADG" ; del "c:\%temppath%\DelUS.bat" invoke lstrcat, pBatFile, addr L1 invoke lstrcat, pBatFile, addr L2A invoke lstrcat, pBatFile, pszUnsetupPathname invoke lstrcat, pBatFile, addr L2B invoke lstrcat, pBatFile, addr L3A invoke lstrcat, pBatFile, pszUnsetupPathname invoke lstrcat, pBatFile, addr L3B invoke lstrcat, pBatFile, addr L4 invoke lstrcat, pBatFile, pszUnsetupPath invoke lstrcat, pBatFile, addr L5 invoke lstrcat, pBatFile, pszBatFilePathname invoke lstrcat, pBatFile, addr L6 ; 创建 bat 文件: invoke lstrlen, pBatFile mov len, eax invoke WriteFile, hFile, pBatFile, len, addr len, NULL invoke CloseHandle, hFile ; 现在在后台执行我们的 bat 文件: invoke ShellExecute, NULL, addr szOpen, pszBatFilePathname, NULL, NULL, SW_HIDE .endif ; 释放堆: invoke HeapFree, hHeap, NULL, pszUnsetupPathreturn: ; 结束啦! retDeleteExecutableBF endpend main;******************** over ********************;by LC 在程序中可疑的地方加入ASSERT断言宏或者VERIFY确认宏,然后用debug版运行。或者在BoundsChecker中运行debug版的程序,一般来说,所有的错误都可以捕捉到。 我想应该是你的程序出现异常,但你没有捕获,你的程序就此死掉。在可能出异常的地方,加上try catch,并显示或记录你的异常信息,那么就可以防止很多问题了。 还有件怪事: 用TC2.0写的程序是可以直接用remove(exeName);//exeName为自己的名字删自己的,在linux下用GCC编译也可以。但是在VC下编译一个相同的程序就不行。 只有internet SDK有这个命令, 你要删除一个exename显然是不支持的, 如果你有数据库编程,没有采用try--catch,当出错的话程序就会消失的无影无踪,和你介绍的情况一下。这是我做程序的经历。 多线程具体实现问题 取得播放视频的当前播放时间 请问怎样声明CListView啊? 如何获得其它程序中EDIT控件的句柄? char 数据过长怎么处理;???在线等待 同样是CDialog继承下来的类,前几天Create()中的参数只要两个,今天就说function does not take 2 parameters,是怎么回事? 对图像如何做二次微分,请提示 串口通信问题!(在线等待) 关于线程挂起和唤醒的一个设计问题 求救!!!!!!!!!! 求教斑竹: 已经知道dll和dll函数接口名称,怎样求得dll接口函数的参数? 怎样得知当前提交的是哪个form?(NULL)
程序的自删除已经不是什么新鲜的话题了,它广泛运用于木马、病毒中。试想想,当你的程序还在运行中(通常是完成了驻留、感染模块),它就自动地把自己从磁盘中删掉,这样一来,就做到了神不知鬼不觉,呵呵,是不是很cool呢?
自删除(Self Deleting)最早的方法是由 Gary Nebbett 大虾写的,太经典了,不能不提。程序如下:#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 DeleteFile
push UnmapViewOfFile
ret
}
return 0;
} 试试编译它,运行。怎么样?从你的眼皮底下消失了吧?是不是很神奇?Gary Nebbett 钻了系统的一个漏洞,他的程序是关闭了 exe 文件的 IMAGE(硬编码为4),然后用 UnmapViewOfFile 解除了 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除。Gary Nebbett 果然不愧为 WIN 系统下顶尖的底层高手。那么是否还有其他的方法实现程序的自删除呢?答案是肯定的。在 Win9x/ME 下,还可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一个节 [[Rename]] ,只要在里面写入要 “Nul=要删除的文件”,那么下次系统重新启动的时候,该文件就会被自动删除了。以下是一个例子:[[Rename]]
NUL=c:\SelfDelete.exe 利用这个特性,我们就可以在程序中对这个 ini 文件进行操作。值得注意的是,当需要自删除的文件多于一个的时候,就不能使用 WritePrivateProfileString 来实现,因为这个 API 会阻止多于一个“NUL=”这样的入口在同一个节里面出现,所以最好还是自己手动实现。第三种方法是利用批处理文件。先让我们做一个试验:创建一个 a.bat ,给它写入以下内容:del %0.bat 现在运行它吧,屏幕一闪而过,最后留下一串字符:“The batch file cannot be found”。这时候它已经从你的硬盘中消失了。这说明,批处理文件是可以删除自己的,于是我们可以把这个小技巧运用在自己的程序当中::Repeat
del "C:\MYDIR\SelfDelete.exe"
if exist "SelfDelete.exe" goto Repeat
rmdir "C:\MYDIR"
del "\DelUS.bat" 它会重复不断地搜索是否有 SelfDelete.exe 这个文件,直到删除了它为止;当删除完毕后,这个批处理文件就会把自己删除。
(注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)用批处理文件的方法有一个缺陷,就是会突然弹出一个 DOS 窗,冷不防的吓人一跳,不过据我所知这是目前唯一可以在 WinXP 下起作用的方法。当然,最理想的方法是用 Gary Nebbett 的那种,不过它的缺陷是没法在 WinXP 下起作用。(注:Gary Nebbett 的方法,hume已经给出了例子,所以我就不重复了,请到他的网站 http://humeasm.yeah.net/ 下载。)
以上的方法都是前辈高人的研究总结,可不是我原创的,不过最后我给出一个 Win32ASM 例子,演示一下用批处理文件删除程序自身的方法。;******************************************************
;程序名称:程序自删除示例,适用于Win9x/WinMe/Win2000/WinXP
;作者:罗聪
;日期:2002-10-23
;出处:http://www.luocong.com/(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.luocong.com/)
;******************************************************.386
.model flat, stdcall
option casemap:noneinclude \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.libDeleteExecutableBF PROTO.code
main:
invoke DeleteExecutableBF
invoke ExitProcess, NULL;********************************************
; 模块功能:用批处理文件删除自身
; 入口参数:无
; 出口参数:无
;********************************************
DeleteExecutableBF proc
LOCAL hFile :DWORD
LOCAL len :DWORD
LOCAL hHeap :DWORD
LOCAL pszUnsetupPathname :DWORD
LOCAL pszUnsetupPath :DWORD
LOCAL pszBatFilePathname :DWORD
LOCAL pBatFile :DWORD jmp nextcode szBatFileName BYTE "DelUS.bat", 0
szOpen BYTE "open", 0
szBKSlash BYTE "\", 0
L1 BYTE ":Repeat", 13, 10, 0
L2A BYTE "del """, 0
L2B BYTE """", 0
L3A BYTE 13, 10, "if exist """, 0
L3B BYTE """ goto Repeat", 13, 10, 0
L4 BYTE "rmdir """, 0
L5 BYTE """",13, 10, "del """, 0
L6 BYTE """",13, 10, 0
nextcode:
; 为字符串分配堆:
invoke GetProcessHeap
mov hHeap, eax
invoke HeapAlloc, hHeap, NULL, 4 * MAX_PATH + 1000
mov pszUnsetupPath, eax
add eax, MAX_PATH
mov pszUnsetupPath, eax
add eax, MAX_PATH
mov pszUnsetupPathname, eax
add eax, MAX_PATH
mov pszBatFilePathname, eax
add eax, MAX_PATH
mov pBatFile, eax ; 创建一个批处理文件,用于删除我们的exe文件。当exe文件被删除后,这个批处理文件会自动删除自己,以及它所在的目录。 ; 得到 temp 目录的路径:
invoke GetTempPath, MAX_PATH, pszBatFilePathname invoke lstrcat, pszBatFilePathname, addr szBatFileName
invoke CreateFile, pszBatFilePathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL
mov hFile, eax
.if (hFile != INVALID_HANDLE_value) ; 得到我们的 exe 文件的全路径(包括文件名):
invoke GetModuleFileName, NULL, pszUnsetupPathname, MAX_PATH ; 得到我们的 exe 文件的路径(不包括文件名):
invoke lstrcpy, pszUnsetupPath, pszUnsetupPathname ; 找到路径最后的 ’\’ 并把它改成0
mov edx, pszUnsetupPath
mov ecx, edx
.repeat
mov al, byte ptr [edx]
.if al == 92 ; "\"
mov ecx, edx
.endif
inc edx
.until al == 0
mov byte ptr [ecx+1], 0 ; Bat 文件的内容:
; :Repeat
; del "C:\Win95ADG\DelSelf.exe"
; if exist "DelSelf.exe" goto Repeat
; rmdir "C:\Win95ADG"
; del "c:\%temppath%\DelUS.bat"
invoke lstrcat, pBatFile, addr L1
invoke lstrcat, pBatFile, addr L2A
invoke lstrcat, pBatFile, pszUnsetupPathname
invoke lstrcat, pBatFile, addr L2B
invoke lstrcat, pBatFile, addr L3A
invoke lstrcat, pBatFile, pszUnsetupPathname
invoke lstrcat, pBatFile, addr L3B
invoke lstrcat, pBatFile, addr L4
invoke lstrcat, pBatFile, pszUnsetupPath
invoke lstrcat, pBatFile, addr L5
invoke lstrcat, pBatFile, pszBatFilePathname
invoke lstrcat, pBatFile, addr L6 ; 创建 bat 文件:
invoke lstrlen, pBatFile
mov len, eax
invoke WriteFile, hFile, pBatFile, len, addr len, NULL
invoke CloseHandle, hFile ; 现在在后台执行我们的 bat 文件:
invoke ShellExecute, NULL, addr szOpen, pszBatFilePathname, NULL, NULL, SW_HIDE .endif
; 释放堆:
invoke HeapFree, hHeap, NULL, pszUnsetupPath
return:
; 结束啦!
retDeleteExecutableBF endpend main
;******************** over ********************
;by LC
或者在BoundsChecker中运行debug版的程序,一般来说,所有的错误都可以捕捉到。
在可能出异常的地方,加上try catch,并显示或记录你的异常信息,那么就可以防止很多问题了。
remove(exeName);//exeName为自己的名字
删自己的,在linux下用GCC编译也可以。但是在VC下编译一个相同的程序就不行。