【问题标题】:Trying to debug LoadlibraryExW with WinDBG Preview Windows 11尝试使用 WinDBG Preview Windows 11 调试 LoadlibraryExW
【发布时间】:2021-11-20 04:09:13
【问题描述】:

我试图弄清楚为什么添加到路径 AddDllDirectory() 而不是退出进程 PATH 不会让我加载在 VBA 函数中使用的 dll。所以想知道LoadLibraryExW()的第三个参数是什么。

第一个问题是我正确加载了符号。我的符号服务器缓存充满了 pdb 文件。但是,没有找到 kernelbase.dll 的符号。

进程监视器显示堆栈跟踪,但不显示符号。

我在 WinDbgPreview 中为kernelbase!LoadLibraryExW 设置了一个断点,但我不确定如何读取堆栈跟踪。在这个例子中,这些十六进制值之一应该是第三个参数吗?还是当我想要堆栈时来自寄存器?

 # Child-SP          RetAddr               : Args to Child                                                           : Call Site
00 00000051`184fe648 00007ffe`e30b5ae5     : 00007ffe`e3431380 00000000`00000060 00000051`184feac0 00000000`00000008 : KERNELBASE!LoadLibraryExW
01 00000051`184fe650 00007ffe`e30b5a45     : 00000051`184fe704 1103aa3e`00000001 00000000`00000008 00000000`00000007 : mso20win32client!Ordinal104+0x295
02 00000051`184fe690 00007ffe`e3090bb1     : 000001df`179f4860 00000000`02000000 00000000`00000008 00000000`00000000 : mso20win32client!Ordinal104+0x1f5
03 00000051`184fe6d0 00007ffe`e3091c11     : 00000051`184feb10 000001df`179f4860 00000000`00000000 00000051`184feaf0 : mso20win32client!Ordinal67+0x1f71
04 00000051`184fea50 00007ffe`d808e62a     : 000001df`179f4860 00007ffe`d9c34730 000001df`17f7b1c0 00000000`00000000 : mso20win32client!Ordinal1818+0x8c1
05 00000051`184fead0 00007ffe`d808f3c3     : 000001df`179f4860 00007ffe`d9c34730 000001df`17f7b1c0 00007ffe`d9c33a10 : mso!Ordinal2534+0x51a
06 00000051`184feb10 00007ffe`d808f347     : 000001df`182fb2c0 000001df`00000001 000001df`182fb2c0 00000000`00000000 : mso!Ordinal2534+0x12b3
07 00000051`184feb50 00007ffe`d8153c24     : 000001df`182fb2c0 00000000`00000000 000001df`17f7b1c0 000001df`17f7b1c0 : mso!Ordinal2534+0x1237
08 00000051`184feb80 00007ffe`d80b1c8e     : 00000051`184ff290 00000000`0001d4c0 000001df`17ed3700 00000051`184ff360 : mso!Ordinal1436+0x16b4
09 00000051`184ff0d0 00007ffe`d80b1925     : 000001df`12529600 00000000`00000000 000001df`17ca9430 000001df`12529600 : mso!Ordinal921+0xe6e
0a 00000051`184ff340 00007ffe`e2fe3c3c     : 00000051`184ff488 00000051`184ff440 00000000`00000000 00000000`00000000 : mso!Ordinal921+0xb05
0b 00000051`184ff3d0 00007ffe`e2fe413b     : 000001df`01849818 00000000`00000000 000001df`01849800 00000000`00000144 : mso20win32client!Ordinal1756+0xbc
0c 00000051`184ff460 00007ffe`e2fe3c3c     : 000001df`11d96b90 000001df`17823c68 000001df`17ca9430 00007fff`88aa7551 : mso20win32client!Ordinal1756+0x5bb
0d 00000051`184ff4f0 00007ffe`e311741d     : 000001df`1284a6a0 00000000`00000000 00000051`184ff790 00000000`00000000 : mso20win32client!Ordinal1756+0xbc
0e 00000051`184ff580 00007ffe`e3050e6e     : 000001df`1284a6a0 00000000`00000000 000001df`1284a601 000001df`01a18f80 : mso20win32client!Ordinal1700+0x28d
0f 00000051`184ff5b0 00007ffe`e3051ed5     : 00000051`184ff710 000001df`1284a6a0 000001df`01a18f80 000001df`1284a6a0 : mso20win32client!Ordinal347+0x23e
10 00000051`184ff610 00007ffe`e305c2d6     : 000001df`017c9470 00000000`00000000 000001df`017c9470 00000000`00000000 : mso20win32client!Ordinal1966+0x6e5
11 00000051`184ff770 00007fff`873854e0     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : mso20win32client!Ordinal2633+0x686
12 00000051`184ff7e0 00007fff`88a8485b     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x10
13 00000051`184ff810 00000000`00000000     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2b

有没有办法获取kernlbase.pdb?它适用于旧版本的 Windows 吗?有没有可以读取参数的 WinDbg 命令?

【问题讨论】:

  • 在 x64 上,前四个参数在寄存器中。 rcxrdxr8r9。所以第三个参数在r8。更一般地说,要调试 DLL 加载问题,您可以打开 loader snaps
  • 加载符号后,您可以使用kp 命令。 Symbols for Windows debugging 解释了如何做到这一点。
  • @ThomasWeller iirc 它是 /HIGHENTROPYVA 链接器开关
  • @ThomasWeller 你就去做吧。使用VirtualQuery 遍历地址空间,使用VirtualAlloc 保留每个低于4GB 且标记为空闲的块。
  • 未死使用日期标记并在重定向的页脚中搜索以找到 earlier discussion,因为我记得它讨论过 highentroyva

标签: winapi windbg


【解决方案1】:

这本来是一个评论,但它变得如此回答

有时您已经下载了一半或中止了 pdb 的下载 在这种情况下,很明显没有下载符号文件

中止的下载具有 .error 扩展名

检查您是否有此类文件并将其删除以正确重新下载 pdb。

   f:\symbols>set _NT_
    _NT_SYMBOL_PATH=srv*f:\symbols*https://msdl.microsoft.com/download/symbols
    
    f:\symbols>dir /s /b *.error
    f:\symbols\windows.ui.xaml.pdb\7349BE8DF456ACFBEE7774E6197449541\downloadDA83A900E9B74A20B6A95465B35021C5.error

如果您的平台是 x64,如已评论的那样
前四个参数通过 rcx,rdx,r8, and r9 在 windows 上传递

任意二进制文件上的中断 LoadLibraryExW

0:000> k4
Child-SP          RetAddr           Call Site
000000a4`6013eda8 00007ffb`f5df62f1 KERNELBASE!LoadLibraryExW
000000a4`6013edb0 00007ffb`f5df6449 ucrtbase!try_get_function+0xa9
000000a4`6013ee00 00007ffb`f5df5e80 ucrtbase!_vcrt_FlsAlloc+0x25
000000a4`6013ee30 00007ffb`f5df5cb9 ucrtbase!_vcrt_initialize_ptd+0x10
0:000> r rcx,rdx,r8,r9
rcx=00007ffbf5e778a0 rdx=0000000000000000 r8=0000000000000800 r9=00007ffbf5e75a70
0:000> du @rcx
00007ffb`f5e778a0  "api-ms-win-core-fibers-l1-1-1"
0:000> ? @r8
Evaluate expression: 2048 = 00000000`00000800
0:000> .shell -ci ".echo looking for 0x800" pss LOAD_.*0x00000800 "c:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\libloaderapi.h"
c:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\libloaderapi.h:409:#define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
.shell: Process exited
0:000>  

编辑

LoadLibrary Api 以各种格式获取其输入字符串

  1. 像内核这样的裸名,
  2. 带有 kernel.dll 等扩展名的名称
  3. 相对路径和绝对路径
  4. 小写和大写,例如 foo.dll 和 BAR.DLL

所以它是一个与内置脚本和 $spat 运算符进行字符串比较的皮塔

尝试编写如下所示的 javascript 来减轻痛苦(仅测试一次)

/// <reference path="JSProvider.d.ts" />
"use strict";
var prevlibs =[];
function libname() {    
    var addr = host.currentThread.Registers.User.rcx;
    var libstr = host.memory.readWideString(addr).toLowerCase()
    var cond = libstr.includes("imm32.dll");
    if (cond) {
        host.diagnostics.debugLog("breaking\n");
    }
    else {
        prevlibs.push(libstr);
        host.namespace.Debugger.Utility.Control.ExecuteCommand("gc");
    }
    return prevlibs;
}

用法和结果如下imm32用来展示case和abs路径输入

0:000> .scriptload f:\wdscr\libname.js
JavaScript script successfully loaded from 'f:\wdscr\libname.js'
0:000> bp KERNELBASE!LoadLibraryExW "dx @$scriptContents.libname()"
0:000> g
KERNELBASE!LoadLibraryExW:
00007ffb`f60ee840 4055            push    rbp
0:000> du @rcx
0000006d`3f56e8f0  "C:\WINDOWS\system32\IMM32.DLL"
0:000> dx @$scriptContents.libname()
breaking
@$scriptContents.libname() : api-ms-win-core-synch-l1-2-0,api-ms-win-core-fibers-l1-1-1,api-ms-win-core-fibers-l1-1-1,api-ms-win-core-synch-l1-2-0,api-ms-win-core-localization-l1-2-1,kernel32,api-ms-win-core-string-l1-1-0,api-ms-win-core-datetime-l1-1-1,api-ms-win-core-localization-obsolete-l1-2-0,api-ms-win-core-file-l1-2-1.dll,api-ms-win-eventing-provider-l1-1-0.dll,ole32.dll
    length           : 0xc
    [0x0]            : api-ms-win-core-synch-l1-2-0
    [0x1]            : api-ms-win-core-fibers-l1-1-1
    [0x2]            : api-ms-win-core-fibers-l1-1-1
    [0x3]            : api-ms-win-core-synch-l1-2-0
    [0x4]            : api-ms-win-core-localization-l1-2-1
    [0x5]            : kernel32
    [0x6]            : api-ms-win-core-string-l1-1-0
    [0x7]            : api-ms-win-core-datetime-l1-1-1
    [0x8]            : api-ms-win-core-localization-obsolete-l1-2-0
    [0x9]            : api-ms-win-core-file-l1-2-1.dll
    [0xa]            : api-ms-win-eventing-provider-l1-1-0.dll
    [0xb]            : ole32.dll
0:000>  

【讨论】:

  • 所以首先,似乎已添加符号。缓存中没有错误文件,但今天下载了。在我确实做了一个嘈杂的负载并看到它试图下载文件但没有得到它之前。我现在唯一需要的是找出条件断点的字符串比较。
  • @jus 尝试获取Time Travel Debugging 跟踪。该工具提供了丰富的查询语言,可以更快地导航到感兴趣的点。
  • 添加了一个demo供大家评论看看
猜你喜欢
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多