用汇编写个最小的WDM驱动程序进RING0

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习阶更高效! 阅读详情

原著:wowocock
http://www.luocong.com/bbs/dispbbs.asp?boardid=2&id=3176

用汇编写个最小的WDM驱动程序进RING0
在WINDOWS 2000/XP/2003里进入RING0是很多人的梦想,但实现这个梦想并不容易,
因为基于NT内核的 WINDOWS 2000/XP/2003对自己保护得非常好,这与WINDOWS 9X
有很大不同,WINDOWS 9X的GDT,IDT,LDT等重要的系统表格是可以被RING3的代码
轻易修改的,因此在WINDOWS 9X里任何程序都可以在GDT,IDT,LDT里构造自己的
调用门/中断门/陷阱门而进入RING0。在WINDOWS 2000/XP/2003里似乎只有写驱动
才能进入RING0了,当然还可以利用系统漏洞进入RING0,本人就发现了2个漏洞可
进入RING0,但本文只讨论写驱动的方式。

现在介绍用汇编语言写普通WINDOWS应用程序的书也不少,用汇编语言写WINDOWS
程序的程序员也越来越多,但遗憾的是这些书介绍的程序都是运行在RING3上的,
我等技术追求者怎能受制于RING3而无所作为?为了写出令人惊叹的程序(比如病毒,
反病毒,防火墙等等),就必须要进入RING0。但是有关用汇编语言写WDM驱动程序
的书和例子非常少,我找到的绝大多数都是用C写的,而且编译也很麻烦,对于汇编
语言这种最适合写系统程序的语言来说是很遗憾的。为此我特意用我所知道的知识
写出本文,意在抛砖引玉,共同进步。

好了,先来看看下面的例子:

.586p
.model flat,stdcall
option casemap:none


.code
start:
nop
nop
nop
nop

pushfd
pushad

push edx
sgdt [esp-2]
pop edx
mov eax,edx
mov ecx,3e0h

.if dword ptr [edx+ecx+2]!=0ec0003e8h
mov byte ptr [edx],0c3h

mov word ptr [edx+ecx],ax
shr eax,16
mov word ptr [edx+ecx+6],ax
mov dword ptr [edx+ecx+2],0ec0003e8h

mov dword ptr [edx+ecx+8],0000ffffh
mov dword ptr [edx+ecx+12],00cf9a00h
.endif

popad
popfd

xor eax,eax
ret 8


end start


把以上的汇编代码保存到文件mywdm.asm,然后用MASM 6.14按照下面的方法编译:

ml /c /coff /Cp mywdm.asm
link /subsystem:windows /driver:wdm /release /out:mywdm.sys mywdm.obj

就会在当前目录下生成一个mywdm.sys文件,这是一个没有导入导出和资源的纯代码
驱动程序,非常短小精悍。如果导入了ntoskrnl.exe和hal.dll里的函数,或者导出
给别人调用的函数,它将是一个功能全面的WDM驱动。

mywdm.sys的功能是在GDT中创建一个3级调用门和一个0级32位代码段描述符,3级调用
门的选择子是3E3,0级32位代码段的选择子是3E8。

好了,现在执行mywdm.sys,但驱动程序是不能直接执行的,所以要构造它的执行环境。
先在注册表HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services中建立一个mywdm
子键,然后建立3个DWORD型的键值:
ErrorControl=0
Start=3 (如果Start=1,mywdm.sys会随电脑启动而自动装入)
Type=1

再把mywdm.sys复制到system32/drivers目录里,然后重新启动(好象不重新启动也可以,
对这个我不太清楚),运行net start mywdm,结果屏幕上显示:

“发生系统错误 1058。

无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动。”

如果你轻信微软的这句话的话,你就到此为止了!别被微软欺骗,因为我们的代码已经
执行过了,3级调用门和0级32位代码段描述符已经被建立在GDT中,而错误提示是在我们
的代码执行后弹出来的,此时不管是成功提示还是错误提示对我们来说都已太晚了。不信,
你可以用SOFT ICE看一看GDT就知道我所言不虚!如果Start=1,系统不会提示错误而运行
mywdm.sys。

好了,既然GDT中已经有了我们的调用门,那么意味着我们写的应用程序可以自由地在
RING3和RING0之间切换,但如何使用这个调用门还是有讲究的,它的使用方法是:

...

call 3e3:00000000 ;机器码 9A 00 00 00 00 E3 03
;此时已经进入RING0,CS=3E8,跟着要切换堆栈
mov eax,esp
mov esp,[esp+4]
push eax

;这里加入你要在RING0里执行的代码

;准备返回RING3
pop esp
push offset ring3
retf
ring3:
;此时回到RING3

...

为什么要切换堆栈?为什么要建立我们自己的0级32位代码段?直接使用操作系统的0级32位
代码段(选择子=8)不可以吗?在这里我要说明一下:WINDOWS 2000/XP/2003对自己保护得
非常好,就算普通应用程序能进入RING0,但还是在用户区(代码和数据的地址都小于80000000H),
所以WINDOWS 2000/XP/2003会认为是非法进入RING0的,就有可能产生页故障,表现是调用子程序
或访问内存时就会触发页故障,解决的方法是切换堆栈;不用操作系统的0级32位代码段(选择子
为8),用我们建立的0级32位代码段(选择子=3E8)。

本文例子生成的mywdm.sys大小是1536字节,如果你对PE文件很了解,可以手工给mywdm.sys减肥,
但要注意的是减肥后要把正确的CHECKSUM值填入PE头的CHECKSUM字段中,否则操作系统是不会装入
mywdm.sys执行的。我就把mywdm.sys减肥到只有368字节(只有DOS头,PE头+节表,60H字节的重定
位表和代码,应该是世界上最小的驱动程序了)。完全可以把这个只有368字节的驱动程序包含在
自己的程序中,在需要是把它还原到SYSTEM32/DRIVERS目录里。

计算CHECKSUM的方法是:把PE文件的所有字用ADC相加,然后得到的结果再和文件大小ADC相加,
这个结果就是CHECKSUM值。网上也可以找到计算CHECKSUM的工具。

RING3测试程序如下:
.386
.model flat, stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib

.data
szExceptionCaused db Exception Caused - could not switch to ring 0,0
szError    db Error,0
MsgCaption      db Test,0
MsgBoxText      db cr0=%8x,0
tmp db 50 dup(90)
Callgt dd 0
      dw 3e3h

.code
ExceptCallBack PROC
invoke    MessageBoxA, 0, addr szExceptionCaused,addr szError, 0
invoke ExitProcess, -1
ret
ExceptCallBack ENDP

start:  
push  offset ExceptCallBack
call   SetUnhandledExceptionFilter
call    fword ptr [Callgt]            ;use callgate to Ring0!

Ring0:
mov eax,esp   ;save ring0 esp
mov esp,[esp+4];->ring3 esp
push eax

mov eax,cr0

pop esp   ;restore ring0 esp
push offset Ring3
retf
Ring3:
invoke wsprintfA,addr tmp,addr MsgBoxText,eax
invoke MessageBox, NULL,addr tmp, addr MsgCaption, MB_OK

Exit:
invoke ExitProcess,NULL

end start
嘿嘿,大家以后就可以方便的写2K/XP/2003下的RING0病毒了。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=337881

[ 点击此处收藏本文]   jarodlau发表于 2005年04月06日 05:44:00
汇编驱动(一)——光速入门 汇编windows驱动非常简单,只要有汇编基础和用C驱动的能力即可。有了这两样基础,我们距离用汇编驱动,只剩下一层窗户纸,一戳就破。一、准备软件:Radasm        为了快速入门,好的IDE是降低入门难道的有效手段。Radasm是我最为钟爱的一款软件,第一次使用过它,我就果断地将masm32删除了。   RadASM是一款著名的WIN32汇编编辑器,精通win32汇编的人对它应该不会陌生。支持MASM、TASM等多种汇编编译器,提供优秀的IDE,自带一个资源编辑器和一个调试器(OD)。拥有较 阅读详情

相关推荐

ring0下使用内核重载绕过杀软hook

内核重载听起来是一个很高大上的概念,但其实跟PE的知识息息相关,那么为什么会有内核重载的出现呢? 我们知道从ring3ring0需要通过int2e/sysenter(syscall)ring0,而ring0之后又会通过KiFastCallEntry/KiSystemService去找SSDT表对应响应的内核函数,那么杀软会在这两个地方行重点盯防。 首先是对int2e/sysenter的盯防,我们知道大多数函数都是通过一系列的调用链,最终找到ntdll.dll里面的函数,找到调用号后通过int

hongduilanjun的博客 1602

汇编语言了个最小WDM驱动程序 ring0内核编程

用masm汇编最小WDM驱动程序 ring0内核编程

【信息科学与工程学】【数据中心】 第十九篇 MFU的优化提升方法03

等级模块类型子模块子子模块功能描述MFU影响因子优化优先级L0​算术逻辑单元(ALU)标量ALU整数ALU标量整数运算α_int = 0.1-0.3中浮点ALU标量浮点运算α_fp_scalar = 0.2-0.4中向量处理单元(VPU)SIMD单元128-bit SIMD短向量运算β_SIMD128 = 0.3-0.6高256-bit SIMD中向量运算β_SIMD256 = 0.4-0.7高512-bit SIMD长向量运算β_SIMD512 = 0.5-0.8极高矩阵处理单元(MPU)Tensor C

weixin_49199313的博客 969

Kill 360Safe delphi版

网上有c和VB的代码,故做了一个delphi的 结束360安全卫士程delphi代码

[转载]用汇编最小WDM驱动程序RING0

[function doZoom(size){ document.getElementById(zoom).style.fontSize=size+px} 字体:大 中 小] 2004年6月12日15:09星期六 原著:wowocockhttp://www.luocong.com/bbs/dispbbs.asp?boardid=2&id=3176用汇编最小WDM驱动程序R

jarodlau的专栏 1597

windows 下驱动NT和WDM 基本例子 (一)

NT /************************************************************************ * 文件名称:Driver.h * 作 者:张帆 * 完成日期:2007-11-1 ************************

linbounconstraint的专栏 1098

指令集--汇编--驱动程序-操作系统

无论AMD还是inter名牌的CPU,硬件厂商都会提供各自CPU的驱动程序,这个驱动程序是所有系统的最底层,他上层可以是操作系统,也可以是汇编语言,因此汇编语言没有操作系统也是可以运行的,或者汇编语言和操作系统没有什么关系; 指令集是最底层的指令,每个不同的硬件CPU都有特定的指令集集合; 汇编语言是直接操作指令集系统,第一点已经说过,他其实经过编译器然后转换成指令集,当然,这个编译器也是厂商提供的; 驱动程序也是依据自身的硬件设置需求,然后根据指令集完成驱动程序的开发;因此,比如I/0的一些控制方式,如.

盖世英雄 1707

基于80C51汇编/C语言的步电机驱动程序

单片机实习:用汇编或C语言在80C51单片机上编电机驱动程序

fmy_xfk的博客 3996

Linux操作系统-汇编LED驱动程序基础

标号,表示地址位置,有些指令前面可以会有标号,这样可以通过这个标号得到指令的地址,标号也可以用来表示数据地址。注意label后面的“ :”,任何一 " : "结尾的标识符都会被认为是一个标号。指令,也就是汇编指令或伪代码。注释符号注释内容伪操作用来定义一个段,使用 .section来定义一个段,每个段以段名开始,以下一段名或者文件结尾结束,汇编系统定义了一些段名:表示代码段初始化的数据段未初始化到数据段只读数据段汇编程序的默认入口标号是定义一个单字节数据定义双字节数据。

m0_61292310的博客 1456

总结RING0的方法

关于RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些RING0的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些方法都是直接利用IA32的方法,所以和操作系统应该没有多大关系,当然由于NT内核对GDT,IDT,的保护所以我们不能用这些方法,不过如果一旦突破了NT的保护,那么所有的方法就都可以使用了,其他的还有SEH等方法,我在前面的文章中也有介绍。 ---

1556

汇编语言 | 裸机驱动开发

最简例子 以流行的FS4412单片机为例,实现LED灯控制。

本末实验室 1788

汇编语言windows2000 xp驱动程序(4)--- 利用驱动程序读取硬盘序列号

汇编语言windows2000 xp驱动程序(4)--- 利用驱动程序读取硬盘序列号

64位驱动中加入汇编代码

本文介绍如何在驱动程序的C文件中调用ASM文件中导出的汇编函数 引言     Windows驱动程序使用DDK或者IFSDDK(以下简称DDK)中的Build.exe程序对源文件行编译和链接,操作时只需启动相应的DDK命令行程序,入待编译的源文件目录,执行Build命令即可得到.sys文件。     Build命令实际上是调用了一个nmake程序,nmake程序随后调用cl.exe和li

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 5908

【光纤通信】SONET/SDH WDM Networks

光网络拓扑是设计光通信网络的基础,其结构决定了网络的性能、可靠性和扩展性。图中列出了四种基本的光网络拓扑结构,每种拓扑都可以根据链路长度需求增加再生器来保持信号完整性。存在数据沿直线形路径传输。由一系列终端复用器(TM)和添加/丢弃复用器(Add-Drop Multiplexer, ADM)组成:位于城域网的边缘,主要用于接入网络的连接。:通过数字交叉连接系统(DCS)管理不同环路和传输速率之间的连接和信号转换。

weixin_62403234的博客 1292

linux内联汇编获取ring0权限,[原创]ring0 head inline hook lib

没啥子技术含量,参考了海风月影的ring3inline hook lib库,主要是简化你的编程工作量,有了此库,你不需要使用一大堆的内联汇编那个裸函数,也不需要为了堆栈破坏问题而蓝屏,目前只支持32系统……来看看到底挂钩一个函数有多简单!你可以专注的编过滤逻辑而完全不需要理会挂钩过程typedef NTSTATUS ( __stdcall *DZwCreateFile)(PHANDLE ...

weixin_36322984的博客 314

linux内联汇编获取ring0权限,gcc - 似乎违反了内联汇编规则的GCC代码,但专家认为并非如此 - 堆栈内存溢出...

我与一位专家合作,据称他的编码技能比我自己高得多,而我比我对行内汇编的理解要好得多。其中一项主张是,只要操作数作为输入约束出现,就不需要将其列出为破坏者,也不必指定该寄存器已被内联汇编程序潜在地修改了。 谈话是在其他人试图通过这种有效编码的memset实现获得帮助时发生的:void *memset(void *dest, int value, size_t count){asm volatile ...

weixin_35450735的博客 231

揭秘Windows内核——如何利用自定义驱动程序Ring3做Ring0的勾当!

最近在做图像处理(其实是利用摄像机采回来的Image行分析,从而得到目标的运动信息),既然是图像处理那就得有图像Source,没错那就是Camera,实验室的这个Camera还挺高级的,是千兆以太网接口的,呵呵,管他是什么接口——反正我们的任务就是将数据采集到指定的缓冲区内,然后再把缓冲区内的数据“显示出来”或者“分析分析”。按照常规的做法,你可能会这样申请一段缓冲区,估计编Windows

LnTigerLn的专栏 4700
上一篇: 用汇编编写屏幕保护程序
下一篇: 用汇编写系统服务程序
Simbao
博客等级 码龄24年 13粉丝 25原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值