问题描述
背景:
我正在使用开源库编写应用程序。这个开源库带有许多插件dll。我们在项目中使用了其中的一些(并非全部)。
在开发过程中,我们只使用了整个库,并且一切正常。
现在,当我们尝试构建可运输的二进制程序包时,似乎需要进行分类,仅从正在使用的开源库中找到那些插件二进制文件(dll)。
这些库带有100个插件dll。在运行时,我们只使用一个主要的lib插件dll,而该dll会依次加载其他dll(目前,当我们运行该应用程序时,它会加载必需或非必需的dll)。我们需要找出一种方法来仅打包我们在代码中使用的那些dll。而且,由于这些仅是插件,因此如果主dll找不到非必需的dll,则完全可以(应用程序不会崩溃)。我们只需要帮助它找到必要的组件即可(没有该组件将无法使用或会崩溃)。
方法: 为了仅找到必需的dll,我所做的是从路径中删除了所有dll,并每次都开始放置一个dll进行检查,直到我们的应用程序开始工作为止。问题在于使用这种方法将花费很长时间。我不是随机选择每个dll,而是尝试使用WinDbg来找出哪些丢失的dll导致了失败。
问题: 在Windbg中,有没有一种方法可以从转储中识别出丢失的dll导致失败的原因?
解决方法
您提出的问题模棱两可。
大多数评论者都为您提供了有关实时调试会话的提示。
- Ldr快照
- ProcMon
- 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