最近期末答辯不知道寫什么好,就寫一個(gè)安全軟件吧。軟件使用驅(qū)動(dòng)和C++編寫,大概多數(shù)安全軟件都是這樣吧。
時(shí)間關(guān)系,就不說那么多了,直接入正題吧。
在此先感謝“伊麗_殺_白”、“墮落天才”、“antirootkit”等提供的優(yōu)秀文章,我只是在他們基礎(chǔ)之上修改了一下。
伊麗_殺_白 暴力搜索內(nèi)存空間檢測隱藏進(jìn)程:
http://bbs.xdnice.com/thread-377796-1-1.html墮落天才 ring0檢測隱藏進(jìn)程:
http://bbs.pediy.com/showthread.php?t=44243antirootkit 枚舉隱藏進(jìn)程for ring0(搜索內(nèi)存大法):
http://hi.baidu.com/antirootkit/blog/item/d2314b5c94772040fbf2c00b.html 原理:
大概流程圖如下,當(dāng)然我修改了部分。

下面看代碼吧,沒時(shí)間了,等下十點(diǎn)還要上課,有不明白的可以留言。我會(huì)解答的。
不過這種方法還是很容易躲過,詳細(xì)就不公布出來了,看來還是要找另外一種方法了。
#include<ntddk.h>
//EPROCESS結(jié)構(gòu)大小,我的系統(tǒng)是XP SP3,所以0x260,不過經(jīng)過測試,這里設(shè)置成比實(shí)際EPROCESS小也是沒問題的
#define EPROCESS_SIZE 0x260
#define PEB_OFFSET 0x1B0 //PEB偏移,下面就不注釋了
#define FILE_NAME_OFFSET 0x174
#define PROCESS_LINK_OFFSET 0x088
#define PROCESS_ID_OFFSET 0x084
#define EXIT_TIME_OFFSET 0x078
#define OBJECT_HEADER_SIZE 0x018
#define OBJECT_TYPE_OFFSET 0x008
ULONG ulPebAddress; //PEB地址的前半部分
ULONG ulStartAddress, ulEndAddress; //起始,結(jié)束地址
ULONG ulObjectType; //進(jìn)程對象類型
BOOLEAN IsaRealProcess(ULONG pEprocess); //該函數(shù)判斷是否真的是進(jìn)程
VOID WorkThread(IN PVOID pContext); //新開線程防止系統(tǒng)頓卡
VOID UpdateEndStartPebAddress(); //更新首尾地址和PEB地址
VOID EnumProcess(); //枚舉進(jìn)程
VOID ShowProcess(ULONG pEProcess); //顯示進(jìn)程信息
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進(jìn)程EPROCESS結(jié)構(gòu)地址,此處已經(jīng)是搜索結(jié)束處。
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結(jié)構(gòu),找到最小地址處
ulEProcessAddress = (ULONG)(((PLIST_ENTRY)(ulEProcessAddress + PROCESS_LINK_OFFSET))->Flink) - PROCESS_LINK_OFFSET;
if (ulStartAddress > ulEProcessAddress)
ulStartAddress = ulEProcessAddress;
}
}
///////////////////////////////////////////////////////
VOID EnumProcess()
{
ULONG i;
ULONG nCount = 2;
ULONG Address;
ULONG ret;
KdPrint(("-------------------------------------------\r\n"));
KdPrint(("EProcess PID ImageFileName\r\n"));
KdPrint(("-------------------------------------------\r\n"));
//系統(tǒng)空閑進(jìn)程的檢測方法有點(diǎn)特殊,只作參考
ShowProcess(*(PULONG)(ulStartAddress + PROCESS_ID_OFFSET));
//system的PEB總是零 上面的方法是枚舉不到的 不過我們用PsGetCurrentProcess就能得到了
ShowProcess(ulEndAddress);
for(i = ulStartAddress; i < ulEndAddress; i += 4) {//system進(jìn)程的EPROCESS地址就是最大值了
if (MmIsAddressValid((PVOID)i)) {
Address = *(PULONG)i;
if (( Address & 0xFFFF0000) == ulPebAddress){//每個(gè)進(jìn)程的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) //已經(jīng)結(jié)束的進(jìn)程的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;
}