linux下如何将PE(可移植可执行文件)格式转换为ELF

linux下如何将PE(可移植可执行文件)格式转换为ELF,linux,binary,elf,portable-executable,Linux,Binary,Elf,Portable Executable,将PE二进制文件转换为ELF二进制文件的最佳工具是什么 以下是这个问题的简要动机: 假设我有一个简单的C程序 我使用用于linux的gcc(这给出了ELF)和用于Windows的“i586-mingw32msvc-gcc”(这给出了一个PE二进制文件)编译了它 我想使用Bitblaze的静态分析工具-vine()分析这两个二进制文件的相似性 现在vine对PE二进制文件没有很好的支持,所以我想转换PE->ELF,然后继续我的比较/分析 由于所有分析都必须在Linux上运行,因此我更喜欢在Linu

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

以下是这个问题的简要动机:

  • 假设我有一个简单的C程序
  • 我使用用于linux的gcc(这给出了ELF)和用于Windows的“i586-mingw32msvc-gcc”(这给出了一个PE二进制文件)编译了它
  • 我想使用Bitblaze的静态分析工具-vine()分析这两个二进制文件的相似性
  • 现在vine对PE二进制文件没有很好的支持,所以我想转换PE->ELF,然后继续我的比较/分析
  • 由于所有分析都必须在Linux上运行,因此我更喜欢在Linux上运行的实用程序/工具


    谢谢

    我不知道这是否完全符合您的需要,但它是您与您的MinGW版本的gcc交叉编译的一个选项吗


    我的意思是说:让i586-mingw32msvc-gcc直接编译成ELF格式的二进制文件(而不是您当前得到的PEs)是否适合您的需要。可以找到关于如何在另一个方向上做事情的描述-我想这会有点黑客,但完全有可能在另一个方向上为您工作(我必须承认我没有尝试过)。

    可以将EXE重建为ELF二进制文件,但加载后生成的二进制文件将很快发生故障,由于缺少操作系统

    这里有一种方法

    总结
  • 转储EXE文件的节头
  • 从EXE中提取原始节数据
  • 将原始节数据封装在GNU链接器脚本片段中
  • 编写链接器脚本以构建ELF二进制文件,包括上一步中的脚本
  • 使用链接器脚本运行
    ld
    ,生成ELF文件
  • 运行新程序,观察它是否在Windows上运行(它尝试调用导入地址表中不存在的函数)
  • 详细示例
  • 转储EXE文件的节头。我正在使用
    mingw
    交叉编译器包中的
    objdump
    来实现这一点

    $ 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 注意,我已经将文件偏移量和节大小从十六进制转换为十进制,以用作
    skip
    count
    ,但我在
    dd
    中使用512字节的块大小来加快进程(例如:0x0400=1024字节=2个块@512字节)

  • 将原始节数据封装在GNU ld链接器脚本片段中(使用字节指令)。这将用于填充各部分

    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
  • 运行新程序,观察它是否在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 $gdb elf_trek (gdb)运行 启动程序:/home/quasar/src/games/botf/elf_trek 程序接收信号SIGSEGV,分段故障。 0x0051d8e6英寸??() (gdb)英国电信 \#0 0x0051d8e6英寸??() \#1 0x00000000英寸??() (gdb)x/i$eip =>0x51d8e6:sub(%edx),%eax (gdb)退出 该位置的IDA Pro输出:

    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 0051D8DB;尺寸(空) 0051D8DB proc stackavail近端 0051D8DB推送edx 0051D8DC呼叫[ds:off_5A0588] 0051D8E2 mov edx,eax 0051D8E4 mov eax,esp 0051D8E6子eax,[edx] 0051D8E8 pop edx 0051D8E9翻新 0051D8E9 endp stackavail
  • 考虑到Wine项目,将二进制文件移植到Linux是毫无意义的。
    对于OP这样的情况,这可能是合适的。

    我找到了一种更简单的方法。使用strip命令

    范例

    strip -O elf32-i386 -o myprogram.elf myprogram.exe
    
    -O elf32-i386
    让它以该格式写出文件

    要查看支持的格式是否运行

    strip --info
    

    我使用的是来自的strip命令,在我的系统上,它实际上被命名为
    /opt/mxe/usr/bin/i686-w64-mingw32。静态strip

    嗨,Aman!是否要在Linux上运行Windows二进制文件?将可执行文件从PE转换为ELF不是一个解决方案@我想比较一下两者,我已经更新了描述,这样人们就可以提供答案了。@Aman:我明白了。你的问题现在清楚多了。我认为我对这个话题不太熟悉,无法回答你的问题,但我可以尽我所能给你一些建议。我访问了你发布的链接,没有提到任何关于PE或ELF的内容,所以它可能也适用于PE。只要使用MinGW或Cygwin编译它就可以了。你知道二进制文件的“代码段”是什么吗?我想如果你能把它提取出来并保存到一个文件中,Vine也许能分析这个“裸二进制文件”。以下是一些可能有用的关键词:binutils、objdump、objcopy、nm、readelf、ld、lld、ar、as。如果您觉得有用,请不要忘记+1我的评论:-)。@SiuChingPong:当我运行vine的分析时,有一条警告消息说该工具还没有准备好使用PE二进制文件。 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
    strip -O elf32-i386 -o myprogram.elf myprogram.exe
    
    strip --info