如何PE(可移植可执行)格式转换为ELF在Linux [英] How to convert PE(Portable Executable) format to ELF in linux
问题描述
什么是转换PE二进制文件的ELF可执行文件的最佳工具?
下面是此问题的一个简短的动机:
- 假设我有一个简单的C程序。
- 我用它GCC为Linux(这给ELF),并使用i586的-mingw32msvc-GCC的Windows(这给出了一个PE二进制)编译。
- 我要分析这两个二进制文件相似,使用Bitblaze的静态分析工具 - 藤( HTTP: //bitblaze.cs.berkeley.edu/vine.html )
- 现在,藤蔓不具备PE二进制文件的良好支持,所以我想转换PE-> ELF,然后用我的比较/分析矣。
由于所有的分析必须在Linux上运行,我想preFER一个实用工具/工具,在Linux上运行。
感谢
有可能重建一个EXE为ELF二进制文件,但由此产生的二进制文件将加载后很快出现段错误,由于缺少操作系统。
下面是做这件事的方法之一。
摘要
- 导出EXE文件的节标头。
- 从EXE中提取原始数据部分。
- 封装在GNU链接脚本片段的原始数据部分。
- 写链接脚本建立一个ELF二进制文件,其中包括从previous步这些脚本。
- 运行
LD
通过链接脚本生成的ELF文件。 - 运行的新方案,并观看段错误,因为它不是Windows上运行(和它试图调用函数中的导入地址表,它不存在)。
详细示例
-
转储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 -
使用
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字节)。 p> -
封装在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 -
写链接脚本建立一个ELF二进制文件,其中包括从previous步这些脚本。请注意,我还预留空间,为未初始化数据(.bss)在部分。
开始= 0x516DE8;
ENTRY(开始)
OUTPUT_FORMAT(ELF32-I386)
SECTIONS {
的.text 0x401000:
{
INCLUDEcode.ld
}
。数据0x576000:
{
INCLUDEdata.ld
}
.bss中0x5A2000:
{
。 =。 + 0x0E7800;
}
} -
运行与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)
静态链接的,不剥离 -
运行的新方案,并观看段错误,因为它不是在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:
- Suppose I have a simple C program.
- I compiled it using gcc for linux(this gives ELF), and using 'i586-mingw32msvc-gcc' for Windows(this gives a PE binary).
- I want to analyze these two binaries for similarities, using Bitblaze's static analysis tool - vine(http://bitblaze.cs.berkeley.edu/vine.html)
- 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
- Dump the section headers of the EXE file.
- Extract the raw section data from the EXE.
- Encapsulate the raw section data in GNU linker script snippets.
- Write a linker script to build an ELF binary, including those scripts from the previous step.
- Run
ld
with the linker script to produce the ELF file. - 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
Dump the section headers of the EXE file. I'm using
objdump
from themingw
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
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
andcount
, but I'm using a block size of 512 bytes indd
to speed up the process (example: 0x0400 = 1024 bytes = 2 blocks @ 512 bytes).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
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; } }
Run the linker script with GNU
ld
to produce the ELF file. Note I have to use an emulation modeelf_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
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屋!