freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录