为啥我在 WinDbg 中看到的是 ntdll 反汇编,而不是我的汇编代码?
Posted
技术标签:
【中文标题】为啥我在 WinDbg 中看到的是 ntdll 反汇编,而不是我的汇编代码?【英文标题】:Why I see ntdll disassembly, not my assembly code in WinDbg?为什么我在 WinDbg 中看到的是 ntdll 反汇编,而不是我的汇编代码? 【发布时间】:2016-01-25 11:36:06 【问题描述】:我想分析我的第一个汇编程序。看寄存器,一步一步执行等等,都是为了学习。
我有问题。拆卸很奇怪。我找不到我的代码。我逐步介绍了一些 ntdll 函数。没有我的 MessageBoxA,没有 ExitProcess 等。
我之前使用过 OllyDbg(32 位),并且 OllyDbg 从程序的正常入口开始执行。 OllyDbg 中的反汇编与我的 MASM 代码非常相似。
我做错了什么?为什么会有不同的拆解?如何单步执行我的代码,而不是 ntdll?
【问题讨论】:
我猜 OllyDbg 知道它如何绕过您的导入表,因此它可以将地址映射到 API 调用 - WinDbg 不是这种情况。只要您不提供符号(.pdb 文件),它就依赖于导出的名称并映射相对于该名称的地址。这就是您所看到的,ntdll!memset
是已知的最接近用于将调用指令地址映射到符号的调试器符号。
【参考方案1】:
ollydbg 解释了 Pe Header 中的入口点地址,并设置了一个临时断点并继续执行直到该地址,如果它是汇编程序,通常是 main,如果是编译器生成的二进制程序,通常是 WinMainCrtStartup
Windbg 不会这样做,它会在系统断点处停止(调试 API 的默认行为)
你有两个选择
如果它是你自己的汇编程序并且你有它的符号 做
.reload /f
bp [your exe]![Your EntryPoint]
bl to confirm if it is right
g to continue execution and break in your code
如果它是您没有源代码的第三方程序
lmm [name of third party binary]
!dh [start address of the third party binary] ( see lm results to know the address)
look for Address of Entry Point
bp [start address of the third party binary] + [Address of entrypoint]
g
windbg 将在用户代码中停止
win7 sp1下calc.exe方法2示例
0:000> lm m calc
start end module name
00210000 002d0000 calc (deferred)
0:000> !dh 210000
---------------------
12D6C address of entry point
0:000> bp 210000+12d6c
0:000> bl
0 e 00222d6c 0001 (0001) 0:**** calc!WinMainCRTStartup
0:000> g
calc!WinMainCRTStartup:
00222d6c e84bfdffff call calc!__security_init_cookie (00222abc)
【讨论】:
您可以简单地使用包含主模块的PE入口点的$exentry
伪寄存器,而不是摆弄!dh
。有关此说明和其他说明,请参阅我的回答。【参考方案2】:
简答:bu $exentry; g
长答案:
一个进程在ntdll
中找到的操作系统代码中开始其用户模式执行,该代码执行各种初始化并最终调用存储在 PE 标头中的入口点。
WinDbg 在所谓的初始断点(或 WinDbg 用语中的 ibp)处中断。 OllyDbg 在此断点后继续运行,并在 PE 入口点设置断点。这很好,除非它搞砸了你。例如,针对 olly 的一个众所周知的反调试技巧是使用自定义 TLS 回调创建二进制文件,这是一个相当深奥的功能。这些回调在 PE 入口点之前被调用,因此 olly 无法检测到。
您确实要做的是在PE入口点上设置一个断点。
困难的方法是像 blabb 那样做 - 使用!dh
转储模块头并在其中记录的地址上设置断点。即使是困难的方法也可以更容易一些,因为在运行!dh
之前不需要lm
。在 WinDbg 中,模块名称在其基地址处解释。例如:
0:000> !dh -f notepad
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (i386)
5 number of sections
55BEBE90 time date stamp Sun Aug 02 18:06:24 2015
...
OPTIONAL HEADER VALUES
10B magic #
12.10 linker version
15400 size of code
1F000 size of initialized data
0 size of uninitialized data
159F0 address of entry point
1000 base of code
然后这只是一个问题:
0:000> bu notepad+159F0
0:000> bl
0 e 002259f0 0001 (0001) 0:**** notepad!WinMainCRTStartup
但简单的方法是使用 WinDbg 的内置 pseudo-registers 之一(“自动伪寄存器”是他们的术语,与用户定义的伪寄存器),即上述$exentry
。
0:000> ? notepad + 159F0 == $exentry
Evaluate expression: 1 = 00000001
0:000> ? $exentry
Evaluate expression: 2251248 = 002259f0
您可以看到002259f0
与我们手动计算的地址相同。
为了完整起见,我注意到$iment(
address
)
运算符提供了任何模块的入口点,而不仅仅是主模块(EXE):
0:000> ? $iment(winspool)
Evaluate expression: 1889096272 = 70995250
0:000> ln $iment(winspool)
Browse module
Set bu breakpoint
(70995250) WINSPOOL!_DllMainCRTStartup | (7099526b) WINSPOOL!__CppXcptFilter
Exact matches:
WINSPOOL!_DllMainCRTStartup (<no parameter info>)
【讨论】:
以上是关于为啥我在 WinDbg 中看到的是 ntdll 反汇编,而不是我的汇编代码?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ntdll.dll 会使我的 c++ 可执行文件崩溃?
关于windbg报错"No symbols for ntdll. Cannot continue."问题
X64 反汇编程序 IDA 和 WINDBG。 IDA 不显示 x64 操作码