表达式函数
你可以在表达式中使用函数。下列函数通过调试器定义:
字符串
ansi(addr): 从addr读取 ANSI 字符串,并返回字符串值。utf8(addr): 从addr读取 UTF-8 字符串,并返回字符串值。utf16(addr): 从addr读取 UTF-16 字符串,并返回字符串值。strstr(str1, str2): 查找子字符串。示例:strstr(utf8(addr), "abc")。streq(str1, str2): 比较两个字符串。示例:streq(utf8(addr), "abc")。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的 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。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):如果该值为 true,则addr是有效的内存地址。mem.base(addr): 返回addr(可更改取决于内存映射模式)内存页的基地址。mem.size(addr):返回addr(可更改取决于内存映射模式)内存页的大小。mem.iscode(addr):如果该值为 true,则addr是可执行的页。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 。
字节/字(Word)/双字(Dword)/四字(Qword)/指针(Ptr)
ReadByte(addr),Byte(addr),byte(addr): 读取字节从addr并返回值。例如:byte(eax)读取字节从内存单元[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,并返回该值。
当 addr 无效时,这些表达式函数返回 0。
函数
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): 最后一个异常信息,如果索引越界,则为零。对于访问冲突或内存断点ex.info(1)包含被访问内存的地址 (详细信息参见 EXCEPTION_RECORD.ExceptionInformation)。
插件
插件可以注册自己的表达式函数。您可以在 StackContains 插件中找到一个示例。相关函数:
_plugin_registerexprfunction_plugin_registerexprfunctionex_plugin_unregisterexprfunction