windows - PE文件操作码

标签 windows parsing assembly x86 portable-executable

我正在编写一个 PE 文件解析器,我已经到了想要解析和解释 PE 文件中实际代码的地步,我假设这些代码存储为 x86 操作码。

例如,DLL 中的每个导出都指向函数将存储在内存中的 RVA(相对虚拟偏移),我编写了一个函数来将这些 RVA 转换为物理文件偏移。

问题是,这些真的是操作码,还是别的东西?

函数在文件中的存储方式是否取决于编译器/链接器,或者它们是一字节还是两字节的 X86 操作码。

例如,Windows 7 DLL“BWContextHandler.dll”包含四个加载到内存中的函数,使它们在系统内可用。第一个导出函数是“DllCanUnloadNow”,它位于文件中的偏移量 0x245D 处。此数据的前四个字节是:0xA1 0x5C 0xF1 0xF2

那么这些是一字节还是两字节的操作码,还是完全不同的东西?

如果有人可以提供有关如何检查这些的任何信息,我们将不胜感激。

谢谢!

进一步阅读并通过 IDA 演示版运行文件后,我认为第一个字节 0xA1 是一个单字节操作码的说法是正确的,意思是 mov eax。我从这里得到的:http://ref.x86asm.net/geek32.html#xA1我假设它暂时是正确的。

但是,我对后面的字节如何构成指令的其余部分感到有点困惑。从我所知道的 x86 汇编程序中,一条移动指令需要两个参数,目标和源,所以该指令是将(某物)移动到 eax 寄存器中,我假设该某物位于以下字节中。但是我还不知道如何阅读这些信息:)

最佳答案

x86 编码是复杂的多字节编码,您不能像在 RISC (MIPS/SPARC/DLX) 中那样简单地在指令表中找到一行来对其进行解码。一条指令甚至可以有 16 字节编码:1-3 字节操作码 + 几个前缀(包括 multibyte VEX )+ 几个用于编码立即数或内存地址、偏移量、缩放比例(imm、ModR/M 和 SIB;moffs)的字段.有时单个助记词有几十个操作码。而且,在某些情况下,同一 asm 行可能有两种编码方式(“inc eax”= 0x40 和 = 0xff 0xc0)。

one byte opcode, meaning mov eax. I got that from here: http://ref.x86asm.net/geek32.html#xA1 and I'm assuming it is correct for the time being.

让我们看一下表格:

po ; flds ; mnemonic ; op1 ; op2 ; grp1 ; grp2 ; Description

A1 ; W ; MOV ; eAX ; Ov ; gen ; datamov ; Move ;

(提示:不要使用 geek32 表,切换到 http://ref.x86asm.net/coder32.html#xA1 - 具有较少的字段和更多的解码,例如“A1 MOV eAX moffs16/32 Move”)

有列 op1 和 op2,http://ref.x86asm.net/#column_op用于操作数。 A1 操作码的第一个始终是 eAX,第二个 (op2) 是 Ov。根据表格http://ref.x86asm.net/#Instruction-Operand-Codes :

O / moffs Original The instruction has no ModR/M byte; the offset of the operand is coded as a word, double word or quad word (depending on address size attribute) in the instruction. No base register, index register, or scaling factor can be applied (only MOV (A0, A1, A2, A3)).

因此,在 A1 操作码之后,内存偏移量被编码。我认为 x86(32 位模式)有 32 位偏移量。

PS:如果您的任务是解析 PE 而不是发明反汇编程序,请使用一些 x86 反汇编库,例如 libdisasm 或 libudis86 或其他任何东西。

PPS:对于原始问题:

The question is, are these really opcodes, or are they something else?

是的,“A1 5C F1 F2 05 B9 5C F1 F2 05 FF 50 0C F7 D8 1B C0 F7 D8 C3 CC CC CC CC CC”是 x86 机器码。

关于windows - PE文件操作码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13763971/

相关文章:

parsing - 如何使用 ANTLR 正确解析泛型类型?

c++ - 方程解析库 C++

调用汇编例程的 C 代码 - ARM

c++ - 如何在内联汇编中实现这个?

windows - cmd.exe 不递增 for 循环中的数字

c++ - 改进我的代码

windows - VB6中多分辨率图标的使用

parsing - 在 PowerShell 语法中, `lvalueExpression` 规则说的是什么?

windows - 可以以低优先级运行 OpenCL 程序(是 "nice")?

linux - ASM printf : no output if string doesn't include\n newline