如何PE(可移植可执行)格式转换为ELF在Linux [英] How to convert PE(Portable Executable) format to ELF in linux

查看:2289
本文介绍了如何PE(可移植可执行)格式转换为ELF在Linux的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是转换PE二进制文件的ELF可执行文件的最佳工具?

下面是此问题的一个简短的动机:


  1. 假设我有一个简单的C程序。

  2. 我用它GCC为Linux(这给ELF),并使用i586的-mingw32msvc-GCC的Windows(这给出了一个PE二进制)编译。

  3. 我要分析这两个二进制文件相似,使用Bitblaze的静态分析工具 - 藤( HTTP: //bitblaze.cs.berkeley.edu/vine.html

  4. 现在,藤蔓不具备PE二进制文件的良好支持,所以我想转换PE-> ELF,然后用我的比较/分析矣。

由于所有的分析必须在Linux上运行,我想preFER一个实用工具/工具,在Linux上运行。

感谢


解决方案

有可能重建一个EXE为ELF二进制文件,但由此产生的二进制文件将加载后很快出现段错误,由于缺少操作系统。

下面是做这件事的方法之一。

摘要


  1. 导出EXE文件的节标头。

  2. 从EXE中提取原始数据部分。

  3. 封装在GNU链接脚本片段的原始数据部分。

  4. 写链接脚本建立一个ELF二进制文件,其中包括从previous步这些脚本。

  5. 运行 LD 通过链接脚本生成的ELF文件。

  6. 运行的新方案,并观看段错误,因为它不是Windows上运行(和它试图调用函数中的导入地址表,它不存在)。

详细示例


  1. 转储EXE文件的节标头。我使用 objdump的的MinGW 交叉编译包来做到这一点。


    $的i686-PC-的mingw32-objdump的-h trek.exetrek.exe:文件格式PEI-I386部分:
    IDX名称大小VMA LMA文件ALGN关闭
      0 AUTO 00172600 00401000 00401000 00000400 2 2 **
                      内容ALLOC,LOAD,只读,code
      1的.idata 00001400 00574000 00574000 00172a00 2 ** 2
                      内容ALLOC,LOAD,DATA
      2 DGROUP 0002b600 00576000 00576000 00173e00 2 ** 2
                      内容ALLOC,LOAD,DATA
      3 .bss中000e7800 005a2000 005a2000 00000000 2 ** 2
                      ALLOC
      4 .reloc节00013000 0068a000 0068a000 0019f400 2 ** 2
                      内容ALLOC,LOAD,只读,DATA
      5 .rsrc 00000a00 0069d000 0069d000 001b2400 2 ** 2
                      内容ALLOC,LOAD,只读,DATA


  2. 使用 DD (或十六进制编辑器),以从EXE中提取原始数据部分。在这里,我只是去复制code和数据段(名为AUTO和DGROUP在这个例子中)。您可能想复制但更多的部分。


    $ DD BS = 512跳过= 2计数= 2963如果= trek.exe = code.bin
    $ DD BS = 512 =跳跃计数2975 = 347 IF =的trek.exe = data.bin

    请注意,我已经转换从十六进制文件偏移和截面尺寸,以十进制为使用跳过计数,但我使用512字节的块大小 DD 来加快这一进程(例如:=的0x0400 1024字节= 2个街区@ 512字节)


  3. 封装在GNU LD链接脚本片段的原始数据部分(使用BYTE指令)。这将被用于填充部分


    猫code.bin | hexdump都-v -e'BYTE(0X1/1%02X)\\ N'> code.ld
    猫data.bin | hexdump都-v -e'BYTE(0X1/1%02X)\\ N'> data.ld


  4. 写链接脚本建立一个ELF二进制文件,其中包括从previous步这些脚本。请注意,我还预留空间,为未初始化数据(.bss)在部分。


    开始= 0x516DE8;
    ENTRY(开始)
    OUTPUT_FORMAT(ELF32-I386)
    SECTIONS {
        的.text 0x401000:
        {
            INCLUDEcode.ld
        }
        。数据0x576000:
        {
            INCLUDEdata.ld
        }
        .bss中0x5A2000:
        {
            。 =。 + 0x0E7800;
        }
    }


  5. 运行与GNU LD 链接脚本生成的ELF文件。注意我必须使用仿真模式 elf_i386 ,因为我使用的是64位的Linux,否则64位ELF会产生。


    $ LD -o elf_trek -m elf_i386 elf_trek.ld
    LD:警告:elf_trek.ld包含输出部分;你忘了-T?
    $文件elf_trek
    elf_trek:ELF 32位LSB的可执行文件,英特尔80386,版本1(SYSV)
              静态链接的,不剥离


  6. 运行的新方案,并观看段错误,因为它不是在Windows上运行。


    $ GDB elf_trek
    (GDB)运行
    启动程序:/家庭/类星体/ src目录/游戏/ botf / elf_trek计划接收信号SIGSEGV,分割过错。
    0x0051d8e6在?? ()
    (GDB)BT
    \\#0 0x0051d8e6的? ()
    \\#1 00000000的? ()
    (GDB)X / I $ EIP
    => 0x51d8e6:分(%EDX),EAX%
    (GDB)退出

    该位置IDA Pro的输出:


    0051D8DB;为size_t stackavail(无效)
    0051D8DB PROC stackavail附近
    0051D8DB推EDX
    0051D8DC调用[DS:off_5A0588]
    0051D8E2 MOV EDX,EAX
    0051D8E4 MOV EAX,ESP
    0051D8E6子EAX,[EDX]
    0051D8E8流行EDX
    0051D8E9 RETN
    0051D8E9 ENDP stackavail


有关二进制代码移植到Linux,这是一种毫无意义的,因为葡萄酒项目。
对于像OP的情况下,可能是适当的。

What's the best tool for converting PE binaries to ELF binaries?

Following is a brief motivation for this question:

  1. Suppose I have a simple C program.
  2. I compiled it using gcc for linux(this gives ELF), and using 'i586-mingw32msvc-gcc' for Windows(this gives a PE binary).
  3. I want to analyze these two binaries for similarities, using Bitblaze's static analysis tool - vine(http://bitblaze.cs.berkeley.edu/vine.html)
  4. Now vine doesn't have a good support for PE binaries, so I wanted to convert PE->ELF, and then carry on with my comparison/analysis.

Since all the analysis has to run on Linux, I would prefer a utility/tool that runs on Linux.

Thanks

解决方案

It is possible to rebuild an EXE as an ELF binary, but the resulting binary will segfault very soon after loading, due to the missing operating system.

Here's one method of doing it.

Summary

  1. Dump the section headers of the EXE file.
  2. Extract the raw section data from the EXE.
  3. Encapsulate the raw section data in GNU linker script snippets.
  4. Write a linker script to build an ELF binary, including those scripts from the previous step.
  5. Run ld with the linker script to produce the ELF file.
  6. Run the new program, and watch it segfault as it's not running on Windows (and it tries to call functions in the Import Address Table, which doesn't exist).

Detailed Example

  1. Dump the section headers of the EXE file. I'm using objdump from the mingw cross compiler package to do this.

    $ i686-pc-mingw32-objdump -h trek.exe
    
    trek.exe:         file format pei-i386
    
    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn
      0 AUTO          00172600  00401000  00401000  00000400  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .idata        00001400  00574000  00574000  00172a00  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      2 DGROUP        0002b600  00576000  00576000  00173e00  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      3 .bss          000e7800  005a2000  005a2000  00000000  2**2
                      ALLOC
      4 .reloc        00013000  0068a000  0068a000  0019f400  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      5 .rsrc         00000a00  0069d000  0069d000  001b2400  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
    

  2. Use dd (or a hex editor) to extract the raw section data from the EXE. Here, I'm just going to copy the code and data sections (named AUTO and DGROUP in this example). You may want to copy additional sections though.

    $ 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
    

    Note, I've converted the file offsets and section sizes from hex to decimal to use as skip and count, but I'm using a block size of 512 bytes in dd to speed up the process (example: 0x0400 = 1024 bytes = 2 blocks @ 512 bytes).

  3. Encapsulate the raw section data in GNU ld linker scripts snippets (using the BYTE directive). This will be used to populate the sections.

    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
    

  4. Write a linker script to build an ELF binary, including those scripts from the previous step. Note I've also set aside space for the uninitialized data (.bss) section.

    start = 0x516DE8;
    ENTRY(start)
    OUTPUT_FORMAT("elf32-i386")
    SECTIONS {
        .text 0x401000 :
        {
            INCLUDE "code.ld";
        }
        .data 0x576000 :
        {
            INCLUDE "data.ld";
        }
        .bss 0x5A2000 :
        {
            . = . + 0x0E7800;
        }
    }
    

  5. Run the linker script with GNU ld to produce the ELF file. Note I have to use an emulation mode elf_i386 since I'm using 64-bit Linux, otherwise a 64-bit ELF would be produced.

    $ ld -o elf_trek -m elf_i386 elf_trek.ld
    ld: warning: elf_trek.ld contains output sections; did you forget -T?
    $ file elf_trek
    elf_trek: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), 
              statically linked, not stripped
    

  6. Run the new program, and watch it segfault as it's not running on Windows.

    $ gdb elf_trek
    (gdb) run
    Starting program: /home/quasar/src/games/botf/elf_trek 
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0051d8e6 in ?? ()
    (gdb) bt
    \#0  0x0051d8e6 in ?? ()
    \#1  0x00000000 in ?? ()
    (gdb) x/i $eip
    => 0x51d8e6:    sub    (%edx),%eax
    (gdb) quit
    

    IDA Pro output for that location:

    0051D8DB ; size_t stackavail(void)
    0051D8DB proc    stackavail near
    0051D8DB         push    edx
    0051D8DC         call    [ds:off_5A0588]
    0051D8E2         mov     edx, eax
    0051D8E4         mov     eax, esp
    0051D8E6         sub     eax, [edx]
    0051D8E8         pop     edx
    0051D8E9         retn
    0051D8E9 endp    stackavail
    

For porting binaries to Linux, this is kind of pointless, given the Wine project. For situations like the OP's, it may be appropriate.

这篇关于如何PE(可移植可执行)格式转换为ELF在Linux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆