原来经典的Gary   Nebbett写的就请不要再提了,没法运行了。生成批处理的也了解了,现在就是想问问有没有别的方法可以自删除呢,主要是在VS2005 C++环境编程用到的。看到过远程线程插入,再回来删除自己,但这个主动防御都会提示。还能不能在自己的进程中自删除呢?请高人指点迷津,谢谢!

解决方案 »

  1.   

    试试这个,某大牛写的~~
    #include <windows.h>
    BOOL DeleteMyself(WCHAR *pHelper)
    {
    int ret;
    WCHAR helper[MAX_PATH];
    ZeroMemory(helper, sizeof(helper));
    if (pHelper)
    wcsncpy(helper, pHelper, MAX_PATH-2);
    else
    wcscpy(helper, L"calc.exe");
    STARTUPINFOW si = {sizeof(STARTUPINFOW),0};
    PROCESS_INFORMATION pi;
    HANDLE hSYNC = OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
    if (CreateProcessW(NULL, helper, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, π))
    {
    CONTEXT ctx = {CONTEXT_FULL,0};
    ret = GetThreadContext(pi.hThread, &ctx);
    WCHAR MyselfPath[MAX_PATH];
    int nPathLen = GetModuleFileNameW(NULL, MyselfPath, MAX_PATH);
    struct StackContext
    {
    DWORD_PTR DeleteFileW;
    DWORD_PTR WaitForSingleObject_argv1;
    DWORD_PTR WaitForSingleObject_argv2;
    DWORD_PTR ExitProcess;
    DWORD_PTR DeleteFileW_argv1;
    DWORD_PTR shit;
    DWORD_PTR ExitProcess_argv1;
    }stackctx;
    HMODULE hKernel32 = GetModuleHandleW(L"Kernel32.dll");
    ctx.Eip = (DWORD_PTR)GetProcAddress(hKernel32, "WaitForSingleObject");
    ctx.Esp = (DWORD_PTR)VirtualAllocEx(pi.hProcess, 0, 512*1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    ctx.Esp += 256*1024;
    stackctx.DeleteFileW = (DWORD_PTR)GetProcAddress(hKernel32, "DeleteFileW");
    stackctx.WaitForSingleObject_argv1 = (DWORD_PTR)hSYNC;
    stackctx.WaitForSingleObject_argv2 = (DWORD_PTR)-1;
    stackctx.ExitProcess = (DWORD_PTR)GetProcAddress(hKernel32, "ExitProcess");
    stackctx.DeleteFileW_argv1 = (DWORD_PTR)VirtualAllocEx(pi.hProcess, 0, (nPathLen+1)*sizeof(WCHAR), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    ret = WriteProcessMemory(pi.hProcess, (LPVOID)stackctx.DeleteFileW_argv1, MyselfPath, (nPathLen+1)*sizeof(WCHAR), NULL);
    if (!ret) return FALSE;
    stackctx.shit = 0;
    stackctx.ExitProcess_argv1 = 0;
    ret = WriteProcessMemory(pi.hProcess, (LPVOID)(ctx.Esp), &stackctx, sizeof(stackctx), NULL);
    if (!ret) return FALSE;
    ret = SetThreadContext(pi.hThread, &ctx);
    if (!ret) return FALSE;
    ResumeThread(pi.hThread);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return TRUE;
    }else
    {
    return FALSE;
    }
    }
    int main()
    {
    DeleteMyself(0);
    return 0;
    }
    //2000/xp/2003/vista 上已经测试通过
      

  2.   

    有办法,通过 BAT 批处理.这个流程:1. A程序运行
    2. A程序在某个目录输出一个BAT批处理文件, BAT的工作是休眠一段时间中删除A程序
    3. A程序启动BAT
    4. A程序退出.
    5. BAT命令休眠结束,删除A程序.问题的关键在于BAT的休眠时间要控制好,必须在A程序退出以后才能结束休眠.
      

  3.   

    使用bat文件是最安全可靠和可移植的。2楼抄的代码没有可移植性。
      

  4.   

    1. 还得同时删掉BAT自己
    2. 如果A的关闭事件不固定的话,可以考虑另写一个小程序来等待A结束,在A结束后删除A,生成Bat