将PE二进制文件转换为ELF二进制文件的最佳工具是什么?

以下是此问题的简要动机:

  • 假设我有一个简单的C程序。
  • 我为Linux使用gcc编译了它(给出了ELF),对于Windows使用了'i586-mingw32msvc-gcc'给出了(给了PE二进制文件)。
  • 我想使用Bitblaze的静态分析工具-vine(http://bitblaze.cs.berkeley.edu/vine.html)
  • 对这两个二进制文件进行相似性分析
  • 现在vine对PE二进制文件没有很好的支持,因此我想转换PE-> ELF,然后继续进行比较/分析。

  • 由于所有分析都必须在Linux上运行,因此我更喜欢在Linux上运行的实用程序/工具。

    谢谢

    最佳答案

    可以将EXE重建为ELF二进制文件,但是由于缺少操作系统,因此生成的二进制文件将在加载后很快出现段错误。

    这是执行此操作的一种方法。

    概括

  • 转储EXE文件的节头。
  • 从EXE提取原始节数据。
  • 将原始节数据封装在GNU链接器脚本片段中。
  • 编写一个链接器脚本以构建ELF二进制文件,包括上一步中的那些脚本。
  • 使用链接程序脚本运行ld以生成ELF文件。
  • 运行新程序,并观察它的段错误,因为它不在Windows上运行(并且它尝试调用“导入地址表”中的函数,该函数不存在)。

  • 详细的例子
  • 转储EXE文件的节头。我正在使用objdump交叉编译器包中的mingw来执行此操作。

    $ i686-pc-mingw32-objdump -h trek.exe

    trek.exe:文件格式为pei-i386

    栏目:
    Idx名称大小VMA LMA文件关闭Algn
    0 auto 00172600 00401000 00401000 00000400 2 ** 2
    目录,ALLOC,加载,只读,代码
    1 .idata 00001400 00574000 00574000 00172a00 2 ** 2
    目录,ALLOC,加载,数据
    2 DGROUP 0002b600 00576000 00576000 00173e00 2 ** 2
    目录,ALLOC,加载,数据
    3 .bss 000e7800 005a2000 005a2000 00000000 2 ** 2
    ALLOC
    4 .reloc 00013000 0068a000 0068a000 0019f400 2 ** 2
    目录,ALLOC,加载,只读,数据
    5 .rsrc 00000a00 0069d000 0069d000 001b2400 2 ** 2
    目录,ALLOC,加载,只读,数据
  • 使用dd(或十六进制编辑器)从EXE提取原始节数据。在这里,我将复制代码和数据部分(在此示例中分别命名为AUTO和DGROUP)。不过,您可能要复制其他部分。

    $ dd bs = 512 skip = 2 count = 2963 if = trek.exe of = code.bin
    $ dd bs = 512 skip = 2975 count = 347 if = trek.exe of = data.bin

    请注意,我已将文件偏移量和节大小从十六进制转换为十进制以用作skipcount,但是我在dd中使用512字节的块大小来加快该过程(例如:0x0400 = 1024字节= 2块@ 512字节)。
  • 将原始节数据封装在GNU ld链接器脚本片段中(使用BYTE指令)。这将用于填充各节。

    cat code.bin | hexdump -v -e'“BYTE(0x” 1/1“%02X”“)\n”'> code.ld
    cat data.bin | hexdump -v -e'“BYTE(0x” 1/1“%02X”“)\n”'> data.ld
  • 编写一个链接器脚本以构建ELF二进制文件,包括上一步中的那些脚本。注意我还为未初始化的数据(.bss)部分留出了空间。

    开始= 0x516DE8;
    ENTRY(开始)
    OUTPUT_FORMAT(“elf32-i386”)
    部分{
    .text 0x401000:
    {
    包含“code.ld”;
    }
    .data 0x576000:
    {
    包含“data.ld”;
    }
    .bss 0x5A2000:
    {
    。 =。 + 0x0E7800;
    }
    }
  • 使用GNU ld运行链接器脚本以生成ELF文件。注意由于我使用的是64位Linux,因此必须使用仿真模式elf_i386,否则将生成64位的ELF。

    $ ld -o elf_trek -m elf_i386 elf_trek.ld
    ld:警告:elf_trek.ld包含输出节;你忘了-T吗?
    $文件elf_trek
    elf_trek:ELF 32位LSB可执行文件,Intel 80386版本1(SYSV),
    静态链接,不剥离
  • 运行新程序,并在没有在Windows上运行的情况下观看它的段错误。

    $ gdb elf_trek
    (gdb)运行
    启动程序:/home/quasar/src/games/botf/elf_trek

    程序收到信号SIGSEGV,分段故障。
    0x0051d8e6 in ?? ()
    (gdb)bt
    \#0 0x0051d8e6 in ?? ()
    \#1 0x00000000 in ?? ()
    (gdb)x/i $ eip
    => 0x51d8e6:子(%edx),%eax
    (gdb)退出

    该位置的IDA Pro输出:

    0051D8DB; size_t stackavail(void)
    0051D8DB proc堆栈在附近可用
    0051D8DB推EDX
    0051D8DC调用[ds:off_5A0588]
    0051D8E2 mov edx,eax
    0051D8E4 mov eax,esp
    0051D8E6 sub eax,[edx]
    0051D8E8 pop edx
    0051D8E9 retn
    0051D8E9 endp堆栈可用

  • 考虑到Wine项目,将二进制文件移植到Linux上是毫无意义的。
    对于诸如OP之类的情况,这可能是适当的。

    09-11 19:30
    查看更多