ring0级暴力搜索内存检测系统隐藏进程(或Rootkit)
ring0级暴力搜索内存检测系统隐藏进程(或Rootkit)
#include<ntddk.h>
//EPROCESS结构大小,我的系统是XP SP3,所以0x260,不过经过测试,这里设置成比实际EPROCESS小也是没问题的
#defineEPROCESS_SIZE 0x260
#definePEB_OFFSET 0x1B0 //PEB偏移,下面就不注释了
#defineFILE_NAME_OFFSET 0x174
#definePROCESS_LINK_OFFSET 0x088
#definePROCESS_ID_OFFSET 0x084
#defineEXIT_TIME_OFFSET 0x078
#defineOBJECT_HEADER_SIZE0x018
#defineOBJECT_TYPE_OFFSET0x008
ULONG ulPebAddress; //PEB地址的前半部分
ULONG ulStartAddress, ulEndAddress; //起始,结束地址
ULONG ulObjectType; //进程对象类型
BOOLEAN IsaRealProcess(ULONG pEprocess); //该函数判断是否真的是进程
VOID WorkThread(IN PVOID pContext); //新开线程防止系统顿卡
VOID UpdateEndStartPebAddress(); //更新首尾地址和PEB地址
VOID EnumProcess(); //枚举进程
VOID ShowProcess(ULONG pEProcess); //显示进程信息
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
HANDLE hThread;
DriverObject -> DriverUnload = OnUnload;
UpdateEndStartPebAddress();
ulObjectType = *(PULONG)((ULONG)ulEndAddress - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET);
PsCreateSystemThread(&hThread,
(ACCESS_MASK)0,
NULL,
(HANDLE)0,
NULL,
WorkThread,
NULL );
return STATUS_SUCCESS;
}
VOID WorkThread(IN PVOID pContext)
{
EnumProcess();
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID UpdateEndStartPebAddress()
{
ULONG ulEProcessAddress = (ULONG)IoGetCurrentProcess();
ULONG pEProcess;
//IoGetCurrentProcess返回的是System进程EPROCESS结构地址,此处已经是搜索结束处。
ulStartAddress = ulEndAddress = ulEProcessAddress;
ulEProcessAddress = (ULONG)(((PLIST_ENTRY)(ulEProcessAddress + PROCESS_LINK_OFFSET))->Flink) - PROCESS_LINK_OFFSET;
ulPebAddress = *(PULONG)(ulEProcessAddress + PEB_OFFSET) & 0xFFFF0000;
while (ulEProcessAddress != ulEndAddress)
{ //遍历EPROCESS结构,找到最小地址处
ulEProcessAddress = (ULONG)(((PLIST_ENTRY)(ulEProcessAddress + PROCESS_LINK_OFFSET))->Flink) - PROCESS_LINK_OFFSET;
if (ulStartAddress > ulEProcessAddress)
ulStartAddress = ulEProcessAddress;
}
}
VOID EnumProcess()
{
ULONGi;
ULONG nCount = 2;
ULONGAddress;
ULONGret;
KdPrint(("-------------------------------------------\r\n"));
KdPrint(("EProcess PID ImageFileName\r\n"));
KdPrint(("-------------------------------------------\r\n"));
//系统空闲进程的检测方法有点特殊,只作参考
ShowProcess(*(PULONG)(ulStartAddress + PROCESS_ID_OFFSET));
//system的PEB总是零 上面的方法是枚举不到的 不过我们用PsGetCurrentProcess就能得到了
ShowProcess(ulEndAddress);
for(i = ulStartAddress; i < ulEndAddress; i += 4) {//system进程的EPROCESS地址就是最大值了
if (MmIsAddressValid((PVOID)i)) {
Address = *(PULONG)i;
if (( Address & 0xFFFF0000) == ulPebAddress){//每个进程的PEB地址都是在差不多的地方,地址前半部分是相同的
if (IsaRealProcess(i)) {
ShowProcess(i - PEB_OFFSET);
i -= 4;
i += EPROCESS_SIZE;
nCount ++;
}
}
} else {
i -= 4;
i += 0x5000000;//5M
}
}
KdPrint(("-------------------------------------------\r\n"));
KdPrint(("===== Total Processes count:%3d =======\r\n", nCount));
KdPrint(("-------------------------------------------\r\n"));
}
VOID ShowProcess(ULONG pEProcess)
{
PLARGE_INTEGER ExitTime;
ULONG PID;
PUCHAR pFileName;
ExitTime = (PLARGE_INTEGER)(pEProcess + EXIT_TIME_OFFSET);
if(ExitTime->QuadPart != 0) //已经结束的进程的ExitTime为非零
return ;
PID = *(PULONG)(pEProcess + PROCESS_ID_OFFSET);
pFileName = (PUCHAR)(pEProcess + FILE_NAME_OFFSET);
KdPrint(("0x%08X%04d %s\r\n",pEProcess,PID,pFileName));
}
BOOLEAN IsaRealProcess(ULONG pEprocess)
{
NTSTATUS STATUS;
PUNICODE_STRING pUnicode;
UNICODE_STRING Process;
ULONG pObjectType;
ULONG ObjectTypeAddress;
if (!MmIsAddressValid((PVOID)(pEprocess - PEB_OFFSET)))
return FALSE;
ObjectTypeAddress = pEprocess - PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET ;
if (MmIsAddressValid((PVOID)ObjectTypeAddress)) {
pObjectType = *(PULONG)ObjectTypeAddress;
} else {
return FALSE;
}
if(ulObjectType == pObjectType) {//确定ObjectType是Process类型
return TRUE;
}
return FALSE;
}
页:
[1]