表达式函数
你可以在表达式中使用函数。调试器定义了以下函数:
字符串
utf8(addr[, count]):从addr读取以 null 结尾的 UTF-8 字符串并返回该字符串值。当指定count时,字符串将被截断。utf16(addr[, count]):从addr读取以 null 结尾的 UTF-16 字符串并返回该字符串值。当指定count时,字符串将被截断。ansi(addr[, count]):从addr读取以 null 结尾的 ANSI 字符串并返回该字符串值。当指定count时,字符串将被截断。strstr(str1, str2):查找子字符串。示例:strstr(utf8(addr), "abc")。stristr(str1, str2):查找子字符串(不区分大小写)。streq(str1, str2):比较两个字符串。示例:streq(utf8(addr), "abc")。strieq(str1, str2):比较两个字符串(不区分大小写)。strlen(str):计算字符串的长度。
函数 ansi/utf8/utf16 可作为其他接受 str 参数的函数的输入。如果无法读取 addr,则返回空字符串。如果你想让它失败,可以使用 .strict 变体(例如 utf8.strict(rax))。
表达式 utf8(rax) 不返回数字,因此不能用作跟踪条件等。
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的哈希值。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。mod.fromname(str):获取str的模块基址。如果找不到模块则返回0。示例:mod.fromname("ntdll.dll")。
进程信息
peb():获取 PEB 地址。teb():获取 TEB 地址。tid():获取当前线程 ID。kusd()、KUSD()、KUSER_SHARED_DATA():获取KUSER_SHARED_DATA的地址(0x7FFE0000)。
通用功能
bswap(value):字节交换value。例如,bswap(44332211)= 0x11223344。ternary(condition, val1, val2):如果条件非零,返回val1,否则返回val2。GetTickCount():Windows APIGetTickCount(),一个每 1ms 递增的计时器。rdtsc():RDTSC指令的结果,一个 CPU 计时器。在 32 位环境下只返回 32 位结果。isdebuggerfocused():检查 x64dbg 是否获得焦点。x64dbg 获得焦点时返回1,否则返回0。isdebuggeefocused():检查被调试程序是否获得焦点。被调试程序获得焦点时返回1,否则返回0。
内存
mem.valid(addr):如果addr是有效内存地址,则为 True。mem.base(addr):返回addr所在内存页的基址(可能根据你的内存映射模式而变化)。mem.size(addr):返回addr所在内存页的大小(可能根据你的内存映射模式而变化)。mem.iscode(addr):如果addr是可执行页面,则为 True。mem.decodepointer(ptr):相当于对ptr调用DecodePointerAPI,仅在 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。dis.mnemonic(addr):返回addr的助记符str。示例:str.streq(dis.mnemonic(cip), "cpuid")。dis.text(addr):将指令文本作为字符串addr返回。可用于条件,例如:strstr(dis.text(rip), "rbx")。注意:指令文本可能与 GUI 中的格式不完全匹配。dis.match(addr, str):如果addr处的指令匹配str中的正则表达式,则为 True。示例:dis.match(rip, "test.+, 0x1")。你可以使用dis.text来查看可以匹配什么。
跟踪
tr.enabled(addr):如果addr处启用了跟踪覆盖,则为 True。tr.hitcount(addr):addr处跟踪覆盖的命中次数。tr.isrecording()、tr.runtraceenabled():如果启用了跟踪录制,则为 True。
字节/字/双字/四字/指针
ReadByte(addr)、Byte(addr)、byte(addr):从addr读取一个字节并返回该值。示例:byte(eax)从内存位置[eax]读取一个字节。ReadWord(addr)、Word(addr)、word(addr):从addr读取一个字(2 字节)并返回该值。ReadDword(addr)、Dword(addr)、dword(addr):从addr读取一个双字(4 字节)并返回该值。ReadQword(addr)、Qword(addr)、qword(addr):从addr读取一个四字(8 字节)并返回该值(仅在 x64 上可用)。ReadPtr(addr)、ReadPointer(addr)、ptr(addr)、Pointer(addr)、pointer(addr):从addr读取一个指针(4/8 字节)并返回该值。
当 addr 无效时,这些表达式函数返回 0。
函数
func.start():返回addr所在函数的起始地址,否则为零。func.end():返回addr所在函数的结束地址,否则为零。
引用
ref.count():当前引用视图中的条目数量。ref.addr(index):获取索引index处的引用地址。失败时为零。
参数
这假设返回地址在栈上(例如你在函数内部)。
arg(index)、arg.get(index):获取索引index处的参数(从零开始)。arg.set(index, value):将索引index处的参数(从零开始)设置为value。
异常
这是一组用于获取上一个异常信息的函数。它们可用于异常断点以构造更高级的条件。
ex.firstchance():上一个异常是否为第一次机会异常。ex.addr():上一个异常的地址。例如,导致异常的指令地址。ex.code():上一个异常代码。ex.flags():上一个异常标志。ex.infocount():上一个异常信息计数(参数数量)。ex.info(index):上一个异常信息,如果索引越界则为零。对于访问违规或内存断点,ex.info(1)包含被访问内存的地址(详细信息请参阅 EXCEPTION_RECORD.ExceptionInformation)。
系统调用
syscall.name(number):以字符串形式返回number对应的系统调用名称。syscall.id(name):返回name对应的系统调用编号。
插件
插件可以注册自己的表达式函数。你可以在 StackContains 插件中找到示例。相关函数: