dfbb7788
驱动牛犊
驱动牛犊
  • 注册日期2007-07-07
  • 最后登录2010-05-06
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望106点
  • 贡献值0点
  • 好评度40点
  • 原创分0分
  • 专家分0分
阅读:1886回复:2

一款红外usb NDIS-IRDA-USB反汇编及重写

楼主#
更多 发布于:2008-10-26 01:55
背景:
最近公司有个红外项目,买了个usb口的红外ir650,只有xp下的驱动文件,项目要求我将这个irda移植到winCE上,并且在xp上也要进行加解密操作。考虑了下决定反汇编先
重写xp下的驱动再移植到ce上,不再另外买串口的红外了(串口红外ddk有例子)。给反汇编核ndis-usb初学者看
开发工具:IDA、WinDBG、VMare、DDK、串口线(双机调试用)

返汇编代码分析:
start函数就是DriverEntry
INIT:00015A4C                 mov     byte ptr [ebp+var_6C], 5
INIT:00015A50                 mov     byte ptr [ebp+var_6C+1], 0
INIT:00015A54                 mov     [ebp+var_64], 0
INIT:00015A5B                 mov     [ebp+var_58], offset MiniportHalt ; complet
INIT:00015A62                 mov     [ebp+var_50], offset MiniportInit ; complete
INIT:00015A69                 mov     [ebp+var_48], offset MiniportQuery ; complete
INIT:00015A70                 mov     [ebp+var_44], 0
INIT:00015A77                 mov     [ebp+var_40], offset MiniportReset ; complete
INIT:00015A7E                 mov     [ebp+var_3C], offset MiniportSend ; complete
INIT:00015A85                 mov     [ebp+var_38], offset MiniportSetInfo ; complete
INIT:00015A8C                 mov     [ebp+var_34], 0
INIT:00015A93                 mov     [ebp+var_54], 0
INIT:00015A9A                 mov     [ebp+var_4C], 0
INIT:00015AA1                 mov     [ebp+var_60], 0
INIT:00015AA8                 mov     [ebp+var_5C], 0
INIT:00015AAF                 mov     [ebp+var_30], offset ReturnPacket ; complete
INIT:00015AB6                 mov     [ebp+var_2C], 0
INIT:00015ABD                 mov     [ebp+var_28], 0
函数名字需要自己改,上面这段是填充NDIS50_MINIPORT_CHARACTERISTICS
INIT:00015B05                 mov     edx, [ebp+arg_0]
INIT:00015B08                 mov     dword ptr [edx+38h], offset Create_Close ; completed
INIT:00015B0F                 mov     eax, [ebp+arg_0]
INIT:00015B12                 mov     dword ptr [eax+40h], offset Create_Close ; completed
INIT:00015B19                 mov     ecx, [ebp+arg_0]
INIT:00015B1C                 mov     dword ptr [ecx+70h], offset DeviceControl ; completed
INIT:00015B23                 mov     eax, [ebp+var_4]
上面这段是
DriverObject->MajorFunction[IRP_MJ_CREATE]        = Create_Close;        // completed
DriverObject->MajorFunction[IRP_MJ_CLOSE]            = Create_Close;        // completed
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = DeviceControl;
由于是ndis-wdm(usb)所以要处理irp。
DriverEntry需要的就是这些,实际上ir650用的usb-serial,所以只注册了这些函数,并且是SIR编码速率低。
重点在MiniportInit函数里,对应普通usb驱动AddDevice里的操作都在该函数里实现,包括匹配PID,配置usb endpoint,及初始化发送接受线程、DPC等。
.text:00010BBF                 mov     edx, [ebp+arg_0]
.text:00010BC2                 add     edx, 1F8h
.text:00010BC8                 mov     eax, [ebp+arg_0]
.text:00010BCB                 mov     [eax+1FCh], edx
.text:00010BD1                 mov     ecx, [ebp+arg_0]
.text:00010BD4                 mov     edx, [ebp+arg_0]
.text:00010BD7                 mov     eax, [edx+1FCh]
.text:00010BDD                 mov     [ecx+1F8h], eax
这种代码就是调用InitializeListHead反出来的代码
调用NdisMSetAttributesEx时注意参数,这个驱动里用了NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND
.text:00010F59                 mov     eax, [ebp+ListEntry]
.text:00010F5C                 push    eax             ; StartContext
.text:00010F5D                 push    offset StartRoutine ; StartRoutine
.text:00010F62                 push    0               ; ClientId
.text:00010F64                 push    0               ; ProcessHandle
.text:00010F66                 push    0               ; ObjectAttributes
.text:00010F68                 push    0               ; DesiredAccess
.text:00010F6A                 mov     ecx, [ebp+ListEntry]
.text:00010F6D                 add     ecx, 4Ch
.text:00010F70                 push    ecx             ; ThreadHandle
.text:00010F71                 call    ds:PsCreateSystemThread
该线程函数主要处理一些irp操作,起调度作用。
.text:00010FA6                 push    0               ; 2008-10-03 18:14 conding...
.text:00010FA8                 push    0
.text:00010FAA                 mov     ecx, [ebp+ListEntry]
.text:00010FAD                 add     ecx, 0Ch
.text:00010FB0                 push    ecx
.text:00010FB1                 push    0
.text:00010FB3                 push    0
.text:00010FB5                 mov     edx, [ebp+ListEntry]
.text:00010FB8                 mov     eax, [edx+18h]
.text:00010FBB                 push    eax
.text:00010FBC                 call    ds:NdisMGetDeviceProperty
这段函数很重要,获得NextDeviceObject。
.text:000143B5                 mov     ecx, [ebp+pUrb]
.text:000143B8                 mov     word ptr [ecx+2], 0Bh ; _URB_HEADER.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
.text:000143BE                 mov     edx, [ebp+pUrb]
.text:000143C1                 mov     word ptr [edx], 50h ; _URB_HEADER.Length
.text:000143C6                 mov     eax, [ebp+pUrb]
.text:000143C9                 mov     dword ptr [eax+18h], 9 ; _URB_CONTROL_DESCRIPTOR_REQUEST.TransferBufferLength
.text:000143D0                 mov     ecx, [ebp+pUrb]
.text:000143D3                 mov     dword ptr [ecx+20h], 0 ; _URB_CONTROL_DESCRIPTOR_REQUEST.TransferBufferMDL
.text:000143DA                 mov     edx, [ebp+pUrb]
.text:000143DD                 mov     eax, [ebp+PUSB_CONFIGURATION_DESCRIPTOR]
.text:000143E0                 mov     [edx+1Ch], eax  ; _URB_CONTROL_DESCRIPTOR_REQUEST.TransferBuffer = PUSB_CONFIGURATION_DESCRIPTOR
.text:000143E3                 mov     ecx, [ebp+pUrb]
.text:000143E6                 mov     byte ptr [ecx+4Bh], 2 ; _URB_CONTROL_DESCRIPTOR_REQUEST.DescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE
.text:000143EA                 mov     edx, [ebp+pUrb]
.text:000143ED                 mov     byte ptr [edx+4Ah], 0 ; _URB_CONTROL_DESCRIPTOR_REQUEST.Index = 0
这种代码一般就是填从URB结构,有一系列函数的,这个是调用UsbBuildGetDescriptorRequest。
对于usb-control端点的写没必要设置完成例程,反出来的结果。还有些usbd的函数
USBD_CreateConfigurationRequest、USBD_ParseConfigurationDescriptorEx
在配置接收函数时需要设置irp完成例程函数,在完成里程里再重新配置接收函数,这段返回编代码我就不贴了,太长。
.text:0001279C off_1279C       dd offset loc_1251E     ; DATA XREF: IrToNdis_124A0+77r
.text:000127A0                 dd offset loc_1253E
.text:000127A4                 dd offset loc_12736
.text:000127A8                 dd offset loc_1268C
.text:000127AC                 dd offset loc_125B9
.text:000127B0 off_127B0       dd offset loc_126F7     ; DATA XREF: IrToNdis_124A0+218r
.text:000127B4                 dd offset loc_126DB
.text:000127B8                 dd offset loc_126BF
.text:000127BC                 dd offset loc_12734
.text:000127C0 byte_127C0      db 0                    ; DATA XREF: IrToNdis_124A0+212r
.text:000127C1                 dd 7 dup(3030303h), 1030303h, 10h dup(3030303h), 1020303h
.text:000127C1                 dd 7 dup(3030303h), 303h, 2 dup(0CCCCCCCCh)
.text:0001284D                 align 10h
这种代码不用想,几乎就是switch()case反出来的代码,不要被吓着,仔细分析,在结合你分析的汇编代码,
比如红外码转化,可以比较轻松将这段代码重新写出来
还有就是由于是ndis-usb,没有irp,irp需要你上面的NextDeviceObject创造出来
在MiniportQuery和set函数中,需要对OID_IRDA_SUPPORTED_SPEEDS和OID_IRDA_MEDIA_BUSY,如果oid错误,
很有可能导致你上层应用程序socket或getsocketopt不成功。
在MiniportSend中,返回STATUS_PENDING,在你的IRP完成例程里调用NdisMSendComplete指示发包完成

代码编写完调试:
用虚拟机和双机调试,具体怎么配置,google搜下很多教程。
根据反汇编代码写的驱动基本会出现错误,建议在编写的时候一定要仔细,不然调试的时候会很烦。
在你的驱动不死机的时候你会发现socket或getsocketopt不成功,检查你的Oid和汇编代码是否一致。
socket成功后继续发现你的驱动让你ir650设备不闪灯不发红外包,请重新重头到尾检查你的代码,
没有办法,也许一个微小的错误会让你的设备不工作。

虚拟机调试usb的问题:
我的驱动能发包后发现在接收红外包的时候速度异常慢虽然可以接收文件,而且丢包率其高,感觉不是代码不正确,
换上正牌驱动居然出现和我的驱动一样的问题,并且还有时死机,我的驱动和正牌驱动死机的dump bug一寞一样,
偶然不用虚拟机调试,直接上机器,问题解决了,看来vmare的usb模拟的不是很好,赫赫,我用的是5.0。
现在调试兰芽usb我都用双机调试,虚拟机到有点不敢用了,不知道6.0还有没有这个bug


总结:
反汇编觉得最重要的是你要把驱动的全局变量要莫清楚,里面的数据结构代表了整个程序的架构和流程,很重要,
不明白的地方先标上,以后明白了再补,表出来了,难度基本就没了。
前后将近一个月时间连反带重写,中间还生病一个星期,驱动文件手上机器没有下次传上来吧,欢迎讨论

过几天奉上将ndis-irda-usb winxp驱动移植到winCE上。
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
沙发#
发布于:2008-10-26 09:28
不错:)
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
dfbb7788
驱动牛犊
驱动牛犊
  • 注册日期2007-07-07
  • 最后登录2010-05-06
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望106点
  • 贡献值0点
  • 好评度40点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-12-04 20:05
ce驱动移植完毕一直有事情现在才发上来,由于没有用ce的ndis-irda架构,估将MiniportInit中的代码放到adddevice(好像是这个名字,有点忘了)中,windows驱动中的dpc历程可以去掉,将这段代码放到issue那个函数注册中断endpoint即可,其他就没有什么了
游客

返回顶部