Ay's Blog@CNSSUESTC

跟群内某大牛聊天笔记...... FOR PspCidTable

仅自己做备忘...


问题1.pspcidtable不是全局变量吗?咋个不能声明直接用?
结论:
因为它没有导出...  其实那个SSDT的结构能用是因为它导出了的...

问题2.(在windbg调试第三篇的补充内容那.....)

问题3.咋个,以及为什么那个HANDLE的值,TableCode的指针和对象体的指针低2位都要是0?
结论:
为了内存对齐~ 这样,内存以4字节一单位划分,指针的值是内存地址 必须能被4整除,所以指针的开始2位必须为0(必须为4的倍数) 搜索内存的时候就以4字节为单位搜索 减少搜索时间

感悟1:

       if (*(PUSHORT)cPtr == 0x35FF && *(pOpcode + 6) == 0xE8)
       {
         pPspCidTable = **(PVOID **)(pOpcode + 2);
         break;
       }
这个代码是在PsLookUpProcessByProcessId的函数内定位pspcidtable
我反了下这个PsLookUpProcessByProcessId函数

kd> uf nt!PsLookUpProcessByProcessId
nt!PsLookupProcessByProcessId:
......
805ca42e ff35e0b25580    push    dword ptr [nt!PspCidTable (8055b2e0)]
805ca434 e84bb50300      call    nt!ExMapHandleToPointer (80605984)
......

大概就是内存特征定位吧 哈哈 红色标注的地方就是pspcidtable的地址拉
也就是说在整个函数中,pspcidtable的地址前面是0xff35 后面是 0xe8
通过这个特征找到0xff35和 0xe8之间的这8字节的数据就是pspcidtable的地址
当然拉看起来不像是吧  内存存放顺序跟我们看的不一样 是以2字节为单位 压栈压进去的
所以逻辑上的顺序和内存上的顺序是正好相反的
所以红色字体以2个字节倒着排过来就是 8055b2e0
我们拿windbg看看
kd> dd pspcidtable
8055b2e0  e1000860 00000002 00000000 00000000

看 果然是pspcidtable的地址 神奇阿~~

感悟2:
记得 <<基于pspCidTable的进程检测技术>>这篇牛文里面说过获取pspcidtable的方法还有一个 就是
KdEnableDebugger->KdInitSystem->KdDebuggerDataBlock
->KDDEBUGGER_DATA32->PspCidTable
这个流程 其实跟那个PsLookUpProcessByProcessId差不多 都是内存定位
但是我们群的牛哥哥说了个更加易用的方法~

#define GetVar( x )        (*(PULONG)((*(PULONG)0xffdff034) + (ULONG)(x)))
PspCidTable = GetVar(0x80);

就这么简单....  原理很简单...  0xffdff000是KPCR这个结构变量的地址
那么0x34就是KdVersionBlock 成员变量在该结构中的偏移
但是在0xffdff034指向的地方对应有个结构_DBGKD_GET_VERSION64
可惜的是这个结构只有0x28字节大小 但是....嘿嘿  这个结构后面藏着N多超级重要的内核变量
我们的pspcidtable这个变量其实就在这个结构起始位置的0x80字节偏移处~
如此一来 我拿sp3的xp系统调试如下:
kd> dd 0xffdff034
ffdff034  80546b38 8003f400 8003f000 80042000

kd> dd 80546b38+0x80
80546bb8  8055b2e0 00000000 8055d708 00000000

kd> dd pspcidtable
8055b2e0  e1000860 00000002 00000000 00000000

其实0xffdff034指向的地方对应的结构体应该就是传说中的KDDEBUGGER_DATA32这个结构(windbg看了下说没这个符号...) 
typedef struct _KDDEBUGGER_DATA32 {
     DBGKD_DEBUG_DATA_HEADER32 Header;
     ULONG    KernBase;
     ULONG    BreakpointWithStatus;      // address of breakpoint
     ULONG    SavedContext;
     USHORT    ThCallbackStack;         // offset in thread data
     USHORT    NextCallback;          // saved pointer to next callback frame
     USHORT    FramePointer;          // saved frame pointer
     USHORT    PaeEnabled:1;
     ULONG    KiCallUserMode;         // kernel routine
     ULONG    KeUserCallbackDispatcher;    // address in ntdll

     ULONG    PsLoadedModuleList;
     ULONG    PsActiveProcessHead;
     ULONG    PspCidTable;         // <--------- What we need!!
     //...
     ULONG    MmLoadedUserImageList;
} KDDEBUGGER_DATA32, *PKDDEBUGGER_DATA32;
大概就是这样的 呵呵 里面保存着比较重要的变量比如pspcidtable PsActiveProcessHead
PsLoadedModuleList等等  重要的是这个地址貌似是硬编码进去的 也就是说好像只要是NT内核的机器这个地址是不会变的,什么?根据?嘿嘿...
据某老外文献记载:
; Start of the architecturally defined section of the PCR. This section
; may be directly addressed by vendor/platform specific HAL code and will
; not change from version to version of NT.
 
看没看没 反正我sp3上机器可以 的确是这个地址 没错



                                                                                                               __ay.字
涉及到的学习资料
http://bbs.pediy.com/showthread.php?p=13746
http://www.0GiNr.com/
http://bbs.pediy.com/showthread.php?t=73028
futo 抹句柄表
Rootkits.com  opc0de



posted on 2009-01-26 21:04 __ay 阅读(2899) 评论(1)  编辑 收藏 引用 所属分类: 操作系统&&内核

Feedback

# re: 跟群内某大牛聊天笔记...... FOR PspCidTable[未登录] 2010-03-16 18:12 xxx

西瓜很强悍。。。。。  回复  更多评论   



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理