使用 GCC 和 objdump 将任何十六进制反汇编为汇编代码

逆向工程 拆卸 数据库 转储 海湾合作委员会
2021-06-27 08:21:47

为给定的十六进制代码生成汇编代码的最佳方法是什么(步骤也更少)?例如,如果我们知道架构是 x86,并且给定十六进制值 0x55,那么使用 gcc、gdb、obdjump 或任何其他 linux 命令行工具生成反汇编的最佳方法是什么?

3个回答

Linux的binutils的工具,如objdumpgdb等靠BFD库,这意味着他们采取结构良好的ELF文件,而不是任意字节值或十六进制的ASCII字符串作为输入。如果您想创建自己的libopcodes基于反汇编程序来执行此操作,以下文章将帮助您入门:使用 libopcodes 进行基本反汇编

GCC 是一个编译器工具链,它执行源文件的预处理,将源代码转换为汇编,将其转换为机器代码,然后通过链接编辑器执行重定位,生成 ELF 二进制文件。听起来您对另一种方式感兴趣,即反汇编对象(二进制)代码。因此 GCC 与此处无关。

如果您想反汇编单个字节,您可以使用Capstone 反汇编框架的 Python 绑定来编写反汇编您指定的字节值的脚本。下面是一个例子:

#!/usr/bin/python3

from capstone import *

CODE = b"\x55"

md = md = Cs(CS_ARCH_X86, CS_MODE_32)
for i in md.disasm(CODE, 0x1000):
    print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))

输出是 0x1000: push ebp

当我们查阅x86 操作码表时,我们看到 0x50 + 寄存器 = 的值Push Word, Doubleword or Quadword Onto the Stack因此,如果我们改变0x550x54输出变为0x1000: push esp-不同的寄存器推。0x50= push eax. 等等。

这是上述脚本的修改版本:

#!/usr/bin/python3

from capstone import *

CODE = b"\x50\x51\x52\x53\x54\x55\x56\x57"

md = md = Cs(CS_ARCH_X86, CS_MODE_32)
for i in md.disasm(CODE, 0x1000):
    print("0x%x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))

这打印

0x1000: push    eax
0x1001: push    ecx
0x1002: push    edx
0x1003: push    ebx
0x1004: push    esp
0x1005: push    ebp
0x1006: push    esi
0x1007: push    edi

您可以使用 objdump 执行此操作:

echo 0000: b0 55 15 de ad f1 55 | xxd -r > x.bin
objdump -D -m i386  -b binary x.bin

这是一个很晚的答案,因为此查询弹出到活动队列中
此答案也部分归因于我对他的查询发表评论后的评论 BY OP

如果可以转义十六进制,则可以编译数据数组
并仅使用 objdump 转储目标文件的反汇编

使用 mingw(在下面的 .rdata 部分查找boss 的反汇编是死胡同

$ ls
gccdis.cpp

$ cat gccdis.cpp
const char *input = "\xb0\x55\x15\xde\xad\xf1\x55";
int main () {
   return 0;
}

$ gcc -g -c gccdis.cpp

$ ls
gccdis.cpp  gccdis.o

$ objdump --disassemble-all --section=.rdata -M intel gccdis.o

gccdis.o:     file format pe-i386    
Disassembly of section .rdata:

00000000 <.rdata>:
   0:   b0 55                   mov    al,0x55
   2:   15 de ad f1 55          adc    eax,0x55f1adde
        ...