Windbg查找丢失的dll

问题描述

背景:

我正在使用开源库编写应用程序。这个开源库带有许多插件dll。我们在项目中使用了其中的一些(并非全部)。

在开发过程中,我们只使用了整个库,并且一切正常。

现在,当我们尝试构建可运输的二进制程序包时,似乎需要进行分类,仅从正在使用的开源库中找到那些插件二进制文件(dll)。

这些库带有100个插件dll。在运行时,我们只使用一个主要的lib插件dll,而该dll会依次加载其他dll(目前,当我们运行该应用程序时,它会加载必需或非必需的dll)。我们需要找出一种方法来仅打包我们在代码中使用的那些dll。而且,由于这些仅是插件,因此如果主dll找不到非必需的dll,则完全可以(应用程序不会崩溃)。我们只需要帮助它找到必要的组件即可(没有该组件将无法使用或会崩溃)。

方法: 为了仅找到必需的dll,我所做的是从路径中删除了所有dll,并每次都开始放置一个dll进行检查,直到我们的应用程序开始工作为止。问题在于使用这种方法将花费很长时间。我不是随机选择每个dll,而是尝试使用WinDbg来找出哪些丢失的dll导致了失败。

问题: 在Windbg中,有没有一种方法可以从转储中识别出丢失的dll导致失败的原因?

解决方法

您提出的问题模棱两可。
大多数评论者都为您提供了有关实时调试会话的提示。

  1. Ldr快照
  2. ProcMon
  3. Etw痕迹

您似乎已要求在转储中查看它

问题:Windbg中是否可以从转储中识别出哪个丢失的dll导致了故障?

根据其性质,插件将被其父二进制文件允许正常失败,因此将创建一个卸载事件

这将通过lm命令在转储中反映出来
卸载的模块将列在模块列表的末尾

:\>cdb -c "lm;q" -z c:\odbgdmp.dmp |awk "/Unloaded/,/quit/"
Unloaded modules:
66940000 66957000   OllyDumpEx_Imm17.dll
quit:

ntdll维护一个数组0x40最后卸载的dlls windbg与下面的代码在同一位置检索它。

#include <stdio.h>
#include <windows.h>
typedef struct _RTL_UNLOAD_EVENT_TRACE {
    PVOID BaseAddress;SIZE_T SizeOfImage;ULONG Sequence;ULONG TimeDateStamp;
    ULONG CheckSum;WCHAR ImageName[32];
} RTL_UNLOAD_EVENT_TRACE,*PRTL_UNLOAD_EVENT_TRACE; 

typedef VOID (WINAPI* RtlGetUnloadEventTraceEx) (
_Out_ PULONG *ElementSize,_Out_ PULONG *ElementCount,_Out_ PVOID  *EventTrace
);

RtlGetUnloadEventTraceEx evt;

int main(void) {
    //ollydbg plugin wont load in curproc will create an unloaded mod event
    LoadLibraryA("OllyDumpEx_Od20.dll");
    HMODULE nt=LoadLibraryA("ntdll.dll");
    if(nt != NULL){
        evt=(RtlGetUnloadEventTraceEx)GetProcAddress(nt,"RtlGetUnloadEventTraceEx");
        PULONG  elsiz = NULL,elcnt = NULL;PVOID evarr = NULL;
        evt(&elsiz,&elcnt,&evarr);
        printf("%p %p %p\n",elsiz,elcnt,evarr);
        printf("%x %x %x\n",*elsiz,*elcnt,*(int*)evarr);
        PRTL_UNLOAD_EVENT_TRACE u1=((PRTL_UNLOAD_EVENT_TRACE)(*(int*)evarr));
        printf("bas\t%p\nsiz\t%x\nSeq\t%x\nstamp\t%x\nCsum\t%x\nname\t%S\n",u1->BaseAddress,u1->SizeOfImage,u1->Sequence,u1->TimeDateStamp,u1->CheckSum,u1->ImageName);        
    }
    return 0;
}

执行时

:\>UnloadModList.exe
7706CDA0 7706CD9C 77067144
5c 40 1fafd8
base    676F0000
size    19000
Seq     0
stamp   55953f77
Chksum  12b14
imgname OllyDumpEx_Od20.dll

证实无法加载的dll详细信息

:\>dumpbin /headers OllyDumpEx_Od20.dll | grep -iE "CheckSum|Stamp|size of image|image base"
        55953F77 time date stamp Thu Jul  2 19:11:11 2015
        6A680000 image base (6A680000 to 6A698FFF)
           19000 size of image
           12B14 checksum