目录存档: 内核驱动

16

[调试笔记]x86页式内存管理(NOPAE)

这两天看了下x86内存分页机制,调试之后大概弄懂了,发出来做个笔记。

0.测试代码

ULONG TestVar = 123456;   // Global Variable
KdPrint(("VirtualAddress: %X\nPhysicalAddress: %X", &TestVar, PhyAddress));   // in DriverEntry

WINDBG输出如下

00000003    35.10139084    VirtualAddress: F889B000    
00000004    35.10139084    PhysicalAddress: 338A000

 

1.物理内存定位
DirBase=CR3,保存着当前进程的页目录表基址

lkd> dd F889B000
f889b000  0001e240 f8891597 0776ea68 00000000
f889b010  00000000 00000000 00000000 00000000
f889b020  00000000 00000000 00000000 00000000
f889b030  00000000 00000000 00000000 00000000
f889b040 

[……]阅读全文

31

WDK驱动开发使用C++模板实现动态存储类CLinkList

WDK支持C++编译,但大多数人写驱动还是习惯用纯C甚至C/C++滥用…最近写一个小项目,驱动代码我则尝试了完全使用C++来实现,之后我发现,即便是驱动开发,C++也要比纯C语言方便得多。虽然内核里没有STL,但是WDK仍支持C++的很多特性,类、重载、模板,以及多态的很多特性,都可以正常使用(当然..我也只是个C++初学者,很多高级功能并没有尝试)。

在内核编程时,很多时候我们要遍历一些内核里的数据结构并做记录,而这些数据的大小通常是动态的,我们在开始遍历时并不知道储存他们的记录要占用多大空间。面对这种问题,最简单的有两个解决方法:

1.分配一个足够大的内存,保证能存储下数据(大多数情况下会浪费很多空间)

2.预先遍历一遍并记录总大小,然后再遍历一次进行记录(毫无疑问地效率低)

以上两种简单的方法都有不可忽视的缺陷,所以我们要用稍高级一些的数据结构来解决这个问题,针对此问题的一个“完美”的解决方案就是动态链表。因为动态链表是不受空间限制的,而且随用随分配,非常好使。于是我建立了一个动态链表来保存我遍历到的数据,效果的确令我满意。但是,一天之后问题就来了,我又要遍历一类新的数据,也不得不采用链表这种动态存储方案。也就是说我又要把相似的代码重写一遍,而且链表的各种操作还不是闭着眼睛就能写好的。这样做无疑是非常不可取的。学习C++之前我对这个问题无可奈何,但现在我掌握了C++的模板机制,使用模板正好可以解决这个代码冗余的问题。于是我便写了一个内核下的动态存储类,方便记录各种类型的数据。下面把代码分享一下,并用一个简单地示例来演示它的使用方法。不过在这之前,要先介绍一下内核编程中的动态内存分配。

 

[……]阅读全文

30

EPROCESS劫持

昨天见群里有人提起,今天就随便写了一下。把PspCidTable中指定进程的Object改成一个自己构造的Object,从而使RING3的各种句 柄操作无效。一开始还没明白跟直接修改EPROCESS有什么区别,后来发现劫持EPROCESS更有针对性,而且比DKOM更稳定一些。很老很简单的技 术,没啥亮点。其实主要还是为了研究一下PspCidTable的稀疏数组结构,以前掌握很多理论但一直没写码遍历过这个表,今天总算是给弄明白了~之后 再看页表的结构应该也更容易理解了。代码贴上来做个记录。
 

[代码如下]
//===================头文件===================//
#include "stdafx.h"

 

//===================结构体声明===================//
typedef struct _HANDLE_TABLE_ENTRY {
    union {
        VOID* Object;
        ULONG32 ObAttributes;
        struct _HANDLE_TABLE_ENTRY_INFO* InfoTable;
 &nbs

[……]阅读全文

21

“RING3″过主防读物理内存、读写IO端口

最近拜读了王爽老师的《汇编语言》,学到了不少东西,终于能勉强逆点简单的小程序了。于是想到了Extreme神犇很早以前提出的这个点子:调用带正规签名的驱动来干坏事- –

鲁大师有正规数字签名,所以它的驱动加载时不会被主防报警,而鲁大师驱动里也没有验证调用者,所以可以利用~

以前ASM完全不懂,用IDA只会F5,一看IoDispatchControl就苦逼了,所以一直搞不定(F5的话,SystemBuffer显示成一个什么.Type,完全驴唇不对马嘴,可怕- -||)

 

于是逆了ComputerZ.sys

一开始我直接拿安装的旧版逆,结果基本接口搞得差不多了之后发现新版的360硬件大师驱动更新了= =旧的没用了。。而内部实现也有变化然后苦逼了,又下了个新的360硬件大师

果然360还是考虑得周到些,加入了SeTokenIsAdmin权限验证,调用Function时对参数的检查也严格了些,不过还是没有验证调用者XD

最后鼓捣鼓捣还是成功了

下面是我逆出的伪码(为啥说是伪码呢?因为我就是边看反汇编边翻译。。只逆了一些关键的接口,没除错,编译不能,所以只能用来看看思路,说是C代码有点对不起观众- -||   逆得很挫,大牛见笑了。。):

#include <ntddk.h>

BOOLEAN read_port_uchar(USHORT usPort, PULONG buffer)
{
    if (!is_port_legal(usPort)) {
    &n

[……]阅读全文