设为首页收藏本站

SKY外语、计算机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6983|回复: 0
打印 上一主题 下一主题

VB写驱动第二季之VB驱动完整版(包括创建设备和应用层通信)原理代码大公开

[复制链接]

60

主题

8

好友

1161

积分

金牌会员

Rank: 6Rank: 6

生肖
星座
处女座
性别

最佳新人 活跃会员 灌水之王 论坛元老

跳转到指定楼层
楼主
发表于 2012-5-14 19:35:58 |只看该作者 |倒序浏览
本帖最后由 sky_yx 于 2015-12-30 14:23 编辑

自从以前研究过download发现的VB写驱后觉得VB写功能完善的驱动是可能的,但是一直懒得研究。另外今年简直是倒霉透了,最近还大病一场,因为病工作也没了,现在家养病两三个月了,真的是闲的蛋疼,然后就研究起了这个东西~~~
另外本人顺带求职,本人除了vb VC也会还有其他一些杂七杂八的  
如果有成都公司不嫌弃的话 给个投简历的机会~~~(外省的就算了)


所有定义的函数必须严格定义参数和返回值,每个函数必须都有返回值,绝对不能用字符串或者数组做参数和返回值,在非必要情况下尽量使用long做参数和返回,可以使用自定义类型,但是类型里面不能包含字符串或者数组(可以利用SafeArray做指针另说)
b)
在程序中绝对不能使用字符串变量,可以使用字符串常量直接传给Dbgpint(但是变量绝对不行),不能直接使用数组 切记~
c)
可以利用SafeArray做指针,但是这个指针必须定义为全局变量,不能做局部变量(具体怎么使用后面讲).
d)
VB中的Lenb类似于C的宏,不会隐含调用VB内部函数,可以直接使用
e)
Lenb以为只能使用vbddklib里面的函数,vbddklib里面包含了部分基本的函数(其他的内核函数自行添加),绝对不能使用val,strVB自带函数.
要想实现具体的功能还必须调用内核api,但是直接Declare的API也是不行的,得用TLB封装,这样才不会产生vbaSetSystemError调用(关于这个tlb以及odl原文件后面会提供).
要写驱动那必然离不开指针,要用指针就离不开vb自带函数varptr,但是要进内核这个东西绝对是不允许的,但是不用又不行.最经典的来了,我翻遍内核的各种函数,我终于发现了VarPtr的内核版:RtlConvertUlongToLargeInteger.其汇编代码为
.text:00404E0C mov eax, [esp+4]
.text:00404E10 xor edx, edx
.text:00404E12 retn 4
代码仅仅比VarPtr多了一条xor edx, edx指令,功能完全和varptr一样,我已经把这个函数封装在了VBDDK里面重命名为KernelVarPtr,ring3下的各种常用函数(RtlMoveMemory之类的)内核里面都有,有了地址和RtlMoveMemory基本上我们就无所不能了.
到了这个地步VB驱动在内核做一些基本操作是没有问题了,但是我们还看不到驱动的运行状态,最重要的是我们有时候希望输出一些调试信息。我翻遍ddk发现只有DbgPrint是做这个事的,杯具的是这个函数的调用方式是cdecl而stdcall,我苦恼两天后我又想了招经典的方法,将RtlConvertUlongToLargeInteger定义为无参数的Pop4b(),DbgPrint有多少个参数就调用多少次pop4b,完美无错~~~比如:

DbgPrint DBGPRINT_UCHAR, "Helloworld! i'm VB programmer!"
Pop4B
Pop4B

自此VB驱动有了指针,有了调试信息,理想的状况下驱动就能运行了.但是往往有时候不是这么理想,写驱动动不动就是蓝屏,而且VB写驱动蓝的更厉害。所以强烈推荐安装的工具有如下:
虚拟机+windbg:进行双机调试,在驱动调试问题上,VB这里比用delphi写驱动强一点,因为VB可以进行源码级调试(delphi似乎只能调试汇编),要源码调试需在编译的时候设置产生符号化调试信息并在windbg设置好符号路径.还有断点,如果要下断点,那就就指定的地方调用DbgBreakPoint就可以了,只能在调试状态下 不然就蓝屏.

IDA:静态反汇编工具,可以看看生成的代码里面有没有问题,有没有调用隐含的函数。
Dbgview:查看输出的调试字符串(DbgPrint输出的内容)
各种驱动加载工具
另关于如何双机调试,如何IDA的各种教程和信息,网络上已经是发烂的东西.请自行搜索
关于使用safearray实现指针访问:
在代码里面可以看到如下结构
Public TypePDRIVER_OBJECT
pData() As DRIVER_OBJECT
safearray As rawSAFEARRAY
End Type
这是一个定义的DRIVER_OBJECT指针类型,指针类型必须用InitSafeArray2初始化如:
InitSafeArray2KernelVarPtr(pDriver), pDriver.safearray, 60

Public FunctionInitSafeArray2(ByVal pArray As Long, ByRef safearray As rawSAFEARRAY, ByValitemSize As Long) As Long
Dim tmp As Long
safearray.cDims = 1
safearray.cbElements = itemSize
safearray.rgsabound.cElements = 1
tmp = KernelVarPtr(safearray)
RtlMoveMemory ByVal pArray, tmp, 4
End Function

初始化后是一个空指针,空指针是不能用的,必须指向一个地址
pDriver.safearray.pvData= DriverObject’ DriverObject是地址

然后就可以通过pDriver.pData(0)访问数据,比如:
pDriver.pData(0).DriverUnload= ReturnValue(AddressOf DriverUnload)

注意的是这种类型不能定义为局部变量,否则会因为有数组的原因导致有隐含的VB内部函数导入.定义为全局变量就没有问题

最后 放代码和编译插件

Link是编译插件 把VB的命名为link2.exe
DrverTest是VB驱动的代码,里面有创建设备对象,ring0和ring3通信,输出调试信息等基本操作
vbntDDK.tlb就是VB的ddk 需引用
其他的就是小工具.
由于本人比较马虎,所以可能有某些错误,本代码仅供研究学习使用,由此代码和工具引发的一切问题后果本人概不负责

补充内容 (2011-11-4 14:17):

分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
分享淘帖0 收藏收藏0 评分评分
你老婆要生了。我要当爹了
您需要登录后才可以回帖 登录 | 立即注册


手机版|SKY外语计算机学习 ( 粤ICP备12031577 )    

GMT+8, 2024-4-26 19:10 , Processed in 0.130420 second(s), 27 queries .

回顶部