ln 命令显示给定地址处的或者最近的符号。
ln表示list near,ln命令将尽可能地给出与特定地址相关的符号,如果没有符号能够精确地与这个地址匹配,那么调试器将通过指针算法对靠近这地址的符号进行运逄,
并返回运算结果符号
0:000> ln 01012475 (01012475) calc!WinMainCRTStartup | (0101263c) calc!__CxxFrameHandler Exact matches: calc!WinMainCRTStartup = <no type information> 0:000> ln 01012475+1 (01012475) calc!WinMainCRTStartup+0x1 | (0101263c) calc!__CxxFrameHandler
我们发现,第一个显示为Exact matches:表示精确匹配了一个地址,如果不是精确匹配,我们要小心,是否模块进行了优化,在优化后,一个函数,可能被拆分为多个部分
分别位于不同的地址,经过优化的映像可以通过lm查看:会有perf标识
当你在查看某部分数据,却不知道这部分数据所表示的内容时,这个命名能带来极大的帮助
对于那些偶尔使用调试器的用户是很难记得所有平台的指令指针寄存器名字(或其他的名字),为了克服这个问题,调试器的开发团队引入了各种伪寄存器,由调试器把这些伪寄存器对应到不同的硬件架构上,形式为$name,与标准的寄存器一样,如果要在表达式中使用伪寄存器,那么必须使用转义字符@
0:002> r $exentry $exentry=01012475
一般可以直接在这下断点,
这个就对应PE文件中的ImageBase+AddressOfEntryPoint(_IMAGE_OPTIONAL_HEADER)
指令指针寄存器
在X86架构上,$ip = eip
在x64架构上,$ip = rip
在Itanium架构上, $ip = iip
x86/x64/ia-64的区别
0:000> r @$ip $ip=7c92120e 0:000> r eip eip=7c92120e
注意到下面显示的分别是$ip,eip,虽然它们在X86下是同一个东东.
当前函数的返回地址
0:000> r $ra $ra=7c95e612 0:000> kb ChildEBP RetAddr Args to Child 0012fb1c 7c95e612 7ffdd000 7ffde000 00000000 ntdll!DbgBreakPoint 0012fc94 7c94108f 0012fd30 7c920000 0012fce0 ntdll!LdrpInitializeProcess+0xffa 0012fd1c 7c92e437 0012fd30 7c920000 00000000 ntdll!_LdrpInitialize+0x183 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7
其实也是对应当前线程,如果要看所有线程的当前函数的返回地址:
0:000> ~* r $ra $ra=77d191be $ra=7c92df2c $ra=7c92df3c $ra=7c970010
主要的值寄存器,在函数调用返回后,函数的结果将放在这个寄存器中,根据处理器架构的不同,$retreg的值分别为
在x86架构上,$retreg = eax
在x64架构上,$retreg = rax
在Itanium架构上,$retreg = ret0
0:000> r $retreg $retreg=00251eb4 0:000> r eax eax=00251eb4
当前的栈指针,根据处理器架构的不同,$csp的值分别为
在x86架构上,$csp = esp
在x64架构上,$csp = rsp
在Itanium架构上,$csp = bsp
0:000> r $csp $csp=0012fb24 0:000> r esp esp=0012fb24
当前进程的标识(PID)
0:000> r $tpid $tpid=000013f4
当前线程的标识(TID0
0:000> r $tid $tid=000014a0
伪寄存器 | 描述 |
---|---|
$ea | 最后一条被执行指令的有效地址(effective address)。如果这条指令没有一个有效地址,将显示"Bad register error"。如果这条指令有两个有效地址,则显示第一个地址。 |
$ea2 | 最后一条被执行指令的第二个有效地址,如果这条指令没有两个有效地址,将显示"Bad register error"。 |
$exp | 最后一个被求值的表达式。 |
$ra | 当前堆栈的返回地址。 这个在执行命令中特别有用。例如,g @$ra 将一直执行到返回地址处(虽然,对于“步出(stepping out)”当前函数gu (Go Up)是一个更加准备有效的方法)。 |
$ip | 指令指针寄存器: x86 处理器:和 eip 相同 Itanium 处理器:涉及 iip(请看表后的注解) x64处理器:和rip相同 |
$eventip | 当前事件发生时的指令指针,通常和 $ip 匹配,除非你切换了线程或者手动改变了指令指针的值。 |
$previp | 前一个事件发生时的指令指针。(中断进入调试器算做一个事件。) |
$relip | 和当前事件相关的指令指针,当你正在跟踪分支指令时,这个是分支来源指针。 |
$scopeip | 当前局部上下文(也称为作用域)的指令指针。 |
$exentry | 当前进程的第一个可执行的入口点地址。 |
$retreg | 主要的返回值寄存器: x86 处理器:和 eax 相同 Itanium 处理器:和 ret0 相同 x64 处理器:和 rax 相同 |
$retreg64 | 主要的返回值寄存器,以64位格式。 x86处理器:和edx:eax 相同 |
$csp | 当前调用堆栈指针,是一个通常表示调用堆栈深度的寄存器。 x86 处理器:和 esp 相同 Itanium 处理器:和 bsp 相同 x64 处理器:和 rsp 相同 |
$p | 最后一条 d* (Display Memory)命令打印的值。 |
$proc | 当前进程的地址(换句话说,就是 EPROCESS 块的地址)。 |
$thread | 当前线程的地址(换句话说,就是 ETHREAD 块的地址)。 |
$peb | 当前进程的进程环境块(PEB)的地址。 |
$teb | 当前线程的线程环境块(TEB)的地址。 |
$tpid | 当前线程所在进程的进程 ID(PID)。 |
$tid | 当前线程的线程 ID。 |
$bpNumber | 对应断点的地址。例如,$bp3(或者 $bp03)引用断点 ID 为 3 的断点。Number 总是一个十进制数,如果没有哪个断点的 ID 为Number,则$bpNumber 求值为 0,详细请看使用断点。 |
$frame | 当前帧索引,这个和.frame (Set Local Context) 命令常用的 frame number 相同。 |
$dbgtime | 当前时间,根据调试器运行的计算机。 |
$callret | 被.call (Call Function)命令调用的或者被.fnret /s命令使用的最后函数得到的返回值,$callret 的数据类型就是返回值的数据类型。 |
$lastclrex | 仅托管代码调试: 最近一次遇到的公共语言运行时(CLR)异常对象的地址。 |
$ptrsize | 指针大小。在内核模式下,指目标计算机上的指针大小。 |
$pagesize | 一个内存页的大小(也就是占用的字节数目),在内核模式下,指目标计算机上的页大小。 |
0:000> x 0026fb80 argc = 1 0026fb84 argv = 0x002d33a0 0026fb70 p = 0x002d1b90 0:000> r $t0 $t0=00000000 0:000> r $t0 = poi(p) 0:000> r $t0 $t0=002d1b90除非 r 命令使用了 ? 开关选项,否则一个伪寄存器总是具有整数类型。如果用到了 ? 选项,则伪寄存器可以获得赋给它的任意类型,例如,下面的命令把 UNICODE_STRING** 类型和 0x0012FFBC 值赋给了 $t15(译注:这里好像是 UNICODE_STRING 类型吧!另外,如果 UNICODE_STRING 解析不了,可以用 _UNICODE_STRING)。
0:000> r? $t15 = * (UNICODE_STRING*) 0x12ffbc
下面可以看出r和r?的区别,比如我的代码有个char* g_char = "I am string";
00bc7004 test1!g_char = 0x00bc573c "I am string" 0:000> r? $t0 = test1!g_char 0:000> r $t0 $t0=00bc573c 0:000> r $t1 = test1!g_char 0:000> r $t1 $t1=00bc7004可以看到$t0保存的是真实的test1!g_char的指针地址,而$t1只是保存了它的对象地址
所以:
0:000> da $t0 00bc573c "I am string" 0:000> da $t1 00bc7004 "<W." 0:000> da test1!g_char 00bc7004 "<W." 0:000> da poi(test1!g_char) 00bc573c "I am string"自己比对吧