一、简介
x32/64 dbg作为一款优秀的调试工具,其调试器必定配套了一系列函数供读者使用的;灵活使用这些函数可以帮助我快速定位,调试,分析软件的相关信息;
二、常用表达式函数
GUI 交互
disasm.sel()/dis.sel()
:在反汇编视图中获取选定的地址。
dump.sel()
:在转储视图中获取选定的地址。
stack.sel()
:在堆栈视图中获取选定的地址。
源
src.disp(addr)
:获取相对于最后一次源行 addr
的位移。
src.line(addr)
:获取 addr
的源行号。
模块
mod.party(addr)
:获取模块的参与方编号 addr
。0 是用户模块,1 是系统模块。
mod.base(addr)
:获取模块 addr
的基地址。
mod.size(addr)
:获取模块 addr
的大小。
mod.hash(addr)
:获取模块 addr
的 hash 值。
mod.entry(addr)
:获取模块 addr
的入口地址。
mod.system(addr)
:如果模块在 addr
是系统模块,则为 True。False:模块是用户模块
mod.user(addr)
:如果模块在 addr
为 True,则是用户模块。False:模块不是用户模块。
mod.main()
:返回主模块(调试对象)的基地址。如果是一个 DLL,则将返回0 直到加载为止。
mod.rva(addr)
:获取 addr
的 RVA。如果 addr
不在模块内,则其将返回0。
mod.offset(addr)
:获取 addr
的文件偏移量。如果 addr
不在模块内,则其将返回0。
mod.isexport(addr)
: 如果 addr
是从模块导出的函数,则为 True。
进程信息
peb()
:获取 PEB 地址。
teb()
:获取 TEB 地址。
tid()
:获取当前线程 ID。
一般用途
bswap(value)
: 字节交换 value. 例如, bswap(44332211)
= 0x11223344.
ternary(condition, val1, val2)
:如果条件为非零,则返回 val1
, 否则返回 val2
。
GetTickCount()
:x64dbg 滴答计数。
内存
mem.valid(addr)
: 如果该值为 true,则 addr
是有效的内存地址。
mem.base(addr)
: 返回 addr
(可更改取决于内存映射模式)内存页的基地址。
mem.size(addr)
: 返回 addr
(可更改取决于内存映射模式)内存页的大小。
mem.iscode(addr)
: 如果该值为 true,则 addr
是可执行的页。
mem.decodepointer(ptr)
:在 ptr
上等于调用 DecodePointer API
,仅工作于 Vista+。
反汇编
dis.len(addr)
:获取在 addr
指令的长度。
dis.iscond(addr)
:如果在 addr
的指令是条件分支,则为 true。
dis.isbranch(addr)
:如果在 addr
的指令是分支(jcc/call),则为 true。
dis.isret(addr)
:如果在 addr
的指令是 ret,则为 true。
dis.iscall(addr)
:如果在 addr
的指令是 call,则为 true。
dis.ismem(addr)
:如果在 addr
的指令有一个内存操作数,则为 true。
dis.isnop(addr)
:如果在 addr
的指令等于 NOP,则为 true。
dis.isunusual(addr)
:如果在 addr
的指令是独特的,则为 true。
dis.branchdest(addr)
:在 addr
(如果按回车键接着会发生的)指令的分支目标。
dis.branchexec(addr)
:如果分支在 addr
转到执行,则为 true。
dis.imm(addr)
:在 addr
指令的立即值。
dis.brtrue(addr)
:在 addr
指令的分支目标。
dis.brfalse(addr)
:如果在 addr
的指令是条件转移,则是下一个指令的地址。
dis.next(addr)
:来自 addr
下一个指令的地址。
dis.prev(addr)
:来自 addr
上一个指令的地址。
dis.iscallsystem(addr)
: 如果 addr
中的指令进入系统模块,则为 True。
跟踪记录
tr.enabled(addr)
:如果跟踪记录在 addr
被启用,则为 true。
tr.hitcount(addr)
:跟踪记录在 addr
上找到的数目。
tr.runtraceenabled()
:如果启用运行跟踪,则为 true。
字节/字(Word)/双字(Dword)/四字(Qword)/指针(Ptr)
ReadByte(addr),Byte(addr),byte(addr)
: Read a byte from addr
and return the value. Example: byte(eax)
reads a byte from memory location [eax]
.
ReadWord(addr),Word(addr),word(addr)
: 读取一个字(2字节)从 addr
并返回该值。
ReadDword(addr),Dword(addr),dword(addr)
: 读取双字(4字节)从 addr
并返回该值。
ReadQword(addr),Qword(addr),qword(addr)
: 读取四字(8字节)从addr
,并返回该值(仅用于x64)。
ReadPtr(addr),ReadPointer(addr),ptr(addr),Pointer(addr),pointer(addr)
: 读取一个指针(4/8 字节)从addr
,并返回该值
函数
func.start():返回函数的开始 addr
的一部分,零除外。
func.end():返回函数的结束 addr
的一部分,零除外。
引用
ref.count()
:在当前引用视图中的条目数。
ref.addr(index)
:获取在 index
引用的地址。零为失败。
参数
这里假设返回地址在堆栈上(例如,在函数内)。
arg.get(index)
:在 index
获取参数(从零开始)。
arg.set(index, value)
:在 index
(从零开始) 到 value
设置参数。
异常
这是一组函数,用于获取有关上一个异常的信息。它们可用于异常断点以构建更高级的条件。
ex.firstchance()
: 最后一个异常是否是首次偶发异常。
ex.addr()
: 最后一个异常地址。
ex.code()
: 最后一个异常代码。
ex.flags()
: 最后一个异常标志。
ex.infocount()
: 最后一个异常信息计数(参数个数)。
ex.info(index)
: 最后一个异常信息,如果索引超出范围,则为零。
插件
作为开源软件,我们可以编写插件来注册自己的表达式函数;
三、表达式函数举例
举例函数:disasm.sel()
为了方便展示,我直接在命令框使用函数,如图所示:
在命令栏执行msg {disasm.sel()}
后,显示结果为0x77091b83
;刚好对应汇编窗口中的鼠标选定的地址;