作者:wzt
原文鏈接:https://mp.weixin.qq.com/s/08KHfzVltDu3rwZefJ98-Q
NT內核在創建進程時,會將自身插入到nt!PsActiveProcessHead鏈表中,它保存的是當前系統中活躍的進程鏈表。
NTSTATUS
PspCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess OPTIONAL,
IN ULONG Flags,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN ULONG JobMemberLevel
)
{
PspLockProcessList (CurrentThread);
InsertTailList (&PsActiveProcessHead, &Process->ActiveProcessLinks);
PspUnlockProcessList (CurrentThread);
}
在kd查看下相關的數據結構信息:
0: kd> dt nt!_eprocess
+0x2e8 UniqueProcessId : Ptr64 Void
+0x2f0 ActiveProcessLinks : _LIST_ENTRY
Win32 api就是通過調用nt!NtQueryInformationProcess函數獲取系統的進程列表,所以隱藏進程的一個思路就是將目標進程從nt!PsActiveProcessHead鏈表中摘除。
首先看下,如何編寫kd腳本,來輸出全部的進程列表:
r $t1=$proc;
r @$t2=@$t1;
.while (@$t1 != poi(@$t2+0x2f0)-0x2f0)
{
.printf "%ma\n", @$t2+0x450;
r @$t2=poi(@$t2+0x2f0)-0x2f0
}
PsActiveProcessHead是一個雙向循環列表,因此只要知道一個節點的地址,就能循環遍歷處所有的節點。
$proc 在kd環境中保存的是當前進程的eprocess地址。
Poi(@$t2+0x2f) 為Process->ActiveProcessLinks地址,poi函數用于取地址中的值,類似于c的取指針值操作。Poi(@$t2+0x2f)得到的就是當前節點的下一個節點地址。
那么刪除雙向鏈表中的節點,就可以使用如下腳本:
$$ 準備遍歷PsActiveProcessHead鏈表
r @$t1=nt!PsActiveProcessHead;
r @$t2=poi($t1);
.while (@$t2 != @$t1)
{
$$ 判斷是否是需要隱藏的進程號
.if (poi(@$t2-0x8) == 0n532)
{
.printf "start hide process %ma(%d)\n", @$t2-0x2f0+0x450,poi(@$t2-0x8) ;
$$ 刪除鏈表節點
eq poi(@$t2)+0x8 poi(@$t2+0x8)
eq poi(@$t2+0x8) poi(@$t2)
.break
}
$$ 獲取下一節點
r @$t2=poi(@$t2)
}
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1611/
暫無評論