SKY外语计算机学习
标题: VB写驱动第二季之VB驱动完整版(包括创建设备和应用层通信)原理代码大公开 [打印本页]
作者: SKY定格 时间: 2012-5-14 19:35
标题: VB写驱动第二季之VB驱动完整版(包括创建设备和应用层通信)原理代码大公开
本帖最后由 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,str等VB自带函数.
要想实现具体的功能还必须调用内核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):
欢迎光临 SKY外语计算机学习 (http://skywj.com/) |
Powered by Discuz! X2.5 |