首页
社区
课程
招聘
来段美国Arkon大牛写的自杀代码,有兴趣的可以研究下
发表于: 2004-9-12 10:49 13322

来段美国Arkon大牛写的自杀代码,有兴趣的可以研究下

2004-9-12 10:49
13322
#include <windows.h>
#include <stdio.h>

struct _RemoteData {
  CHAR moduleName[MAX_PATH];
  DWORD processID;
  HANDLE (__stdcall *OpenProcessPtr)(DWORD, BOOL, DWORD);
  DWORD (__stdcall *WaitForSingleObjectPtr)(HANDLE, DWORD);
  BOOL (__stdcall *CloseHandlePtr)(HANDLE);
  BOOL (__stdcall *DeleteFilePtr)(LPCTSTR);
  void (__stdcall *SleepPtr)(DWORD);
  void (__stdcall *ExitProcessPtr)(UINT);
};

// Allocation size for the InjectedThreadProc in the host process.
// Well, you can use some hacks to calc the function size in runtime, I leave it for you.
#define MAX_CODE_SIZE 1024

DWORD WINAPI InjectedThreadProc(_RemoteData* rd)
{
        HANDLE hProcess = NULL;
        // Open the process we want to delete its file, the one who injected this code...
        if (hProcess = rd->OpenProcessPtr(PROCESS_ALL_ACCESS, FALSE, rd->processID)) {
                // Wait 'till it finishes executing.
                rd->WaitForSingleObjectPtr(hProcess, INFINITE);
                // Close handle to it.
                rd->CloseHandlePtr(hProcess);
        }
        // Delete process's executable file, sleep a bit and retry if required...?
        while (!rd->DeleteFilePtr(rd->moduleName)) rd->SleepPtr(1000);
        // Kill host also.
        rd->ExitProcessPtr(0);
        return 0;
}

int InjectCode()
{
        int rc = -1;
        SIZE_T dummy = 0;
        LPVOID codeAddr = NULL;
        HANDLE hProcess = NULL, hThread = NULL;

        _RemoteData rd = {0};
        CONTEXT cntxt = {0};

        STARTUPINFO sui = {0};
        PROCESS_INFORMATION pi = {0};
        sui.cb = sizeof(STARTUPINFO);
        // Create a host process that will run our code.
        if (!CreateProcess(NULL, "notepad.exe", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED, NULL, NULL, &sui, &pi)) {
                rc = 1;
                goto cleanup;
        }
        // Luckily, PROCESS_INFORMATION returns to us precious handles...
        hProcess = pi.hProcess;
        hThread = pi.hThread;

        // Allocate some memory for our thread function to be copied to the host process.
        codeAddr = VirtualAllocEx(hProcess, NULL, MAX_CODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // XRW
        if (!codeAddr) {
                rc = 2;
                goto cleanup;
        }

        // Get pointers to required functions.
        rd.OpenProcessPtr = OpenProcess;
        rd.WaitForSingleObjectPtr = WaitForSingleObject;
        rd.CloseHandlePtr = CloseHandle;
        rd.DeleteFilePtr = DeleteFile;
        rd.SleepPtr = Sleep;
        rd.ExitProcessPtr = ExitProcess;

        // Pass our own process ID so the remote thread can wait for us to terminate.
        rd.processID = GetCurrentProcessId();
        // Get our own executable path name so the remote thread can later delete us.
        GetModuleFileName(NULL, rd.moduleName, MAX_PATH);

        // Write the CODE into the process!
        if (!WriteProcessMemory(hProcess, codeAddr, (LPVOID)&InjectedThreadProc, MAX_CODE_SIZE, &dummy)) {
                rc = 3;
                goto cleanup;
        }
        if (dummy != MAX_CODE_SIZE) {
                rc = 4;
                goto cleanup;
        }

        // Get remote thread's context, so we can use it for our needs.
        cntxt.ContextFlags = CONTEXT_FULL; // We actually need ESP and EIP.
        if (!GetThreadContext(hThread, &cntxt)) {
                rc = 5;
                goto cleanup;
        }
        // Change the EIP to point to the thread procedure we copied earlier.
        // So when we assume running, our code will immediately start running.
        cntxt.Eip = (DWORD)codeAddr;

        // Every thread function gets one argument, this will be a pointer to _RemoteData structure.
        // Put the structure on the stack so the remote thread will be able to use it, make sure it's 4 bytes aligned!
        cntxt.Esp -= sizeof(_RemoteData); // Make some room.
        // Write it into the host process' stack space.
        if (!WriteProcessMemory(hProcess, (LPVOID)cntxt.Esp, (LPVOID)&rd, sizeof(_RemoteData), &dummy)) {
                rc = 6;
                goto cleanup;
        }
        if (dummy != sizeof(_RemoteData)) {
                rc = 7;
                goto cleanup;
        }

        // Now PUSH the ESP to point to the structure we copied above.
        // Just as pushing a pointer to rd so the remote thread will POP(or whatever usage of ESP) this pointer as its argument and use it...
        // cntxt.Esp points by now to our copied structure.
        // Making more room for the pointer itself on the stack and writing it.
        if (!WriteProcessMemory(hProcess, (LPVOID)(cntxt.Esp - sizeof(DWORD)), (LPVOID)&cntxt.Esp, sizeof(DWORD), &dummy)) {
                rc = 8;
                goto cleanup;
        }
        if (dummy != sizeof(DWORD)) {
                rc = 9;
                goto cleanup;
        }

        // Remember that ESP is always advanced by one DWORD after a push, something like atomic: mov [esp], dwVal; sub esp, 4.
        // Advance it twice, because of the last WriteProcessMemory.
        cntxt.Esp -= sizeof(DWORD)*2;

        // After we've set everything correctly in place, set the remote thread's context to the changed one.
        if (!SetThreadContext(hThread, &cntxt)) {
                rc = 10;
                goto cleanup;
        }
        // Now the thread will RESUME running from our copied code using the pointer to rd we copied to stack.
        if (!ResumeThread(hThread)) {
                rc = 11;
                goto cleanup;
        }

        rc = 0;
cleanup:
        // Oh no? (@_@) I'm looking at the error code!
        if (pi.hProcess) CloseHandle(pi.hProcess);
        if (pi.hThread) CloseHandle(pi.hThread);
        return rc;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCommandLine, int nCmdshow)
{
        if (InjectCode() != 0) {
                MessageBox(NULL, "Cannot inject code to host process!", "Self Deleting Executable!", MB_OK);
                return -1;
        }
        MessageBox(NULL, "Do whatever you want here,\r\nthread is blocked on us.", "Self Deleting Executable!", MB_OK);
        return 0;
}

[课程]Linux pwn 探索篇!

收藏
免费 1
支持
分享
最新回复 (24)
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
程序的思想比较简单: 要自杀的程序 A ,在其他的程序 B 中创建一个线程,该线程等待 A 程序结束,如果结束了,那么就把 A 程序 delete 了
2004-9-12 13:49
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
3
学习
有些利用堆栈达到这个目的.更简单
2004-9-12 13:54
0
雪    币: 233
活跃值: (43)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
程序值得改进的地方:在注入删除代码后,再注入必要的数据,然后可以采用远程线程的方法,这样可使代码更可读,避免了修改线程上下文的麻烦。虽然远程线程大部分被病毒所使用,但在这应用却是恰到好处。
2004-9-13 09:05
0
雪    币: 226
活跃值: (330)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
手段太粗劣了
网上有自删除程序的代码。
最初是windows native api的作者写的。
改一下可以用于win98-win2k3的所有系统。
2005-1-8 00:35
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
网上的那个大师的代码只能在windows 2000上使用

xp / 2003 不行, 远程线程注入是一个比较好通用的办法了
2005-5-13 00:25
0
雪    币: 342
活跃值: (323)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
7
支持啊.我特来跟贴
2005-5-14 11:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
嗯,谢谢提供。
2005-5-14 13:35
0
雪    币: 93908
活跃值: (200199)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习
2005-5-14 13:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习学习!
2005-5-16 13:40
0
雪    币: 223
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
怕怕怕
不玩
2005-5-18 15:05
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
够深噢的!不赶恭维!
2005-5-19 09:43
0
雪    币: 226
活跃值: (330)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
13
最初由 luoluo 发布
网上的那个大师的代码只能在windows 2000上使用

xp / 2003 不行, 远程线程注入是一个比较好通用的办法了

废话,你不改的话当然只有win2K可以用。
网上可以找到如何修改以使它适应win98,
改一改,win98-win2k3通吃。
winxp和win2k3是我想出来的。
试验成功了,不过代码我现在找不到了,找到了可以贴出来!
2005-5-19 16:12
0
雪    币: 221
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
赶紧找,呵呵
2005-5-20 21:04
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
研究研究。
编译完后,自删除失败。
win2kserver.
2005-9-8 20:56
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
有意思,学习了
2005-9-11 20:14
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
17
学习!
2005-9-12 21:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
看不懂啊 唉
2005-9-16 09:13
0
雪    币: 212
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
有点弄明白是怎么一回事了
2005-10-1 10:09
0
雪    币: 216
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
下载,慢慢看
2005-10-23 13:30
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
学习
2005-11-3 16:19
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
最初由 goldenegg 发布

废话,你不改的话当然只有win2K可以用。
网上可以找到如何修改以使它适应win98,
改一改,win98-win2k3通吃。
winxp和win2k3是我想出来的。
........


说说你改的思路?
2005-11-4 22:23
0
雪    币: 226
活跃值: (330)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
23
最初由 yusjck 发布


说说你改的思路?

不难,在xp/2k3下,那个handle的值不是4
只要遍历所有handle,找出来关掉即可。
2005-11-7 13:20
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
这样啊,不知道如何遍历HANDLE,希望有机会能看看你的代码
2005-11-7 20:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
学习 学习学习
2005-11-10 20:25
0
游客
登录 | 注册 方可回帖
返回
//