我认为这是一个容易(也许是愚蠢容易)的问题,但经过近两个小时的谷歌搜索,我已经被淘汰了。我很确定我的问题是因为我不了解语法的作用。
我正在查看IDA中的一些反汇编代码,我不知道以下内容是做什么的:
mov dl, byte_404580[eax]
如果我跳转到byte_404580
,我会发现.data:00404580 byte_404580 db 69h
告诉我该值为0x69
。但我不知道如何使用它。
让我提供此代码出现的上下文:
mov eax, 0x73 ; Move hex 73 to EAX
and eax, 0x0F ; Keep lower half of EAX
mov dl, byte_404580[eax] ; MAGIC
根据上述EAX
最初为0x73的假设,我得到DL
= 0x76。我试过改变EAX
的值来找到一些模式,但我还没有弄清楚发生了什么。
答案 0 :(得分:4)
此语法用于表示内存寻址,类似于C的数组语法(array[index]
)。您的示例等同于计算表达式0x404580 + (eax & 0x0F)
,将其视为地址,并从该地址获取一个字节。这表明0x404580
处的数据是一个字节数组(最可能是基于掩码的0x10
元素)。
如果能回答你的问题,你可以在这里停止阅读。
如果你进入选项>常规并将“显示操作码字节”设置为非零值,您将看到指令字节的实际值,并能够与处理器文档交叉引用它们以了解发生了什么。这通常不是必需的,但它可以是教育性的。例如:
mov dl, byte_404580[eax]
可以表示为字节序列:
8A 14 05 80 45 40 00
使用Intel's Architecture Manual, Volume 2A,可以按如下方式解码:
8A - instruction opcode for MOV r8, r/m8 - determines the operand sizes
14 - the Mod R/M byte:
| 00010100b
Mod | 00
R/M | 100
Reg | 010
Mod R/M combination 00-100 is specified as "followed by the SIB byte".
Reg 010 stands for register DL/DX/EDX, the destination operand.
05 - the SIB byte:
| 00000101b
Scale | 00
Index | 000
Base | 101
This combination is specified as [scaled value of EAX] + a 32 bit displacement.
80 45 40 00 - the displacement itself, 0x404580
将这些加在一起,你得到:
该指令从EAX + 0x404580
获取一个字节并将其移入DL
寄存器。
IDA使用此信息来推断0x404580
处有一个字节大小的值数组,如果它还没有名称则尝试命名该位置,尝试调整该位置的命名项的大小跨越正确的字节数(它不一定知道这个数组中有多少个元素,所以它实际上并没有在那里创建一个数组)并将显示的表达式转换为byte_404580[eax]
。