windbg 相关问题

WinDbg是Windows的用户和内核模式调试器。它可用于调试本机代码和托管代码。

使用WinDbg分析.NET服务高内存使用率

我遇到了一个问题,即在云上运行的一个使用.Net4.8编写的Web服务内存使用率过高的问题。监控工具警告内存峰值达到1.4GB。我转储了该进程的

回答 1 投票 0

在 Windbg 断点基于操作中使用 WinApi 32

我正在阅读有关 Windbg 基于断点的操作,它就像触发断点时在调试器中自动执行命令一样。 例如这个: 0:005> bp kernel32!写...

回答 1 投票 0

Windbg 需要不同版本的 mscordacwks.dll

我在尝试使用windbg 调试小型转储文件时遇到一个非常奇怪的问题。 我已经在我自己的机器上尝试过这个,并在小型转储所在的目标机器上运行windbg...

回答 2 投票 0

分析windbg中的故障转储

我正在使用第三方闭源API,它会抛出一个异常,指出“所有命名管道都忙”。 我想进一步调试(而不是单步调试),这样我实际上就可以

回答 5 投票 0

如何确定WinDbg中以空结尾的字符串的长度

正在调试的目标进程的地址空间中存在以空结尾的 ASCII 字符串。我想编写一个WinDbg脚本来打印出这个字符串的长度。假设我知道...

回答 4 投票 0

跟踪 Windows Crypto API 中的 CSP 调用

我正在使用 Windows Server 2008 R2 证书颁发机构进行私钥存档。在客户端,我有兴趣知道 Windows 进程调用了哪些 Crypto API 函数...

回答 2 投票 0

WinDbg/SOS:!SyncBlk 输出说明

我正在寻找 SOS 的 !SyncBlk 命令生成的输出的描述。 特别是我在“MonitorHeld”列中没有找到有用的解释。此列显示了系列中的高值...

回答 2 投票 0

编辑系统转储(核心文件)并写入WinDBG中的新文件

我将核心文件加载到 winDBG 中并对其进行了所需的更改。问题是,我需要写回来。由于我正在测试调试器,因此我需要对核心进行更改。我知道如何使用 .

回答 1 投票 0

Windows Handle 如何关联对应的对象类型?

有两个文件。一个是LearnHanle.exe(拼写错误,应该是LearnHandle.exe),另一个是pop.exe。 这些文件的源代码在这里: // 学习Hanle.cpp #包括 有两个文件。一个是LearnHanle.exe(拼写错误,应该是LearnHandle.exe),另一个是pop.exe。 这些文件的源代码在这里: // LearnHanle.cpp #include <windows.h> #include <stdlib.h> #include <stdio.h> int main() { STARTUPINFOW startup = { 0 }; startup.cb = sizeof startup; PROCESS_INFORMATION pi = { 0 }; BOOL createProcResult = FALSE; if (!CreateProcessW(L"C:\\pop.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &pi)) MessageBoxA(NULL, "Create Process Failed", "Alert", MB_OK); char handle[80] = { 0 }; sprintf_s(handle, "Process Handle: %llu ProcessId: %llu", pi.hProcess, pi.dwProcessId); MessageBoxA(NULL, handle, "Process", MB_OK); sprintf_s(handle, "Thread Handle: %llu ThreadId: %llu", pi.hThread, pi.dwThreadId); MessageBoxA(NULL, handle, "Thread", MB_OK); system("pause"); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } // pop.cpp #include <windows.h> #include <stdlib.h> #include <stdio.h> int main() { MessageBox(0, 0, 0, 0); // Just sleep Sleep(6000000); } LearnHanle.exe 只是创建 pop.exe 进程,然后自行挂起。 我用LearnHanle.exe查看了Process Explorer进程的详细信息,找到了与pop.exe进程关联的HANDLE,然后就得到了HANDLE地址,如下所示: Basic Information Name: pop.exe(9092) Type: Process Description: Contains threads, an address space, and handles. Address: 0xFFFFE786E04AF080 我用WinDbg调试了Windows 11内核,我使用!object命令查看HANDLE地址。输出在这里: 0: kd> !object 0xffffe786e04af080 Object: ffffe786e04af080 Type: (ffffe786da2cfd20) Process ObjectHeader: ffffe786e04af050 (new version) HandleCount: 9 PointerCount: 293899 ObjectHeader指针指向_EPROCESS进程的pop.exe的对象头: 0: kd> dt _OBJECT_HEADER ffffe786e04af050 nt!_OBJECT_HEADER +0x000 PointerCount : 0n293899 +0x008 HandleCount : 0n9 +0x008 NextToFree : 0x00000000`00000009 Void +0x010 Lock : _EX_PUSH_LOCK +0x018 TypeIndex : 0x47 'G' +0x019 TraceFlags : 0 '' +0x019 DbgRefTrace : 0y0 +0x019 DbgTracePermanent : 0y0 +0x01a InfoMask : 0x88 '' +0x01b Flags : 0 '' +0x01b NewObject : 0y0 +0x01b KernelObject : 0y0 +0x01b KernelOnlyAccess : 0y0 +0x01b ExclusiveObject : 0y0 +0x01b PermanentObject : 0y0 +0x01b DefaultSecurityQuota : 0y0 +0x01b SingleHandleEntry : 0y0 +0x01b DeletedInline : 0y0 +0x01c Reserved : 0 +0x020 ObjectCreateInfo : 0xffffe786`dca5ccc0 _OBJECT_CREATE_INFORMATION +0x020 QuotaBlockCharged : 0xffffe786`dca5ccc0 Void +0x028 SecurityDescriptor : 0xffffd705`63f2962f Void +0x030 Body : _QUAD 但是, 0: kd> dq 0xffffe786e04af080 ffffe786`e04af080 00000000`00000003 ffffe786`e04af088 ffffe786`e04af090 ffffe786`e04af088 ffffe786`e04af098 ffffe786`e04af0a0 ffffe786`e04af098 00000000`9e0b9000 ffffe786`e04af0b0 ffffe786`df8ec378 ffffe786`df8ec378 ffffe786`e04af0c0 00000000`00000000 00000000`00000000 ffffe786`e04af0d0 00000000`00200001 00000000`0000000f ffffe786`e04af0e0 00000000`00000000 00000000`00000000 ffffe786`e04af0f0 00000000`00000000 00000000`00000000 我不知道该地址存储什么,以及!object命令如何获取pop.exe进程的信息。 然后我使用!process命令查看主机进程LearnHanle.exe。 0: kd> !process 0 0 LearnHanle.exe PROCESS ffffe786e04020c0 SessionId: 1 Cid: 22a8 Peb: 0036b000 ParentCid: 1344 DirBase: 999c2000 ObjectTable: ffffd70567953400 HandleCount: 121. Image: LearnHanle.exe 我看了LearnHanle.exe_HANDLE_TABLE。 0: kd> dt _HANDLE_TABLE ffffd70567953400 nt!_HANDLE_TABLE +0x000 NextHandleNeedingPool : 0x400 +0x004 ExtraInfoPages : 0n0 +0x008 TableCode : 0xffffd705`6645a000 +0x010 QuotaProcess : 0xffffe786`e04020c0 _EPROCESS +0x018 HandleTableList : _LIST_ENTRY [ 0xffffd705`67953bd8 - 0xffffd705`67133918 ] +0x028 UniqueProcessId : 0x22a8 +0x02c Flags : 0 +0x02c StrictFIFO : 0y0 +0x02c EnableHandleExceptions : 0y0 +0x02c Rundown : 0y0 +0x02c Duplicated : 0y0 +0x02c RaiseUMExceptionOnInvalidHandleClose : 0y0 +0x030 HandleContentionEvent : _EX_PUSH_LOCK +0x038 HandleTableLock : _EX_PUSH_LOCK +0x040 FreeLists : [1] _HANDLE_TABLE_FREE_LIST +0x040 ActualEntry : [32] "" +0x060 DebugInfo : (null) 0: kd> dt _HANDLE_TABLE_ENTRY nt!_HANDLE_TABLE_ENTRY +0x000 VolatileLowValue : Int8B +0x000 LowValue : Int8B +0x000 InfoTable : Ptr64 _HANDLE_TABLE_ENTRY_INFO +0x008 HighValue : Int8B +0x008 NextFreeHandleEntry : Ptr64 _HANDLE_TABLE_ENTRY +0x008 LeafHandleValue : _EXHANDLE +0x000 RefCountField : Int8B +0x000 Unlocked : Pos 0, 1 Bit +0x000 RefCnt : Pos 1, 16 Bits +0x000 Attributes : Pos 17, 3 Bits +0x000 ObjectPointerBits : Pos 20, 44 Bits +0x008 GrantedAccessBits : Pos 0, 25 Bits +0x008 NoRightsUpgrade : Pos 25, 1 Bit +0x008 Spare1 : Pos 26, 6 Bits +0x00c Spare2 : Uint4B 我想知道进程句柄表中的句柄表项如何与相应的对象类型关联。 而且我也想知道这两位成员的目的:struct _HANDLE_TABLE_ENTRY::ObjectPointerBits、struct _OBJECT_HEADER::TypeIndex和struct _KPROCESS::Header(_DISPATCHER_HEADER)。 作为示例,我将从资源管理器进程 (6496) 获取文件句柄 (0x1c8): 1: kd> !handle 0x1c8 3 0n6496 PROCESS ffffe4856647a080 SessionId: 2 Cid: 1960 Peb: 00238000 ParentCid: 1904 DirBase: 1409e3002 ObjectTable: ffffd10029c47740 HandleCount: 2981. Image: explorer.exe Handle table at ffffd10029c47740 with 2981 entries in use 01c8: Object: ffffe48565dd7110 GrantedAccess: 00100001 (Inherit) (Audit) Entry: ffffd10029ff9720 Object: ffffe48565dd7110 Type: (ffffe485608f7220) File ObjectHeader: ffffe48565dd70e0 (new version) HandleCount: 1 PointerCount: 32783 Directory Object: 00000000 Name: \Windows\en-US\explorer.exe.mui {HarddiskVolume3} 从_EPROCESS的手柄表开始: 0: kd> dt nt!_eprocess ffffe4856647a080 -y ObjectTable nt!_EPROCESS +0x570 ObjectTable : 0xffffd100`29c47740 _HANDLE_TABLE 0: kd> dt nt!_handle_table 0xffffd100`29c47740 nt!_HANDLE_TABLE +0x000 NextHandleNeedingPool : 0x3800 +0x004 ExtraInfoPages : 0n0 +0x008 TableCode : 0xffffd100`29ef4001 +0x010 QuotaProcess : 0xffffe485`6647a080 _EPROCESS +0x018 HandleTableList : _LIST_ENTRY [ 0xffffd100`29c47418 - 0xffffd100`29c47d98 ] +0x028 UniqueProcessId : 0x1960 +0x02c Flags : 0 +0x02c StrictFIFO : 0y0 +0x02c EnableHandleExceptions : 0y0 +0x02c Rundown : 0y0 +0x02c Duplicated : 0y0 +0x02c RaiseUMExceptionOnInvalidHandleClose : 0y0 +0x030 HandleContentionEvent : _EX_PUSH_LOCK +0x038 HandleTableLock : _EX_PUSH_LOCK +0x040 FreeLists : [1] _HANDLE_TABLE_FREE_LIST +0x040 ActualEntry : [32] "" +0x060 DebugInfo : (null) TableCode字段指向一个表数组,较低位决定应使用哪个表: 0: kd> dq 0xffffd100`29ef4000 ffffd100`29ef4000 ffffd100`29ff9000 ffffd100`29ef5000 ffffd100`29ef4010 ffffd100`255fd000 ffffd100`29d96000 ffffd100`29ef4020 ffffd100`2a1fd000 ffffd100`2a0f7000 ffffd100`29ef4030 ffffd100`258bc000 ffffd100`25b5a000 ffffd100`29ef4040 ffffd100`25bff000 ffffd100`25cfc000 ffffd100`29ef4050 ffffd100`25b57000 ffffd100`25dfe000 ffffd100`29ef4060 ffffd100`258c6000 ffffd100`2802c000 ffffd100`29ef4070 00000000`00000000 00000000`00000000 nt!ExpLookupHandleTableEntry中的代码有助于确定如何使用表数组(第一个参数是RCX中的_HANDLE_TABLE*,第二个参数是RDX中的句柄): PAGE:00000001407427E0 ExpLookupHandleTableEntry proc near ; CODE XREF: ObDuplicateObject+180↑p PAGE:00000001407427E0 ; ExMapHandleToPointer+11↑p ... PAGE:00000001407427E0 PAGE:00000001407427E0 ; FUNCTION CHUNK AT PAGE:0000000140895396 SIZE 00000022 BYTES PAGE:00000001407427E0 PAGE:00000001407427E0 mov eax, [rcx+_HANDLE_TABLE.NextHandleNeedingPool] PAGE:00000001407427E2 and rdx, 0FFFFFFFFFFFFFFFCh PAGE:00000001407427E6 cmp rdx, rax PAGE:00000001407427E9 jnb short loc_140742820 PAGE:00000001407427EB mov r8, [rcx+_HANDLE_TABLE.TableCode] PAGE:00000001407427EF mov eax, r8d PAGE:00000001407427F2 and eax, 3 PAGE:00000001407427F5 cmp eax, 1 PAGE:00000001407427F8 jnz short loc_140742812 PAGE:00000001407427FA mov rax, rdx PAGE:00000001407427FD shr rax, 0Ah PAGE:0000000140742801 mov rax, [r8+rax*8-1] PAGE:0000000140742806 PAGE:0000000140742806 loc_140742806: ; CODE XREF: ExpLookupHandleTableEntry+152BD3↓j PAGE:0000000140742806 and edx, 3FFh PAGE:000000014074280C lea rax, [rax+rdx*4] PAGE:0000000140742810 retn PAGE:0000000140742810 ; --------------------------------------------------------------------------- PAGE:0000000140742811 align 2 PAGE:0000000140742812 PAGE:0000000140742812 loc_140742812: ; CODE XREF: ExpLookupHandleTableEntry+18↑j PAGE:0000000140742812 test eax, eax PAGE:0000000140742814 jnz loc_140895396 PAGE:000000014074281A lea rax, [r8+rdx*4] PAGE:000000014074281E retn PAGE:000000014074281E ; --------------------------------------------------------------------------- PAGE:000000014074281F align 20h PAGE:0000000140742820 PAGE:0000000140742820 loc_140742820: ; CODE XREF: ExpLookupHandleTableEntry+9↑j PAGE:0000000140742820 xor eax, eax PAGE:0000000140742822 retn PAGE:0000000140742822 ExpLookupHandleTableEntry endp 在我的例子中,它只是数组中的第一个表,因此句柄条目位于table_base + (handle * 4)。尽管每个表条目都是 _HANDLE_TABLE_ENTRY(大小为 0x10),但每个句柄都是 4 的倍数(因此 0x10 / 4 = 4): 1: kd> ? ffffd100`29ff9000 + (0x1c8 * 4) Evaluate expression: -51676341889248 = ffffd100`29ff9720 表格条目: 1: kd> dt _handle_table_entry ffffd100`29ff9720 nt!_HANDLE_TABLE_ENTRY +0x000 VolatileLowValue : 0n-1980064459403493377 +0x000 LowValue : 0n-1980064459403493377 +0x000 InfoTable : 0xe48565dd`70e0ffff _HANDLE_TABLE_ENTRY_INFO +0x008 HighValue : 0n1048577 +0x008 NextFreeHandleEntry : 0x00000000`00100001 _HANDLE_TABLE_ENTRY +0x008 LeafHandleValue : _EXHANDLE +0x000 RefCountField : 0n-1980064459403493377 +0x000 Unlocked : 0y1 +0x000 RefCnt : 0y0111111111111111 (0x7fff) +0x000 Attributes : 0y000 +0x000 ObjectPointerBits : 0y11100100100001010110010111011101011100001110 (0xe48565dd70e) +0x008 GrantedAccessBits : 0y0000100000000000000000001 (0x100001) +0x008 NoRightsUpgrade : 0y0 +0x008 Spare1 : 0y000000 (0) +0x00c Spare2 : 0 这里至少有两个有趣的东西: GrantedAccessBits:这是对象的授予访问掩码(这里有 0x100001,对于文件对象来说它只是 SYNCHRONIZE (0x10000) | FILE_READ_DATA (0x1) ObjectPointerBits:经过计算后将是指向对象_OBJECT_HEADER的指针。 根据 ObjectPointerBits 值,您需要执行以下操作来获取对象头地址:(ObjectPointerBits << 4) | 0xffff000000000000 1: kd> ? (0xe48565dd70e << 4) | 0xffff000000000000 Evaluate expression: -30213385916192 = ffffe485`65dd70e0 1: kd> dt _object_header ffffe485`65dd70e0 nt!_OBJECT_HEADER +0x000 PointerCount : 0n32783 +0x008 HandleCount : 0n1 +0x008 NextToFree : 0x00000000`00000001 Void +0x010 Lock : _EX_PUSH_LOCK +0x018 TypeIndex : 0x14 '' +0x019 TraceFlags : 0 '' +0x019 DbgRefTrace : 0y0 +0x019 DbgTracePermanent : 0y0 +0x01a InfoMask : 0x4c 'L' +0x01b Flags : 0 '' +0x01b NewObject : 0y0 +0x01b KernelObject : 0y0 +0x01b KernelOnlyAccess : 0y0 +0x01b ExclusiveObject : 0y0 +0x01b PermanentObject : 0y0 +0x01b DefaultSecurityQuota : 0y0 +0x01b SingleHandleEntry : 0y0 +0x01b DeletedInline : 0y0 +0x01c Reserved : 0 +0x020 ObjectCreateInfo : 0xffffe485`62c5ecc0 _OBJECT_CREATE_INFORMATION +0x020 QuotaBlockCharged : 0xffffe485`62c5ecc0 Void +0x028 SecurityDescriptor : (null) +0x030 Body : _QUAD 从对象头中,您可以通过执行以下计算来获取对象类型: *((BYTE*)nt!ObHeaderCookie) ^ second_byte_of_object_header_address ^ _OBJECT_HEADER.TypeIndex 1: kd> db nt!ObHeaderCookie L1 fffff800`7911ed74 4c 1: kd> ? (ffffe485`65dd70e0 >> 8) & 0xff Evaluate expression: 112 = 00000000`00000070 1: kd> dt _object_header ffffe485`65dd70e0 -y TypeIndex nt!_OBJECT_HEADER +0x018 TypeIndex : 0x14 '' 1: kd> ? 0x4c ^ 0x70 ^ 0x14 Evaluate expression: 40 = 00000000`00000028 上面的结果(在本例中为 0x28)是内核类型数组的索引,该数组是一个名为 nt!ObTypeIndexTable 的全局变量(_OBJECT_TYPE 的数组): 1: kd> dt _OBJECT_TYPE poi(nt!ObTypeIndexTable + (0x28 * 8)) nt!_OBJECT_TYPE +0x000 TypeList : _LIST_ENTRY [ 0xffffe485`608f7220 - 0xffffe485`608f7220 ] +0x010 Name : _UNICODE_STRING "File" +0x020 DefaultObject : 0x00000000`0000009b Void +0x028 Index : 0x28 '(' +0x02c TotalNumberOfObjects : 0x27cc +0x030 TotalNumberOfHandles : 0xaae +0x034 HighWaterNumberOfObjects : 0x2a42 +0x038 HighWaterNumberOfHandles : 0xd36 +0x040 TypeInfo : _OBJECT_TYPE_INITIALIZER +0x0b8 TypeLock : _EX_PUSH_LOCK +0x0c0 Key : 0x656c6946 +0x0c8 CallbackList : _LIST_ENTRY [ 0xffffe485`608f72e8 - 0xffffe485`608f72e8 ] 所以它是一个文件对象(由 nt!FILE_OBJECT 表示)。 _DISPATCHER_HEADER 如果一个对象是可等待的(即它的句柄可以传递给WaitForSingleObject或WaitForMutipleObjects),那么它有一个_DISPATCH_HEADER。

回答 1 投票 0

使用windbg内核态调试从模块地址找到driverObject

我有已加载驱动程序的模块地址。我想在内核模式调试中使用windbg从模块地址或名称中获取驱动程序对象。有没有命令可以找到它?

回答 1 投票 0

核心转储文件批处理(Windows)

我有许多来自客户的核心转储(或小型转储)文件(.dmp) 我可以在 MS Visual Studio 中打开每个并查看调用堆栈。 我也可以使用 WinDBG 来完成。 但因为有很多而且我想要

回答 1 投票 0

我的配置的正确 _NT_SYMBOL_PATH 是什么?

好吧,我已经研究这个问题有一段时间了,但不知道问题出在哪里。我有预感它可能是 _NT_SYMBOL_PATH 或 Microsoft 符号服务器。我正在运行本地调试...

回答 1 投票 0

windbg .shell 将整个脚本传递给 cmd,以“命令行太长”结尾

我正在尝试在windbg脚本文件中创建一个文件夹。如果我只是打开windbg,我可以使用.shell -ci "*" mkdir C:\mydir 来完成。但是,如果我在 Windbg sc 中输入完全相同的命令...

回答 1 投票 0

WinDBG 无法读取使用 _NT_SYMBOL_PATH 环境变量设置的符号路径字符串

我已将环境变量 _NT_SYMBOL_PATH 设置为以下值 SRV*C:\My\Sym*http://msdl.microsoft.com/download/symbols 我还确保目录 C:\My\Sym 实际上确实存在。

回答 1 投票 0

_NT_SYMBOL_PATH 格式

我尝试更多地使用windbg,但符号缓存一直存在问题。我不清楚字符串的格式应该是什么。 我有几个要求: 使用微软的se...

回答 2 投票 0

为什么TimerThread中int64数组这么大

我正在调查32位进程中的OutOfMemoryException, 以下统计数据引起了我的注意(大型 int64 数组): !dumpheap -stat ………… 707b251c 3 692500 系统.Int64[] 6fa6b...

回答 1 投票 0

windbg的ah系列命令如何使用?

我无法弄清楚ah系列命令的Address参数是什么。 这是 ah 系列命令的 msdn。 https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggerc...

回答 1 投票 0

0x0000ffff是windows下dll的默认加载次数吗?

使用windbg,通过!dlls命令获取带有加载计数的dll列表。观察到许多加载的 dll 的加载计数为 0x0000ffff。 这是默认值吗? 这还有别的意思吗?

回答 2 投票 0

有没有Windbg命令可以查出进程是32位还是64位?

是否有 Windbg/NTSD 命令可以告诉我在实时调试会话中附加的进程是 32 位进程还是 64 位进程? 您能告诉我两者吗: 不受管理的流程? 一个...

回答 2 投票 0

通过调试引擎API读取Dump文件

我使用调试引擎API编写了一个小程序来读取转储文件。 我正在通过代码执行 !analyze -v 命令。 我能够获得几乎所有可以通过上面提取的细节

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.