我是靠谱客的博主 和谐棒球,最近开发中收集的这篇文章主要介绍查看进程是否被注入线程(不在系统模块)当然,该检测是纯windows提供的API所写,某些“伪装者”可能利用一些方法,来隐藏自己。这时候需要写Windows驱动来检测,需要安装windows driver kit(WDK),这个以后再说把。,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
有些进程被注入了某些恶意的线程(也可能不是恶意的)
首先我们拿到该进程的进程模块,用来对比进程中线程的模块是否在这里面
把这些模块放入到vector里面
便利该进程的所有线程获取模块的起始地址和大小,很快就可以得到伪装线程。
#pragma region 依赖
typedef enum _THREADINFOCLASS{
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
}THREADINFOCLASS;
typedef struct _CLIENT_ID{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION{
LONG ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
LONG AffinityMask;
LONG Priority;
LONG BasePriority;
}THREAD_BASIC_INFORMATION,*PTHREAD_BASIC_INFORMATION;
extern "C" LONG (__stdcall *ZwQueryInformationThread)(
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
) = NULL;
#pragma endregion
有些API或结构体是微软未公开的,但是被某些大牛给分析出来了,就比如ZwQueryInformationThread结构体。
当然,该检测是纯windows提供的API所写,某些“伪装者”可能利用一些方法,来隐藏自己。这时候需要写Windows驱动来检测,需要安装windows driver kit(WDK),这个以后再说把。
以下是本菜手写的API检测代码。
while (Process32Next(hProcessSnap,&process)){
string s_szExeFile = process.szExeFile; // char* 转 string
//if(s_szExeFile != "QQ.exe") continue;
if(process.th32ProcessID == 0) continue;
HANDLE hThreadSnap = INVALID_HANDLE_VALUE; // 线程快照句柄
THREADENTRY32 te32; // 线程快照信息
// 创建线程快照
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE){cout << "创建线程快照失败" << endl;continue;}
// 为快照分派内存空间
te32.dwSize = sizeof(THREADENTRY32);
// 获取第一个线程的信息
if (!Thread32First(hThreadSnap, &te32)){cout << "线程信息获取失败" << endl;continue;}
// 拿进程所有模块信息
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,process.th32ProcessID);
if (INVALID_HANDLE_VALUE == hSnapshot){continue;}
MODULEENTRY32 mi;
mi.dwSize = sizeof(MODULEENTRY32);
BOOL bRet = Module32First(hSnapshot,&mi);
struct szMoudleStr{
DWORD modBaseAddr;
ULONG32 modBaseSize;
char szModule[256];
};
vector<szMoudleStr>szMoudleVec;
while (bRet){
szMoudleStr sms;
sms.modBaseAddr = (ULONG32)mi.modBaseAddr;
sms.modBaseSize = (DWORD)mi.modBaseSize;
strcpy(sms.szModule, mi.szModule);
szMoudleVec.push_back(sms);
bRet = Module32Next(hSnapshot,&mi);
}
// 遍历线程
while (Thread32Next(hThreadSnap, &te32)){
if(te32.th32OwnerProcessID == process.th32ProcessID){
HANDLE hThread = ::OpenThread (
THREAD_ALL_ACCESS, // 访问权限,THREAD_ALL_ACCESS :所有权限
FALSE, // 由此线程创建的进程不继承线程的句柄
te32.th32ThreadID // 线程 ID
);
if(hThread == NULL){
cout << "线程打开失败 :" << GetLastError() << "process:" << process.szExeFile << process.th32ProcessID << endl;
continue;
}
setlocale(LC_ALL,".ACP");
HINSTANCE hNTDLL = ::GetModuleHandle("ntdll");
(FARPROC&)ZwQueryInformationThread = ::GetProcAddress(hNTDLL,"ZwQueryInformationThread");
PVOID startaddr; // 用来接收线程入口地址
ZwQueryInformationThread(
hThread, // 线程句柄
ThreadQuerySetWin32StartAddress, // 线程信息类型,ThreadQuerySetWin32StartAddress :线程入口地址
&startaddr, // 指向缓冲区的指针
sizeof(startaddr), // 缓冲区的大小
NULL
);
int allFlag = true;
int WgFlag = 0;
int dbgFlag = true;
if(dbgFlag)cout << "startAddr :" << startaddr;
for(int i = 0; i < szMoudleVec.size(); i++){
if((ULONG32)startaddr >= szMoudleVec[i].modBaseAddr && (ULONG32)startaddr < szMoudleVec[i].modBaseAddr + szMoudleVec[i].modBaseSize){
allFlag = false;
if(dbgFlag){
printf("///modname : %s ----", szMoudleVec[i].szModule);
cout << hex << "为系统模块 ---modBaseAddr:" << szMoudleVec[i].modBaseAddr << " ,modEndAddr:" << szMoudleVec[i].modBaseAddr + szMoudleVec[i].modBaseSize << endl;
}
}else{
WgFlag = i;
}
}
if(allFlag == true){
if(dbgFlag){
printf("pid = %d不是系统模块%s", process.th32ProcessID, szMoudleVec[WgFlag].szModule);
cout << hex << "///modBaseAddr:" << szMoudleVec[WgFlag].modBaseAddr << " ,modEndAddr:" << szMoudleVec[WgFlag].modBaseAddr + szMoudleVec[WgFlag].modBaseSize << endl;
}
return true;
}
}
}
}
return false;
加油啦!
最后
以上就是和谐棒球为你收集整理的查看进程是否被注入线程(不在系统模块)当然,该检测是纯windows提供的API所写,某些“伪装者”可能利用一些方法,来隐藏自己。这时候需要写Windows驱动来检测,需要安装windows driver kit(WDK),这个以后再说把。的全部内容,希望文章能够帮你解决查看进程是否被注入线程(不在系统模块)当然,该检测是纯windows提供的API所写,某些“伪装者”可能利用一些方法,来隐藏自己。这时候需要写Windows驱动来检测,需要安装windows driver kit(WDK),这个以后再说把。所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复