[原创]浅谈如何使用gcc开发NT核心驱动程序

大熊猫侯佩
iOS开发领域优质创作者
博客专家认证
2008-04-11 03:00:42


一谈到在 Win NT 下开发核心驱动程序,可能不少人首先都会想到微软“正统”

的VC来。诚然,用VC 配合 WINDDK 的确工作的不错,但或许我们可以让其变

得更简单更完善一些。

其实偶一般是用 Masm32v9 + EditPlus2 编写 NT内核驱动,仅此而已。

从环境搭建的便捷性和编写代码的灵活性来说无疑这是非常高的。但汇编

终归是汇编,虽然强大,但很多事都要自己动手来做,往往很简单的功能都

要用比较“生硬”的方法来完成,比如:


;****************************************************************

.data

;****************************************************************

szenter db "enter driverentry",0

szleave db "leave driverentry",0

;****************************************************************
.code INIT
;****************************************************************

DriverEntry proc pDriverObject:PDRIVER_OBJECT,\

pusRegistryPath:PUNICODE_STRING

local status:NTSTATUS

mov status,STATUS_DEVICE_CONFIGURATION_ERROR

invoke DbgPrint,$CTA0("enter driverentry")

invoke DbgPrint,addr szenter

;do someting you want!


invoke DbgPrint,addr szleave

mov eax, status

ret

DriverEntry endp
;****************************************************************
end DriverEntry



以上是一个简单的不能再简单的Driver 模版。如君所见,连字符串放在哪个段

中也要自己亲手安排,小程序尚可忍受,一旦代码规模上去就非常不方便。我们

也可以把数据直接放在代码段中,比如:


;****************************************************************
.code INIT
;****************************************************************

DriverEntry proc pDriverObject:PDRIVER_OBJECT,\

pusRegistryPath:PUNICODE_STRING

local status:NTSTATUS

jmp Real_Start:

szenter db "enter driverentry",0
szleave db "leave driverentry",0


Real_Start:

mov status,STATUS_DEVICE_CONFIGURATION_ERROR

invoke DbgPrint,addr szenter

;do someting you want!


invoke DbgPrint,addr szleave

mov eax, status

ret

DriverEntry endp
;****************************************************************
end DriverEntry



这样一来虽然不用自己操作段,但是毕竟稍显怪异,而且变量定义和

使用还是要分开。无奈,只有用宏来解决了:


invoke DbgPrint,$CTA0("enter driverentry")

invoke DbgPrint,$CTA0("leave driverentry")




辛勤的汇编语言工作者们多么希望能向c那样简单的方式来写啊:


puts("So Cool!");



但是VC对 标准 c99 的支持并不好,咋办呢?用gcc吧(不是广告哦。)

有人可能会问gcc能写Windows下的驱动么?答案是肯定的。以下是偶

总结出的2个方法:

1 gcc.exe + ld.exe

2 gcc.exe + link.exe

前者是全部是原汁原味的gcc;而后者编译器是gcc,连接器却是MS官方的

link.exe。以下便是用 gcc 写的一个类似 ASM-Driver 的模版:


#include <stdio.h>
#include "ddk\ntddk.h"

_stdcall NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,\
PUNICODE_STRING pRegistryPath)
{
NTSTATUS status = STATUS_DEVICE_CONFIGURATION_ERROR;

DbgPrint("enter DriverEntry,I'm Hopy!\n");

DbgPrint("Leave DriverEntry,byb :)!\n");

return status;
}



简单吗?呵呵。注意开头的_stdcall一定要加,否则调用者会来平衡stack,

这会造成stack异常,从而sys必须重启后才能卸载。

活活,偶们可以利用gcc出色的代码优化功能来优化偶们的代码:

gcc -O3 -o miniDrv.obj -c miniDrv.c

注意我们并不连接只是编译,所以用 -c 选项,而且可以看见我们使用了 O3

级别的优化。

结果生成的PE文件只比用汇编生成的大几十字节,而且从逆向sys可以看到

机器码布局非常简练几乎可以和汇编的相媲美了。

总结如下:

使用gcc编写NT下的驱动十分方便,只需要

gcc 包 + MS link + 一个好用的编辑器 即可。 :)

...全文
219 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
agaric 2008-04-12
  • 打赏
  • 举报
回复
不错。
fluke 2008-04-12
  • 打赏
  • 举报
回复
应该用的mingw吧,linux gcc生成的obj文件怎么能用ms link来链接?

mark,学习 :-)
大熊猫侯佩 2008-04-11
  • 打赏
  • 举报
回复
今天太累,明后天总结吧
Wolf0403 2008-04-11
  • 打赏
  • 举报
回复
好文!置顶

另,链接步骤如何?最好能完整记录全过程,让新手直接跟踪就可以完成编写、连接、挂载全部步骤。您可以跟帖,我会帮助更新到首帖。
我啃 2008-04-11
  • 打赏
  • 举报
回复
呵呵,汇编版老大爷有幸来这里谢谢原创文,哈哈
VC在05后对标准的支持都很不错了,加上DDK和优秀的调试功能,或许用起来比较方便吧。如果再加上nugma的driverstudio近乎完美,毕竟用GCC写全要从头写起,会比较累~
看雪最近貌似驱动的文不少,有入门的有HOOK的,有兴趣的可以去看看,一堆内核HOOK的文很不错
ayw215 2008-04-11
  • 打赏
  • 举报
回复
又见mydo混c版

我是风 2008-04-11
  • 打赏
  • 举报
回复
厉害。学习。。。
sailinghz 2008-04-11
  • 打赏
  • 举报
回复
学习
过去的我 2008-04-11
  • 打赏
  • 举报
回复
sys和dll没区别,关键是pe头部的校验和, 用ms link解决了这一问题,delphi 也可以编译驱动程序,lz给出细节,顶
独孤过儿 2008-04-11
  • 打赏
  • 举报
回复
汇编版的大牛...
Oversense 2008-04-11
  • 打赏
  • 举报
回复
厉害,厉害,佩服,佩服。。。
hanb99 2008-04-11
  • 打赏
  • 举报
回复
楼主,说的细一些,比如在编译时是在Windows还是Linux环境,gcc.exe link.exe 是W版还是L版,在哪里有下的
hanb99 2008-04-11
  • 打赏
  • 举报
回复
up
babyvox1999 2008-04-11
  • 打赏
  • 举报
回复
学习
ttlyfast 2008-04-11
  • 打赏
  • 举报
回复
哈 好主意
liyuzhu_1984 2008-04-11
  • 打赏
  • 举报
回复
up

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧