[经验贴]内核编程&内核原理学习
本帖最后由 bboyiori 于 2012-12-14 14:35 编辑小弟,搞的东西比较杂,以前还搞过几天linux内核,但是都不精,现在仍在菜鸟阶段.看到论坛很多大牛发的帖子,都是有码,要水晶币,感觉这个对于我等菜菜进步帮助不大,所以想把这几天搞的东西发出来,大家技术交流下.
一.书籍+代码
《windows内核情景分析》+《windows内核原理》
WRK+win2000代码
刚开始学建议不用深入,大概知道概念,相关的代码不用深究
学习方法:内核数据结构+算法是理解win内核的不二法则
由于内核数据结构常用不常用有几十个,每个域与算法之间有紧密关系,所以大家学习的时候不必要细抠,每个数据结构的意义,只需要对整体把握,学习的深入了,自然会遇到相关的数据结构.例如进程ActiveProcessLinks链表,我的笔记如下:
typedef struct _EPROCESS {
... ...
HANDLE UniqueProcessId;
//
// Global list of all processes in the system. Processes are removed
// from this list in the object deletion routine.References to
// processes in this list must be done with ObReferenceObjectSafe
// because of this.
//
LIST_ENTRY ActiveProcessLinks;
UCHAR ImageFileName[ 16 ];
... ...
} EPROCESS, *PEPROCESS;
kd> dt nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x084 UniqueProcessId: Ptr32 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY
+0x174 ImageFileName : UChar //PsGetProcessImageFileName
先把遇到的数据结构搞熟悉,其他的忽略
二.逆向+调试 必备技能
学内核windbg基本上要不离手,
在这里说下,我以前写了简单ARK功能方法:用windbg调试一遍,验证结果,然后把调试过程写成代码
例子如下,遍历ActiveProcessLinks链表:
kd> !process(在DriverEntry使用PsGetCurrentProcess(),进程是System)
PROCESS 827b7830SessionId: noneCid: 0004 Peb: 00000000ParentCid: 0000
kd> da827b7830+174
827b79a4"System"
kd> dt nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x084 UniqueProcessId: Ptr32 Void
+0x088 ActiveProcessLinks : _LIST_ENTRY
+0x174 ImageFileName : UChar //PsGetProcessImageFileName
(取下一个EPROCESS 地址)
kd> ? poi(827b7830+88h)-88
Evaluate expression: -2110435296 = 82355020
(验证正确)
kd> !object 8212dcf8
Object: 8212dcf8Type: (827b7e70) Process
ObjectHeader: 8212dce0 (old version)
HandleCount: 3PointerCount: 167
kd> da 8212dcf8+174
8212de6c"csrss.exe"
写代码就比较简单了,这里硬编码不太好,不过初学者可以先试试NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pCurrentEProc;
PEPROCESS pNextEProce;
PVOID lpAdress = NULL;
PVOID lpOldAddress = NULL;
int i = 0;
pCurrentEProc = PsGetCurrentProcess();
lpAdress = (PVOID)((ULONG)pCurrentEProc + 0x88);
lpOldAddress = lpAdress;
//3页表法
for(i = 0; i < 3 * PAGE_SIZE; i++)
{
if(!strncmp("System", (PCHAR)pCurrentEProc+i, strlen("System")))
{
break;
}
}
KdPrint(("offset %0x\n",i));
do
{
GetProcessInfo(lpOldAddress);
lpOldAddress = *(PVOID*)lpOldAddress;
} while ( lpAdress != lpOldAddress);
DriverObject->DriverUnload = EprocessUnload;
return status;
}
VOID GetProcessInfo(PVOID lpAddress)
{
PVOID lpEprocess =(PVOID)((ULONG)lpAddress - 0x88);
KdPrint(("FileImageName: %s\n", (char *)((ULONG)lpEprocess + 0x174 )));
KdPrint(("DirectoryTableBase: %p\n", *(PVOID *)((ULONG)lpEprocess +0x18)));
}
比较初级,大家见笑了 以前学习玩SSDT HOOK时,也全是硬编码,判断一下系统版本再分支使用,哈哈.
支持! 马大哈 发表于 2012-12-14 17:18 static/image/common/back.gif
以前学习玩SSDT HOOK时,也全是硬编码,判断一下系统版本再分支使用,哈哈.
支持! ...
搞内核开发如果做产品最重要的是兼容性,很考验耐心
硬编码或者简单inlinehook,做做坏事,搞搞灰色产业比较合适 bboyiori 发表于 2012-12-15 18:15 static/image/common/back.gif
搞内核开发如果做产品最重要的是兼容性,很考验耐心
硬编码或者简单inlinehook,做做坏事,搞搞灰色产业 ...
我主要是搞工控的东西,唯一用过一次SSDT HOOK是拦截别人程序中串口里的指令,目的是将多余的指令去除,因为硬件改动了,有些动作不需要了,但是改软件的话要太多钱,哈哈. 不错的学习经验 这两本书都好贵。。买了破产了 學學!
页:
[1]