作者:thiji_0 | 来源:互联网 | 2023-06-29 16:42
在kd中查看某一确定用户态进程加载的dll,这不是什么刚需,甚至可以说是一个伪需求。我只是用这个做引子,介绍一些windbg命令。
1)
最简单的办法,切换到目标进程,然后:
.reload /user
lmuf
2)
shellcode常用办法,遍历三条链表。
!list -t nt!_LIST_ENTRY.Flink -x "r $t0=@@(#CONTAINING_RECORD(@$extret,nt!_LDR_DATA_TABLE_ENTRY,InLoadOrderLinks));r @$t0,@$extret;dt -io nt!_LDR_DATA_TABLE_ENTRY DllBase FullDllName @$t0" @@(@$peb->Ldr->InLoadOrderModuleList.Flink)
notepad.exe
ntdll.dll
KERNEL32.DLL
KERNELBASE.dll
ADVAPI32.dll
msvcrt.dll
...
按"初始化顺序"前向遍历链表时,第一个结点对应ntdll.dll。按"加载顺序"、"内存顺序"前向遍历,第一个结点对应EXE,第二个结点才对应ntdll.dll。"初始化顺序"要少一个结点。
"!list"不支持后向遍历,或者说它无法用Blink遍历。
3)
其实也是遍历链表,只不过我演示一下用dx遍历。
dx -g Debugger.Utility.Collections.FromListEntry(@$peb->Ldr->InLoadOrderModuleList,"nt!_LDR_DATA_TABLE_ENTRY","InLoadOrderLinks").Select(o=>new{DllBase=o._LDR_DATA_TABLE_ENTRY::DllBase,FullDllName=o._LDR_DATA_TABLE_ENTRY::FullDllName}),0x1000
4)
dx有内置的模块列表支持,不需要遍历链表:
dx -g @$curprocess.Modules.Where(o=>o.BaseAddress<0xf000000000000000).Select(o=>new{BaseAddress=o.BaseAddress,Name=o.Name}),0x1000
看这个输出,应该是按照加载基址升序排列。
5)
windbg有个!dll扩展命令
按加载顺序遍历:
!dll -l
按内存顺序遍历:
!dll -m
按初始化顺序遍历:
!dll -i
输出形如:
不管哪种顺序遍历,打头的地址指向nt!_LDR_DATA_TABLE_ENTRY结构。
6)
windbg有个!peb扩展命令
kd> .shell -ci "!peb @$peb" findstr /i /c:".dll"
kd> .shell -ci "!peb @$peb" find /i ".dll"
顺便说一句,Tarik Soulami介绍kd调试的某些技术原理,提到尽管目标地址未被扇入,并不影响对之设0xCC断点。扇入目标内存时,处理缺页异常的代码会真正写入0xCC。看了一下缺页异常,以x64/Win10为例补充了两条代码路径,包括内核态调试时断点命中后g起来写回0xCC的代码路径。虽然这个道理一直知道,但确实没有如此近距离地观察过这条代码路径。更新scz.617.cn/windows/201711151139.txt,在PC上直接拖到文末看更新部分。
周期性吐槽,微信订阅号只能当RSS用,截图是因为无法排版。感兴趣者请在PC上用浏览器查看原文。