首页
论坛
专栏
课程

[系统底层] [原创]对编写驱动时需谨慎使用EBX的分析

2008-3-7 12:26 12766

[系统底层] [原创]对编写驱动时需谨慎使用EBX的分析

HSQ
8
2008-3-7 12:26
12766
问题简述:       
        至少在XP SP2中,驱动程序DriverEntry例程和UnLoadedDrive例程中不能随意改动EBX的值,否则
会引起程序执行错误,甚至BSOD.

对于DriverEntry例程:
        当DriverEntry例程执行完毕后,返回到系统IopLoadDriver例程中,若在DriverEntry例程中改变
了EBX的值,则会在以下去引起地址访问违例,从而发生BSOD;或没有发生BSOD,但几乎必定会引起程序执行
错误,如虽然提供了卸载例程的驱动,亦无法卸载.

805a3ec0 895da0          mov     dword ptr [ebp-60h],ebx
805a3ec3 8b45a0          mov     eax,dword ptr [ebp-60h]
805a3ec6 8d448738        lea     eax,[edi+eax*4+38h]
kd> u
nt!IopLoadDriver+0x68c:
805a3eca 3918            cmp     dword ptr [eax],ebx    ;◆◆◆◆◆==BSOD===★★★★★★
805a3ecc 0f84e1430400    je      nt!IopLoadDriver+0x690 (805e82b3)

详细流程:
重现在DriverEntry例程中随意改动EBX的值引起BSODD

Microsoft (R) Windows Debugger Version 6.8.0004.0 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: D:\WINDDK\Symbols;d:\WINDOWS\Symbols
Executable search path is: E:\汇编编程\WIN32ASM\SOFT
Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp2_qfe.070227-2300
Kernel base = 0x804d8000 PsLoadedModuleList = 0x8055b820
Debug session time: Thu Mar  6 19:33:10.109 2008 (GMT+8)
System Uptime: 0 days 0:03:25.828
Break instruction exception - code 80000003 (first chance)
... ...
kd> t
HellowDDK!DriverEntry+0xee:
faf6f3e7 68f2f6f6fa      push    offset HellowDDK!szMsgDispathM (faf6f6f2)
kd> u
HellowDDK!DriverEntry+0xee [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 157]:
faf6f3e7 68f2f6f6fa      push    offset HellowDDK!szMsgDispathM (faf6f6f2)
faf6f3ec e817010000      call    HellowDDK!DbgPrint (faf6f508)
faf6f3f1 83c404          add     esp,4
faf6f3f4 8b4508          mov     eax,dword ptr [ebp+8]
faf6f3f7 c740388ef4f6fa  mov     dword ptr [eax+38h],offset HellowDDK!CalledIofCompleteRequest (faf6f48e)
faf6f3fe c7403a8ef4f6fa  mov     dword ptr [eax+3Ah],offset HellowDDK!CalledIofCompleteRequest (faf6f48e)
faf6f405 c74046a9f4f6fa  mov     dword ptr [eax+46h],offset HellowDDK!CalledDeviceControl (faf6f4a9)
faf6f40c c740342cf4f6fa  mov     dword ptr [eax+34h],offset HellowDDK!UnLoadedDrive (faf6f42c)
kd> u
HellowDDK!DriverEntry+0x11a [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 168]:
faf6f413 e8a9000000      call    HellowDDK!DebugShowRegisterInformation (faf6f4c1)
faf6f418 6840f6f6fa      push    offset HellowDDK!szMsgRun (faf6f640)
faf6f41d e8e6000000      call    HellowDDK!DbgPrint (faf6f508)
faf6f422 83c404          add     esp,4
faf6f425 8b45fc          mov     eax,dword ptr [ebp-4]
faf6f428 c9              leave
faf6f429 c20800          ret     8
HellowDDK!UnLoadedDrive [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 177]:
faf6f42c 55              push    ebp
kd> g faf6f429
Hellow Msg: The Driver is Dispathing Major Function !
Hellow Msg: The Code's Curent Address EIP = FAF6F413, More Information:
Hellow Msg: EAX = 811AE7E0 ECX = 80500073 EDX = 00000037 EBX = FAE3482B
Hellow Msg: ESP = F823BC60 EBP = F823BC7C ESI = E10A08CC EDI = 811AE7E0
Hellow Msg: The Driver is Runing !
HellowDDK!DriverEntry+0x130:
faf6f429 c20800          ret     8
kd> t
nt!IopLoadDriver+0x66c:
805a3ead 3bc3            cmp     eax,ebx
kd> u
nt!IopLoadDriver+0x66c:
805a3ead 3bc3            cmp     eax,ebx
805a3eaf 8b8d68ffffff    mov     ecx,dword ptr [ebp-98h]
805a3eb5 8945ac          mov     dword ptr [ebp-54h],eax
805a3eb8 8901            mov     dword ptr [ecx],eax
805a3eba 0f8ce7430400    jl      nt!IopLoadDriver+0x67b (805e82a7)
805a3ec0 895da0          mov     dword ptr [ebp-60h],ebx
805a3ec3 8b45a0          mov     eax,dword ptr [ebp-60h]
805a3ec6 8d448738        lea     eax,[edi+eax*4+38h]
805a3eca 3918            cmp     dword ptr [eax],ebx
805a3ecc 0f84e1430400    je      nt!IopLoadDriver+0x690 (805e82b3)
kd> G

*** Fatal System Error: 0x0000007e
                       (0xC0000005,0x805A3ECA,0xF88CABC4,0xF88CA8C0)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..................................................................................
Loading User Symbols
Loading unloaded module list
.........
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck 7E, {c0000005, 805a3eca, f88cabc4, f88ca8c0}
Probably caused by : ntoskrnl.exe ( nt!IopLoadDriver+68c )
Followup: MachineOwner
---------
nt!RtlpBreakWithStatusInstruction:
804e4592 cc              int     3
kd> !ANALYZE -V
Unknown option '-V'
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck 7E, {c0000005, 805a3eca, f88cabc4, f88ca8c0}
Probably caused by : ntoskrnl.exe ( nt!IopLoadDriver+68c )
Followup: MachineOwner
---------
kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e)
This is a very common bugcheck.  Usually the exception address pinpoints
the driver/function that caused the problem.  Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: c0000005, The exception code that was not handled
Arg2: 805a3eca, The address that the exception occurred at
Arg3: f88cabc4, Exception Record Address
Arg4: f88ca8c0, Context Record Address
Debugging Details:
------------------
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"
FAULTING_IP:
nt!IopLoadDriver+68c
805a3eca 3918            cmp     dword ptr [eax],ebx
EXCEPTION_RECORD:  f88cabc4 -- (.exr 0xfffffffff88cabc4)
ExceptionAddress: 805a3eca (nt!IopLoadDriver+0x0000068c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 6ca7bff4
Attempt to read from address 6ca7bff4
CONTEXT:  f88ca8c0 -- (.cxr 0xfffffffff88ca8c0)
eax=6ca7bff4 ebx=fae3482b ecx=f88cad70 edx=00000024 esi=e15ea23c edi=811a9f10
eip=805a3eca esp=f88cac8c ebp=f88cad4c iopl=0         nv up ei pl nz ac po cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010213
nt!IopLoadDriver+0x68c:
805a3eca 3918            cmp     dword ptr [eax],ebx  ds:0023:6ca7bff4=????????
Resetting default scope
DEFAULT_BUCKET_ID:  DRIVER_FAULT
PROCESS_NAME:  System
ERROR_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"
READ_ADDRESS:  6ca7bff4
BUGCHECK_STR:  0x7E
LAST_CONTROL_TRANSFER:  from 805a4182 to 805a3eca
STACK_TEXT:  
f88cad4c 805a4182 0000046c 00000001 00000000 nt!IopLoadDriver+0x68c
f88cad74 804e526b 0000046c 00000000 ffa9a640 nt!IopLoadUnloadDriver+0x45
f88cadac 8057dfce f88cecf4 00000000 00000000 nt!ExpWorkerThread+0x100
f88caddc 804f98fa 804e5196 80000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
FOLLOWUP_IP:
nt!IopLoadDriver+68c
805a3eca 3918            cmp     dword ptr [eax],ebx
SYMBOL_STACK_INDEX:  0
SYMBOL_NAME:  nt!IopLoadDriver+68c
FOLLOWUP_NAME:  MachineOwner
MODULE_NAME: nt
IMAGE_NAME:  ntoskrnl.exe
DEBUG_FLR_IMAGE_TIMESTAMP:  45e55172
STACK_COMMAND:  .cxr 0xfffffffff88ca8c0 ; kb
FAILURE_BUCKET_ID:  0x7E_nt!IopLoadDriver+68c
BUCKET_ID:  0x7E_nt!IopLoadDriver+68c
Followup: MachineOwner
---------
kd> u
nt!IopLoadDriver+0x68c:
805a3eca 3918            cmp     dword ptr [eax],ebx
805a3ecc 0f84e1430400    je      nt!IopLoadDriver+0x690 (805e82b3)

对于UnloadDriver例程:
        当不随意改EBX(这里是先保存在结束前将其恢复原值),程序正常执行
eax=00000000 ebx=00000000 ecx=80500073 edx=00000024 esi=f88e2b84 edi=f88e2b84
eip=faf1249c esp=fac9ed4c ebp=fac9ed58 iopl=0         nv up ei ng nz ac pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00200296
faf1249c c9              leave
kd> t
faf1249d c20400          ret     4
kd> t
nt!IopLoadUnloadDriver+0x19:
805e82fc 33ff            xor     edi,edi
        当随意改EBX,程序提前返回,无法正常执行,引起BSOD
kd> g fae69496
Hellow Msg: The Code's Curent Address EIP = FAE6947E, More Information:
Hellow Msg: EAX = 00000000 ECX = 00000000 EDX = 80562ED8 EBX = FAE6982B
Hellow Msg: ESP = F8236D48 EBP = F8236D58 ESI = F89EEB84 EDI = F89EEB84
Hellow Msg: The Driver is Unload !
Hellow Msg: The Code's Curent Address EIP = FAE69491, More Information:
Hellow Msg: EAX = 00000000 ECX = 80500073 EDX = 00000024 EBX = FAE6982B
Hellow Msg: ESP = F8236D4C EBP = F8236D58 ESI = F89EEB84 EDI = F89EEB84
HellowDDK!UnLoadedDrive+0x6e:
fae69496 c9              leave
faf12497 c20400          ret     4    ;<---------次条指令被跳过(在堆栈平衡绝对正确的情况下)
kd> t
nt!IopLoadUnloadDriver+0x19:
805e82fc 33ff            xor     edi,edi

详细流程:
重现在UnLoadedDrive例程中随意改动EBX的值引起BSODD

kd> u
HellowDDK!UnLoadedDrive+0x42 [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 196]:
fae6946a 83c404          add     esp,4
fae6946d 8b4508          mov     eax,dword ptr [ebp+8]
fae69470 83780400        cmp     dword ptr [eax+4],0
fae69474 7408            je      HellowDDK!UnLoadedDrive+0x56 (fae6947e)
fae69476 ff7004          push    dword ptr [eax+4]
fae69479 e884000000      call    HellowDDK!IoDeleteDevice (fae69502)
fae6947e e84a000000      call    HellowDDK!DebugShowRegisterInformation (fae694cd)
fae69483 686596e6fa      push    offset HellowDDK!szMsgUnload (fae69665)
kd> u
HellowDDK!UnLoadedDrive+0x60 [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 207]:
fae69488 e887000000      call    HellowDDK!DbgPrint (fae69514)
fae6948d 83c404          add     esp,4
fae69490 58              pop     eax
fae69491 e837000000      call    HellowDDK!DebugShowRegisterInformation (fae694cd)
fae69496 c9              leave
fae69497 c20400          ret     4
HellowDDK!CalledIofCompleteRequest [E:\汇编编程\WIN32ASM\SOFT\HellowDDK.asm @ 214]:
fae6949a 55              push    ebp
fae6949b 8bec            mov     ebp,esp
kd> g fae69496
Hellow Msg: The Code's Curent Address EIP = FAE6947E, More Information:
Hellow Msg: EAX = 00000000 ECX = 00000000 EDX = 80562ED8 EBX = FAE6982B
Hellow Msg: ESP = F8236D48 EBP = F8236D58 ESI = F89EEB84 EDI = F89EEB84
Hellow Msg: The Driver is Unload !
Hellow Msg: The Code's Curent Address EIP = FAE69491, More Information:
Hellow Msg: EAX = 00000000 ECX = 80500073 EDX = 00000024 EBX = FAE6982B
Hellow Msg: ESP = F8236D4C EBP = F8236D58 ESI = F89EEB84 EDI = F89EEB84
HellowDDK!UnLoadedDrive+0x6e:
fae69496 c9              leave
faf12497 c20400          ret     4
kd> t
nt!IopLoadUnloadDriver+0x19:
805e82fc 33ff            xor     edi,edi
kd> g
*** Fatal System Error: 0x000000e1
                       (0x805A4141,0x00000002,0xF8A0EB84,0xF8A0EB84)
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..........................................................................
Loading User Symbols
Loading unloaded module list
.........
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
Use !analyze -v to get detailed debugging information.
BugCheck E1, {805a4141, 2, f8a0eb84, f8a0eb84}
Probably caused by : ntoskrnl.exe ( nt!IopLoadUnloadDriver+0 )
Followup: MachineOwner
---------
nt!RtlpBreakWithStatusInstruction:
804e4592 cc              int     3
kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************
WORKER_THREAD_RETURNED_AT_BAD_IRQL (e1)
Arguments:
Arg1: 805a4141, address of worker routine (do ln on this to find guilty driver)
Arg2: 00000002, IRQL returned at (should have been 0, but isn't).
Arg3: f8a0eb84, workitem parameter
Arg4: f8a0eb84, workitem address
Debugging Details:
------------------
FAULTING_IP:
nt!IopLoadUnloadDriver+0
805a4141 8bff            mov     edi,edi
DEFAULT_BUCKET_ID:  DRIVER_FAULT
BUGCHECK_STR:  0xE1
PROCESS_NAME:  System
LAST_CONTROL_TRANSFER:  from 8053366f to 804e4592
STACK_TEXT:  
f8256918 8053366f 00000003 f8256c74 00000000 nt!RtlpBreakWithStatusInstruction
f8256964 80534146 00000003 f8a0eb84 805628dc nt!KiBugCheckDebugBreak+0x19
f8256d44 80534736 000000e1 805a4141 00000002 nt!KeBugCheck2+0x574
f8256d64 80528cb0 000000e1 805a4141 00000002 nt!KeBugCheckEx+0x1b
f8256dac 8057dfce f8a0eb84 00000000 00000000 nt!ExpWorkerThread+0x1e6
f8256ddc 804f98fa 804e5196 80000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
STACK_COMMAND:  .bugcheck ; kb
FOLLOWUP_IP:
nt!IopLoadUnloadDriver+0
805a4141 8bff            mov     edi,edi
SYMBOL_NAME:  nt!IopLoadUnloadDriver+0
FOLLOWUP_NAME:  MachineOwner
MODULE_NAME: nt
IMAGE_NAME:  ntoskrnl.exe
DEBUG_FLR_IMAGE_TIMESTAMP:  45e55172
FAILURE_BUCKET_ID:  0xE1_nt!IopLoadUnloadDriver+0
BUCKET_ID:  0xE1_nt!IopLoadUnloadDriver+0
Followup: MachineOwner
---------

解决方案:
        鉴于以上原因,我们在驱动程序DriverEntry例程和UnLoadedDrive例程中不要随意改动EBX的
值, 即使必须要改变EBX的值,也应该先将其原值储存后再随意处理EBX,并且一定要在执行完毕前恢复
其值.
        另外,对于其他主功能分发例程没有进行测试,通过查看一些逆过的驱动,也发现程序中使用EBX
的情况很少见,有的完全没有使用EBX,故而估计对于EBX寄存器的修改还得遵循以上处理方法(具体情况
还需自己亲自测试). 如果了解这个问题,就能减少些驱动时出现一些莫名其妙的错误.

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (19)
foxabu 13 2008-3-7 12:59
2
0
All arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left. Structures that are not PODs will not be returned in registers.

The compiler generates prolog and epilog code to save and restore the ESI, EDI, EBX, and EBP registers, if they are used in the function

驱动C用的多点,显然C编译器一般会由于优化避免使用需要 Restore的regs.如果非要使用,自然会被保护.以上文字引自MSDN.

既然是__stdcall调用规则,本来就不能够动EBX......所以我发现最近火星人不少.

打开防忽悠模式ing.....楼下的几位看来不只是海王星人的问题.
防忽悠
防忽悠
防忽悠
防忽悠
防忽悠
防忽悠
防忽悠

不要忽悠我.
HSQ 8 2008-3-7 13:35
3
0
我是最近对驱动开始赶兴趣,看了些KMD教程,就在学写过程中发现的这个问题,每想到竟然成了火星人
笨笨雄 14 2008-3-7 13:38
4
0
貌似写任何程序,引入汇编的时候都要保存环境吧。。。。不止驱动?
海风日影 2008-3-7 13:40
5
0
这和驱动没关系.
三环程序也不能动ebx
sudami 25 2008-3-7 13:43
6
0
理解方向有偏差~~~
dge 6 2008-3-7 13:47
7
0
用asm写代码,是容易范错误。
HSQ 8 2008-3-7 13:50
8
0
好象在《罗》书中提到过,WIN回调函数需要保护 EBX,ESI,EDI。原来在驱动中DriverEntry例程和UnLoadedDrive例程也是系统的回调函数(原来我还认为只是一种人口代码,不属于系统回调),也必须保存环境,那的确是我学业不精所制。只要能有收获,只要骂的有道理,被骂也值得。学业有先后而已。
combojiang 26 2008-3-7 14:09
9
0
学习, ,出来混,难免被误解。
forgot 26 2008-3-7 14:32
10
0
也许LZ是为了省那2个字节作努力,却被世人误解
笨笨雄 14 2008-3-7 14:59
11
0
0x53和0x5b?
lovelyfrog 2008-3-7 15:25
12
0
forgot高人也
cvcvxk 10 2008-3-7 23:27
13
0
LZ用了mwing32编译驱动了?
那玩意经常产生邪恶的sys,比如RKU的那种看似naked的sys
HSQ 8 2008-3-8 12:18
14
0
最后补充一下:
    在我发此帖以前,我刚刚只是看完了KMD教程的前5节,后来,通过分析整个教程的例子,发现自第六节后的例子才开始用到 ex,edi,esi 中的一些或全部,才出现了相应的保护代码。而之前的所有例子,因为没有改动以上敏感寄存器,也就没有出现保护代码。而我在自己的Hellowddk中却无意用到并修改了EBX(个人比较钟爱使用EAX,EBX),也跟着例子没有注意保护EBX,进而导致BSOD,于是想弄明缘由,于是引发了此贴的内容,还获得了火星人之称。自第6节系统堆栈之后的例子,开始偶而出现了对敏感寄存器的保护(uses),但也不是完全性的,当例子中用到了ebx,esi,edi中的一个,两个或全部时,才会使用相应的保护中的一个,两个或全部。
    Windows系统中,任何回调例程,如驱动中的各主功能分发例程及加载,卸载例程和异常处理例程等,凡是需要修改敏感寄存器(ebx,esi,edi),都必须予以保护(uses ebx esi edi)。 似乎很明显在下不使用他们时,可以不用保护,至少KMD中的是这样做的。但这又带来一个疑问,在用户或系统模式下的任何例程,不可避免的最终要调用API和系统服务,如果例程的自身程序代码能保证不修改敏感积存器,并不予提供保护,能保证这些属于OS的服务代码绝对不修改这些敏感积存器,从而再次引发错误吗? 还请各位高手不要取笑,给予赐教!
    我目前的做法是,为了代码运行安全和避免引起不必要的麻烦起见,干脆在所有的回调中保护全部的敏感积存器。算是被forgot 说对了,我是为尽量省字节,减少不必要的指令,而不保护这些敏感积存器。尽可能的精简代码,这也是用汇编而不用C写驱动的目的所在嘛。
theOcrat 8 2008-3-8 13:17
15
0
看来驱动好普及了~
海风日影 2008-3-8 13:51
16
0
pediy, unpackcn等论坛对一些人最大的“毒害”就是汇编至上
很多人忽略了高级语言,但这些人并不是都像亿万大叔那样强悍
所以会走弯路
看来楼主有点像这样的人
笨笨雄 14 2008-3-8 15:58
17
0
个人观点。。。火星并非坏事。。。弯路也无所谓。。。每个人都有刚起步的时候。。。
别人教你怎么做就怎么做固然好,然而,如果不知道为什么,便失去了超越前人的可能性。。。
yangjt 10 2008-3-8 17:37
18
0
看得天花乱坠……
nig 4 2008-3-9 08:35
19
0
我们习惯了按字母顺序来分 AX,BX,CX,DX  但事实上这样经常让我们犯错误,

就象我们说东南西北,而微软一定要说东西南北一样,一不小心就会挂了.

那2字节省不得 pushad   popad 只要嵌汇编,做开头.当结尾,相当于领导们

讲话的"嗯  啊"吧
WHO-AM-I 2008-3-10 12:04
20
0
呵呵,小心驶得万年船!
游客
登录 | 注册 方可回帖
返回