bboyiori 发表于 2012-12-14 14:19:09

[经验贴]内核编程&内核原理学习

本帖最后由 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)));
}
比较初级,大家见笑了

马大哈 发表于 2012-12-14 17:18:41

以前学习玩SSDT HOOK时,也全是硬编码,判断一下系统版本再分支使用,哈哈.

支持!

bboyiori 发表于 2012-12-15 18:15:34

马大哈 发表于 2012-12-14 17:18 static/image/common/back.gif
以前学习玩SSDT HOOK时,也全是硬编码,判断一下系统版本再分支使用,哈哈.

支持! ...

搞内核开发如果做产品最重要的是兼容性,很考验耐心
硬编码或者简单inlinehook,做做坏事,搞搞灰色产业比较合适

马大哈 发表于 2012-12-17 11:47:37

bboyiori 发表于 2012-12-15 18:15 static/image/common/back.gif
搞内核开发如果做产品最重要的是兼容性,很考验耐心
硬编码或者简单inlinehook,做做坏事,搞搞灰色产业 ...

我主要是搞工控的东西,唯一用过一次SSDT HOOK是拦截别人程序中串口里的指令,目的是将多余的指令去除,因为硬件改动了,有些动作不需要了,但是改软件的话要太多钱,哈哈.

DevilLiao 发表于 2013-1-3 12:31:11

不错的学习经验

DevilLiao 发表于 2013-1-11 09:47:55

这两本书都好贵。。买了破产了

kk1025 发表于 2013-4-8 15:17:27

學學!
页: [1]
查看完整版本: [经验贴]内核编程&内核原理学习