反汇编操作数表示
正如我们之前提到的,IDA 中的 I 代表“交互式”,我们已经介绍了一些反汇编视图的交互功能,比如重命名或注释。但实际上,您还可以进行更多更改,例如您可以更改操作数表示(有时在文档中称为操作数类型)。那么,它到底是什么呢?
大多数汇编器(和反汇编器)使用一个助记符(表示指令的基本功能)和其所作用的操作数(通常用逗号分隔)来表示机器指令。举个例子,让我们看看最常见的 x86 指令 mov
,它在两个操作数之间复制数据。几个例子:
-
mov rsp, r11
– 将r11
的值复制到rsp
-
mov rcx, [rbx+8]
– 将rbx
加 8 地址中的 64 位值复制到rcx
(相当于 C 表示:rcx = *(int64*)(rbx+8);
) -
mov [rbp+390h+var_380], 2000000h
– 将值2000000h
(C 表示法中的 0x2000000) 复制到栈变量var_380
第一个例子使用了两个寄存器作为操作数,第二个例子是一个寄存器和一个带基址寄存器和位移的间接内存操作数,第三个例子则是一个内存操作数和一个立即数(一个直接在指令操作码中编码的常量值)。
最后两个例子很有趣,因为它们涉及到位移和立即数,这些数值可以以多种方式表示。例如,考虑以下指令:
mov eax, 64h
mov eax, 100
mov eax, 144o
mov eax, 1100100b
mov eax, 'd'
mov eax, offset byte_64
mov eax, mystruct.field_64
它们在二进制级别具有完全相同的字节序列(机器代码):B8 64 00 00 00
。因此,选择其他操作数表示方法可能会改变视觉效果,但底层值和程序行为不会改变。这允许您选择最能代表代码意图的最佳变体,而不必在注释中添加长篇解释。
IDA 中可用于数值操作数的表示方法如下(其中一些可能只在特定情况下有意义):
-
默认数值表示(即 void):当操作数上没有特定覆盖时使用(无论是用户还是 IDA 的自动分析器或处理器模块)。实际使用的表示取决于处理器模块,但最常见的回退是十六进制。在默认配色方案中使用橙色。对于当前编码中与可打印字符匹配的值,可能会显示带有字符的注释(取决于处理器模块)。
热键:#
(井号)。 -
十进制:将操作数显示为十进制数。热键 H
。 -
十六进制:明确将操作数显示为十六进制。热键 Q
。 -
二进制:将操作数显示为二进制数。热键 B
。 -
八进制:将操作数显示为八进制数。没有默认热键,但可以从上下文菜单或“操作数类型”工具栏中选择。 -
字符:如果可能,将操作数显示为字符常量。热键 R
。 -
结构偏移:用匹配偏移的结构成员引用替换数值操作数。热键 T
。 -
枚举(符号常数):用具有相同值的符号常数替换数值。热键 M
。 -
栈变量:将数值替换成当前函数的栈框架中的符号引用。通常仅在涉及栈指针或帧指针的指令中有意义。热键 K
。 -
浮点常数:仅在某些情况下和某些处理器上有效。例如, 3F000000h
(0x3F000000
) 实际上是 IEEE-754 的编码0.5
。没有默认热键,但转换可以通过工具栏或主菜单进行。 -
偏移操作数:用包含一个或多个程序地址的表达式替换数字。热键: O
、Ctrl
-O
或Ctrl
-R
(用于复杂偏移)。
所有热键如果应用两次则恢复为默认表示。
除了热键,最常见的转换可以通过上下文菜单完成:
完整列表可以在主菜单中找到(编辑 > 操作数类型):
以及“操作数类型”工具栏:
在改变数值基数的基础上,还可以对操作数应用两个转换:
-
取反。热键 _
(下划线)。例如,可以用于将-8
显示为0FFFFFFF8h
(同一二进制值的两种表示)。 -
按位取反(即反转或二进制 NOT)。热键 ~
(波浪号)。例如,0FFFFFFF8h
被认为与not 7
相同。
最后,如果您希望看到完全自定义的表示,而现有的转换不涵盖这种需求,您可以使用手工操作数。这允许您用任意文本替换操作数;它不会被 IDA 检查,因此确保新表示与原始值匹配的任务将由您自己完成。热键:Alt
-F1
。
交流群
添加小助手微信加入: OxCSorder
更多文章
立即关注【二进制磨剑】公众号
原文始发于微信公众号(二进制磨剑):IDA 技巧(46) 反汇编操作数表示
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论