值
很多命令都接受表达式和值作为参数。下面是所有支持的数值格式的列表。你可以通过在命令栏中输入这些信息,或使用计算器来播放这些信息 (帮助 -> 计算器
菜单)。
数字
按默认情况,所有数字都解释为十六进制!如果要确认,你可以用 x
或0x
作为前缀。前面带有一个点的数字,可以用作为十进制数字:.123=7B
。
变量
变量可以选择以 $
开头,并且只能存储一个 DWORD (在 x64 上为 QWORD)。这意味着 myvar
和 $myvar
是等同的。更多信息见变量部分。
寄存器
除浮点寄存器 (如: RAX, EAX, AL) 外,所有大小的寄存器都可以用作变量。
像 XMM0、YMM0 或 ST(0) 这样的浮点寄存器不能作为变量使用,但它们可以通过字符串格式的浮点类型进行记录。目前不支持 AVX-512 寄存器。
备注
- 大多数寄存器的变量名称与它们的名称相同,除了下列寄存器:
- x87 控制字标志:该寄存器的标志被这样命名:
_x87CW_UM
- 除了架构中的寄存器外,x64dbg 还提供了以下寄存器:
CAX
,CBX
,CCX
,CDX
,CSP
,CBP
,CSI
,CDI
,CIP
。这些寄存器在 32-位平台上被映射到 32-位寄存器,而在 64-位平台上被映射到 64-位寄存器。例如,CIP
是EIP
在 32-位平台,而RIP
是在 64-位平台。该功能是为了支持独立于架构的代码。
标志
调试标志 (解释为整数) 可以作为输入。标志的前缀是_
,后面是标志名称。有效的标志是:_cf
, _pf
, _af
, _zf
, _sf
, _tf
, _if
, _df
, _of
, _rf
, _vm
, _ac
, _vif
, _vip
和 _id
。
存储单元
你可以通过使用以下表达式之一从/向一个存储单元读/写。
[addr]
读取 DWORD/QWORD 从addr
。n:[addr]
读取 n 个字节从addr
。seg:[addr]
读取 DWORD/QWORD 从段中的addr
。byte:[addr]
读取 BYTE 从addr
。word:[addr]
读取 WORD 从addr
。dword:[addr]
读取 DWORD 从addr
。qword:[addr]
读取 QWORD 从addr
(仅 x64).n
是要读取的字节数,在 X32 上应小于 4,在 X64 上应小于 8,否则会出现错误。seg
可以是gs
,es
,cs
,fs
,ds
,ss
。仅fs
和gs
有效果。
解除对无效地址的引用会导致错误,这对条件断点或编写脚本时可能是个问题。你可以使用 ReadByte(addr)
系列表达式函数来代替错误时返回 0。
标签/符号
用户定义的标签和符号是一个有效的表达式 (它们解析到所述标签/符号的地址)。
模块数据
DLL 导出
键入 GetProcAddress
,它将自动解析为函数的实际地址。要明确定义从哪个模块加载 API,请使用:module.dll:api
或 module:api
。以类似的方式,你可以解析序数,请尝试 module:ordinal
。另一个宏允许你获取模块的加载基础。当 module
为空字符串(例如 :myexport
)时,将使用当前在 CPU 中选择的模块。使用 .
而不是 :
是等效的。
ntdll.dll:ZwContinue ntdll:memcmp ntdll.memcmp // same as above ntdll:1D // Ordinal 0x1D :myexport // Export 'myexport' in the current module
转发的导出被解析到其最终地址。为了防止这种情况,你可以使用 ?
代替 :
。
kernel32:EnterCriticalSection // resolves to ntdll:RtlEnterCriticalSection
kernel32?EnterCriticalSection // resolves to the export in kernel32
加载的模块基数
如果要访问加载的模块库,你可以写入:module
、module:0
、module:base
、module:imagebase
或 module:header
。
RVA/文件偏移量
如果要访问模块 RVA,可以写入 module + rva
,也可以写入 module:$rva
。如果要将文件偏移量转换为 VA,可以使用 module:#offset
。当 module
为空字符串 (例如 :$123
) 时,将使用当前在 CPU 中选择的模块。
// File offset 0x400
ntdll.dll:#400
:#400
// RVA 0x1000
ntdll.dll:$1000 // RVA 0x1000
:$1000
模块入口点
要访问一个模块的入口点,你可以写入 module:entry
、module:oep
或 module:ep
。请注意,当有名为 entry
、oep
或 ep
的出口时,这些出口的地址将被返回。