- UID
- 3808
- 精华
- 积分
- 1478
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
之前小弟在网上查看论坛的时候,发现了一个帖子,是一个exe程序的运行完成后的自己删除,感觉佷感兴趣,于是想自己来写一个调用WindowsAPI和用C语言写的这个程序
我们知道Windows中当有文件处于运行状态下的时候是不能被删除的,那么一个exe程序怎么删除自己呢?
一般exe自我删除程序有很多用途,比如常见的软件的安装包,在安装完成后可以实现自己的删除,还有远一点的东西比如一些计算机病毒在实行自身的功能进行破坏后,对自身exe的删除
但是exe如何进行自我删除呢,我当时想的是自己的一个创建一个cmd进程,然后用cmd命令行的del来删除文件,但是我当时就有点萌比,怎么来创建cmd后来在cmd中模拟键盘输入命令呢,
网上百度了一些东西,其中偶有SendMessage这个函数,但是用的效果不理想,最后在换一种方式百度,发现可以直接创建一个类似"cmd echo Hello World"的进程。。额,好吧,其中一个问题解决了。
然后就是程序要运行完成后才能删除,这个东西我想到了多线程,但是这里显然不行,我上网上百度发现还有多进程,多进程好,但是我想挂起创建的cmd子进程的时候发现没有反应,也没有
GetLastError也没有显示,最后我在下午吃完了一块西瓜以后,想到了线程和进程的关系,进程的执行要靠线程,我不能挂起进程,那我挂起cmd子进程的主线程就可以了啊,ok,问题解决
代码中的程序由于是我的测试,所以什么都是可见的,要是设置成不可见的删除,那么改动三个参数就可以了,分别是去掉CREATE_NEW_CONSOLE,cmd /c ,还有去掉
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;
这两句代码。
- #include <stdlib.h>
- #include <stdio.h>
- #include <windows.h>
- void DeleteSelf(HANDLE *hProcess,HANDLE *hThread)
- {
- CHAR szExePath[MAX_PATH];
- GetModuleFileName(NULL, szExePath, MAX_PATH); //获取模块的完整路径,也就是exe的路径
- CHAR szCmdOrder[128];
- lstrcpy(szCmdOrder, "cmd /k del "); //这里的命令行要是"cmd /c del "的话是不显示cmd窗口
- lstrcat(szCmdOrder, szExePath);
- STARTUPINFO si = { sizeof(si) };
- PROCESS_INFORMATION pi;
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = TRUE;
- BOOL bRet = CreateProcess(
- NULL,
- szCmdOrder,
- NULL,
- NULL,
- FALSE,
- CREATE_NEW_CONSOLE | CREATE_SUSPENDED, //选择挂起主线程
- NULL,
- NULL,
- &si,
- &pi);
- if (!bRet)
- {
- printf("CreateProcess error:%d\n", GetLastError());
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- return;
- }
-
- //CloseHandle(pi.hThread);
- //CloseHandle(pi.hProcess);
- *hProcess = pi.hProcess; //址传递
- *hThread = pi.hThread;
- }
- int main(void)
- {
- for (int i = 0; i < 3; i++)
- {
- printf("Hello World!\n");
- }
- HANDLE hProcess;
- HANDLE hThread;
- DeleteSelf(&hProcess,&hThread);
- SetPriorityClass(hProcess, IDLE_PRIORITY_CLASS); //设置空闲时刻执行
-
- //设置本程序立刻执行
- SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
- SetPriorityClass(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
- Sleep(3 * 1000); //睡上3秒
-
- if (!ResumeThread(hThread)) //主进程执行完毕后开始执行主线程
- {
- printf("ResumeThread %d\n", GetLastError());
- }
- CloseHandle(hProcess); //关闭进程句柄
- CloseHandle(hThread); //关闭主线程句柄
- printf("程序运行完毕.\n");
- return 0;
- }
复制代码 |
|