freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

[Windows Rootkits学习]Windows驱动程序世界的HelloWorld!准备、运行...
2023-04-10 16:08:27
所属地 山东省

0x00 目的

在虚拟机内部编写驱动并加载驱动,简单的helloworld打印。基于Win11 64位主机,Win 7 X86虚拟机双机调试环境对驱动程序进行调试,对驱动下断点进行控制。

环境主机为win11 x64,虚拟机win7 x86
使用windbg进行双击调试,使用vs2010和ddk7.1。
环境请搜索自行搭建,并不是很难~

今天要做的事,应该是通往驱动大门的第一步。过程可能会出现奇奇怪怪的问题,一定要多耐心尝试!这个东西折磨了我三天。所以非常有幸能把我的经验分享给大家,让大家少走弯路。

0x01 必备软件

DDK7.1、vs2010、DebugView、DriverMonitor或者KMDmanager需要被安装。

0x02 编写helloworld驱动

1.示例代码

#include <ntddk.h>

// 退出driver
VOID DriverUnload(PDRIVER_OBJECT pDriverObject) 
{
    DbgPrint(" the driver unloaded successfully! \n");
}

// driver的入口
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING reg_path) 
{
    DbgPrint("ok, congratulation ,the driver has loaded successfully!\n");

    if(NULL != pDriverObject){
        pDriverObject->DriverUnload = DriverUnload;
	}

    return STATUS_SUCCESS;
}

我们要将上面这个代码保存为helloworld.c文件。

!INCLUDE $(NTMAKEENV)\makefile.def

将上面这个文件保存makefile文件。注意不要有前导空格,只要一行,也不要进行任何修改。

#下面这行的意思是指定生成驱动名为HelloWorld.sys
TARGETNAME=HelloWorld
#下面这行的意思是指定生成文件的类型DRIVER,也就是驱动
TARGETTYPE=DRIVER
#下面这行指定生成驱动所在的路径\SYS\HelloWorld.sys
TARGETPATH=SYS
#下面这行指定相关头文件所在目录路径
INCLUDES=$(BASEDIR)\inc;\
      $(BASEDIR)\inc\wxp;\ 

##上边必空一行H:\WINDDK3790(DDK目录) 等价$(BASEDIR)
#下面这行指定驱动源代码*.cpp或者*.c
SOURCES=HelloWorld.c\

将上面这些代码保存为Sources文件,同样不要进行修改。
文件准备好之后是如下的样子。
image

2.Build it!

如图,在开始菜单中,找到WDK的文件夹,然后Build Environment,接着Windows 7,如果是64位选择x64的,32位选择x86的。注意要右键用管理员权限运行。

小tips:x86是32位是因为像8086的86之类的,86代表初代
所以x86代表32位而不是x32代表32位,hhhh

image

接着我们使用cd命令,将目标目录调整到我们刚才存放三个文件夹的路径下面。我这里存放的路径是C:\demo。然后输入build命令,就开始build了。这里可能会遇到一些报错,需要自己排查代码有没有在复制粘贴的过程中有一些符号出问题。
image
完成之后的效果是这样的:
image

3.给我们的驱动签名

现在我们在开始的菜单栏里搜索Visual Studio Command Prompt,然后使用管理员权限打开,效果如下。

接下来我们要给我们的驱动进行签名,如果没有签名,系统是不认你的驱动的喔。

image
接着我们使用cd命令,首先到达你存放代码的目录。我这边还是C:\demo。不过在build之后,真正的驱动在C:\demo\sys\i386,如果是64位就可能是...\sys\amd64了。

对于我的情况,就是cdC:\demo\sys\i386

首先输入命令,生成cer证书文件:
makecert -r -pe -ss Ctcloud -n CN=Ctcloud.com(Test) xxx.cer
然后输入命令,对sys文件进行签名:
Signtool sign /a /v /s Ctcloud /n Ctcloud.com(Test) /t http://timestamp.verisign.com/scripts/timestamp.dll xxx.sys
image

CtcloudCtcloud.com(Test)以后我们可以自己修改。
xxx.cer中的xxx是我们自己可以修改的,是证书名称。
——————————————————————————
xxx.sysxxx也是可以自己修改的,是我们要签名的文件名,注意签名的时候要像刚才一样,
用命令cd到文件的目录下。
(如果是cat文件,则把后缀改为cat其他命令一样。)

0x03 运行HelloWorld

1.注册并启动

我们使用KMDManger,注意用管理员权限打开,因为我注册过了我就直接点Run了。没注册过的时候,按照Register -> Run -> Stop -> Unregister的操作顺序试试,如果没有报错都是Success那就可以继续往下了。

image

//如果用的是DriverMonitor,在file中导入之后点击`start …`和`stop …`效果是一样的

2.观察

打开debugview,注意用管理员权限打开。然后再次run和stop,就可以看到输出。
image

这个过程可能会busy一会,耐心等待,如果等太久还不正常,那就重启吧。

0x04 调试HelloWorld

首先我们stop我们的驱动HelloWorld,然后在windbg 上方栏目点击debug然后选中break进行点击,进而输入命令bp HelloWorld,将HelloWorld作为断点。这个时候可能会提示失败,但是不要灰心,我们直接在Manger或者Monitor启动我们的驱动HelloWorld,这个时候就会进入单步调试了
image

以下是一些单步调试中常用的命令及其作用:

p:单步执行。p加变量的话则是打印变量内容。
d:查看指定地址范围的内存内容。例如:d 0x1000 0x2000,查看从地址0x1000到0x2000的内存内容。
u:以汇编指令的形式查看指定地址处的代码。例如:u 0x401000,以汇编指令的形式查看地址0x401000处的代码。
t:查看当前线程的调用栈信息。
k:查看当前进程的调用栈信息。
r:查看或修改寄存器的值。例如:r eax,查看eax寄存器的值;r eax=0,将eax寄存器的值设置为0。
g:运行程序,直到遇到下一个断点或异常。
poi:以指定类型的形式查看指定地址处的内存内容。例如:poi 0x1000 l4,以32位整数的形式查看地址0x1000处的内存内容。
ln:查找指定地址所在的源代码行号。例如:ln 0x401000,查找地址0x401000所在的源代码行号。
dv 或 du 命令:查看局部变量或者内存地址中的数据。

r 命令:显示所有寄存器的值。

bp 命令:设置断点,可以通过地址、符号名、函数名等方式设置。

bl 命令:列出当前所有的断点信息。

ba 命令:列出所有类型的断点信息。

tcf 命令:终止程序执行。

!analyze 命令:分析程序崩溃的原因。

lm 命令:列出当前加载的所有模块信息。
!dbgprint:可以查看dbgprint的内容

要以汇编指令的形式查看代码,可以使用u命令。
如果要在u命令中指定汇编指令的数量,可以在命令后面添加一个数字。
例如,要以汇编指令的形式查看地址0x401000处的后10条指令,
可以使用命令u 0x401000 L10。

0x05 尾声

这篇文章的分享就到这里,有什么问题和不对的地方欢迎指出和一起讨论!谢谢~

# 黑客 # windows # rootkit # Windows内核 # Windows系统
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录