你好,祝你好运。
这里需要一些帮助:
场合:
我有一个模糊的DirectX 9应用程序(名称和应用程序的详细信息与问题无关),导致所有nvidia卡(GeForce 8400GS及以上)的蓝屏死机,因为某些驱动程序版本。我认为问题是由DirectX 9调用或触发驱动程序错误的标志间接引起的。
目标:
我想通过编写代理dll来追踪有问题的标记/函数调用(为了好玩,这不是我的工作/作业)并绕过错误条件。我已经有一个完成的代理dll,它为IDirect3D9,IDirect3DDevice9,IDirect3DVertexBuffer9和IDirect3DIndexBuffer9提供包装器,并提供Direct3D调用的基本日志记录/跟踪。但是,我无法确定导致崩溃的功能。
问题:
sendto
)也会导致显着的减速,并且不能异步完成(异步数据包在BSOD上丢失),加上数据包(崩溃周围的数据包)有时会丢失,即使同步发送。 问题:
我通常不会编写驱动程序,也不会进行这种级别的调试,所以我觉得我缺少一些重要的东西,比使用自定义日志记录机制编写IDirect3DDevice9代理dll有更简单的方法来追踪问题。它是什么?诊断/处理/修复问题的标准方法是什么(没有源代码,COM接口方法触发BSOD)?
Minidump分析(WinDBG):
Loading User Symbols Loading unloaded module list ........... Unable to load image nv4_disp.dll, Win32 error 0n2 *** WARNING: Unable to verify timestamp for nv4_disp.dll *** ERROR: Module load completed but symbols could not be loaded for nv4_disp.dll ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* Use !analyze -v to get detailed debugging information. BugCheck 1000008E, {c0000005, bd0a2fd0, b0562b40, 0} Probably caused by : nv4_disp.dll ( nv4_disp+90fd0 ) Followup: MachineOwner --------- 0: kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* KERNEL_MODE_EXCEPTION_NOT_HANDLED_M (1000008e) 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. Some common problems are exception code 0x80000003. This means a hard coded breakpoint or assertion was hit, but this system was booted /NODEBUG. This is not supposed to happen as developers should never have hardcoded breakpoints in retail code, but ... If this happens, make sure a debugger gets connected, and the system is booted /DEBUG. This will let us see why this breakpoint is happening. Arguments: Arg1: c0000005, The exception code that was not handled Arg2: bd0a2fd0, The address that the exception occurred at Arg3: b0562b40, Trap Frame Arg4: 00000000 Debugging Details: ------------------ EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s". FAULTING_IP: nv4_disp+90fd0 bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi TRAP_FRAME: b0562b40 -- (.trap 0xffffffffb0562b40) ErrCode = 00000000 eax=00000808 ebx=e37f8200 ecx=e4ae1c68 edx=e37f8328 esi=e37f8400 edi=00000000 eip=bd0a2fd0 esp=b0562bb4 ebp=e37e09c0 iopl=0 nv up ei pl nz na po nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 nv4_disp+0x90fd0: bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi ds:0023:00000900=???????? Resetting default scope CUSTOMER_CRASH_COUNT: 3 DEFAULT_BUCKET_ID: DRIVER_FAULT BUGCHECK_STR: 0x8E LAST_CONTROL_TRANSFER: from bd0a2e33 to bd0a2fd0 STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. b0562bc4 bd0a2e33 e37f8200 e37f8200 e4ae1c68 nv4_disp+0x90fd0 b0562c3c bf8edd6b b0562cfc e2601714 e4ae1c58 nv4_disp+0x90e33 b0562c74 bd009530 b0562cfc bf8ede06 e2601714 win32k!WatchdogDdDestroySurface+0x38 b0562d30 bd00b3a4 e2601008 e4ae1c58 b0562d50 dxg!vDdDisableSurfaceObject+0x294 b0562d54 8054161c e2601008 00000001 0012c518 dxg!DxDdDestroySurface+0x42 b0562d54 7c90e4f4 e2601008 00000001 0012c518 nt!KiFastCallEntry+0xfc 0012c518 00000000 00000000 00000000 00000000 0x7c90e4f4 STACK_COMMAND: kb FOLLOWUP_IP: nv4_disp+90fd0 bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi SYMBOL_STACK_INDEX: 0 SYMBOL_NAME: nv4_disp+90fd0 FOLLOWUP_NAME: MachineOwner MODULE_NAME: nv4_disp IMAGE_NAME: nv4_disp.dll DEBUG_FLR_IMAGE_TIMESTAMP: 4e390d56 FAILURE_BUCKET_ID: 0x8E_nv4_disp+90fd0 BUCKET_ID: 0x8E_nv4_disp+90fd0 Followup: MachineOwner
答案 0 :(得分:6)
nv4_disp+90fd0
bd0a2fd0 39b8f8000000 cmp dword ptr [eax+0F8h],edi
这是重要的部分。看看这个,最有可能的是eax无效,因此试图访问无效的内存地址。
您需要做的是将nv4_disp.dll加载到IDA(您可以获得免费版本),检查IDA加载nv4_disp的图像库并点击“g”到转到地址,尝试将90fd0添加到图像库IDA正在使用,它应该直接带你到违规指令(取决于部分结构)。
从这里您可以分析控制流程,以及如何设置和使用eax。如果你有一个好的内核级调试器,你可以在这个地址上设置一个断点并试着让它命中。
分析这个函数,你应该试着找出函数的作用,那个eax指向的那个点,实际指向的是什么,以及为什么。这是困难的部分,是逆向工程的难点和技巧的重要组成部分。
答案 1 :(得分:6)
找到解决方案。
<强>问题强>:
记录不可靠,因为消息(转储到文件时)在bsod期间消失,数据包有时在网络登录时丢失,并且由于记录而减慢。
<强>解决方案强>:
而不是记录到文件或通过网络,配置系统以在BSOD上生成完整的物理内存转储并将所有消息记录到任何内存缓冲区中。它会更快。一旦系统崩溃,它将把整个内存转储到文件中,并且可以使用WinDBG的dt
(如果你有调试符号)命令查看日志文件缓冲区的内容,或者你将能够使用“内存”视图搜索和定位存储在内存中的日志文件。
我使用了std :: strings的循环缓冲区来存储消息和单独的const char *数组,以便在WinDBG中更容易阅读,但你可以简单地创建大量的char并以明文形式存储其中的所有消息。 / p>
<强>详情:
winxp上的整个过程:
!analyze -v
命令。dt module!variable
,其中“module”是您的库的名称(不含* .dll),“variable”是变量的名称。您可以使用通配符。您可以使用不包含module!variable
dt module!variable field
其中“field”是变量成员。dt -b module!variable field
或dt -b module!variable
此时,您将能够看到存储在内存中的日志内容,此外,您还可以在崩溃时获得整个系统的快照。
也...
!process
。lm
!thread id
其中id是您在!process
输出中看到的十六进制ID。答案 2 :(得分:1)
看起来崩溃可能是由错误的指针或堆损坏引起的。您可以这样说,因为崩溃发生在一个释放内存的函数(DxDdDestroySurface
)中。破坏表面是你绝对需要做的事情 - 你不能只是将它存根,当程序退出时表面仍会被释放,如果你在内核中禁用它,你将耗尽卡上的内存很快就崩溃了。
您可以尝试找出导致此堆损坏的事件序列,但这里没有灵丹妙药 - 正如文件偏移建议的那样,您需要对驱动程序进行实际反向工程以了解为什么会发生这种情况(这可能有所帮助)在违规驱动程序版本之前和之后比较驱动程序!)