我可以将所有的章节" objdump的-s -d ELF文件"生成到一个重新组装能力的文件? [英] Can I combine all the sections "Objdump -S -d elf-file" generate into a re-assemble capable file?
问题描述
ELF文件的静态链接
THe elf file is static linked
和目前objdump的输出是一样的东西:
and currently the objdump's output is something like:
Disassembly of section: .init:
xxxxxx
Disassembly of section: .plt:
xxxxxx
Disassembly of section: .text:
xxxxxx
基本上是我想要实现的是
basically what I want to achieve is
ELF文件 - (由objdump的反汇编) - >文件汇编 - (重新编译) - > 相同的功能
"elf-file -(disassemble by objdump)-> assemble file --(re-compile)--> same functionality"
我不需要重新编译的二进制文件的二进制内容和原来一样的,唯一的相同的功能就足够了。
I don't need the re-compiled binary has the binary content same as the original one, only same functionality is enough.
快速搜索后,基本上答案是否,然后他们认为拆机文件丢失了一些东西,例如符号信息或其他人,但我认为静态链接,我可以摆脱这个问题...
After a quick search, basically the answer is no, and they argued that disassemble file lost some stuff like symbolic information or others, but I think by static link, I can get rid of this issue...
感谢您!
推荐答案
objdump的-S -d ELF文件
通常没有足够的,因为它缺少。数据
部分。
objdump -S -d elf-file
is not usually sufficient, as it lacks .data
section.
但似乎 objdump的-s -d ELF文件
就足够了。
要试试这个,我写了一个使用的extern的printf
,与组装YASM毫不调试符号,并与海湾合作委员会的联系。一个小的x86-64汇编文件
To try this, I wrote a small x86-64 assembly file that uses extern printf
, assembled it with YASM without debug symbols and linked with GCC.
[bits 64]
; yasm -f elf64 -m amd64 1st_generation.asm -o 1st_generation.o; gcc -o 1st_generation 1st_generation.o
section .text
global main
extern printf
main:
push rbp
mov rbp,rsp
lea rdi,[msg]
mov rsi,[num]
xor eax,eax
call printf
mov eax,60
xor ebx,ebx
syscall
section .data
msg db 'abcdef = %d', 0xa, 0
num dd 1337
testmsg1:
db "test 01", 0x0a, 0
然后我用 objdump的-s -d -M英特尔ELF文件&GT拆开它,objdump_output.txt
。 -M英特尔
生产以Intel格式的拆卸。 AT&安培; T公司将工作太,但我preFER Intel格式的清晰
Then I disassembled it with objdump -S -D -M intel elf-file >objdump_output.txt
. -M intel
produces the disassembly in Intel format. AT&T would work too, but I prefer Intel format for its clarity.
然后我写了 objdump_to_asm
小 GAWK
程序由 objdump的生产拆装转换-s -d -M英特尔精灵文件> objdump_output.txt
成YASM一个合适的格式。假设X86-64 code和主
为切入点。可以很容易地编辑以各种不同的环境(X86是平凡的,其他人可能需要更多的工作)。用法 ./ objdump_to_asm objdump_output.txt
。有趣的是第一代的可执行文件有6598字节大小,而第二代的可执行文件有一个只有6496个字节大小。第三代组装code与第二代组装code完全相同。
Then I wrote a small gawk
program objdump_to_asm
to convert the disassembly produced by objdump -S -D -M intel elf-file >objdump_output.txt
into a suitable format for YASM. Assumes x86-64 code and main
as entry point. Can be easily edited to different kinds of environment (x86 is trivial, others may need more work). Usage ./objdump_to_asm objdump_output.txt
. Interestingly 1st generation executable has size of 6598 bytes, whereas 2nd generation executable has size of only 6496 bytes. 3rd generation assembly code is identical with the 2nd generation assembly code.
这里的code:
#!/usr/bin/awk -f
BEGIN{
disassembly_of_section_string = "Disassembly of section ";
sections_to_discard[1] = ".interp";
sections_to_discard[2] = ".note.ABI-tag";
sections_to_discard[3] = ".note.gnu.build-id";
sections_to_discard[4] = ".dynsym";
sections_to_discard[5] = ".dynstr";
sections_to_discard[6] = ".hash";
sections_to_discard[7] = ".gnu.hash";
sections_to_discard[8] = ".gnu.version";
sections_to_discard[9] = ".gnu.version_r";
sections_to_discard[10] = ".rela.dyn";
sections_to_discard[11] = ".rela.init";
sections_to_discard[12] = ".eh_frame";
sections_to_discard[13] = ".dynamic";
sections_to_discard[14] = ".got";
sections_to_discard[15] = ".got.plt";
sections_to_discard[16] = ".jcr";
sections_to_discard[17] = ".init_array";
sections_to_discard[18] = ".comment";
sections_to_discard[19] = ".note.gnu.gold-version";
number_of_sections_to_discard = length(sections_to_discard);
sections_to_handle[1] = ".plt";
sections_to_handle[2] = ".text";
sections_to_handle[3] = ".data";
sections_to_handle[4] = ".bss";
number_of_sections_to_handle = length(sections_to_handle);
blocks_to_discard_in_text[1] = "<call_gmon_start>:";
blocks_to_discard_in_text[2] = "<deregister_tm_clones>:";
blocks_to_discard_in_text[3] = "<register_tm_clones>:";
blocks_to_discard_in_text[4] = "<__do_global_dtors_aux>:";
blocks_to_discard_in_text[5] = "<frame_dummy>:"
blocks_to_discard_in_text[6] = "<__libc_csu_fini>:"
blocks_to_discard_in_text[7] = "<__libc_csu_init>:"
blocks_to_discard_in_text[8] = "<_start>:"; # !!!
number_of_blocks_to_discard_in_text = length(blocks_to_discard_in_text);
blocks_to_handle_in_text[1] = "main"
number_of_blocks_to_handle_in_text = length(blocks_to_handle_in_text);
blocks_to_handle_in_data[1] = "__dso_handle"
number_of_blocks_to_handle_in_data = length(blocks_to_handle_in_data);
externs_to_handle[1] = "printf";
number_of_externs_to_handle = length(externs_to_handle);
hexdump_start_byte = 11;
disassembly_start_byte = 33;
current_section = "";
getline;
getline;
file_format_index = match($0, "file format elf64-x86-64")
if (file_format_index > 0)
{
print "[bits 64]";
}
}
{
match_index = 0; # 0 : no match, > 0 : match.
i = 1; # index to sections_to_handle .
while (i <= number_of_sections_to_handle)
{
match_index = match($0, (disassembly_of_section_string sections_to_handle[i]));
if (match_index > 0) # we have a section to handle.
{
current_section = sections_to_handle[i];
getline;
break;
}
i++;
}
match_index = 0; # 0 : no match, > 0 : match.
i = 1; # index to sections_to_discard .
while (i <= number_of_sections_to_discard)
{
match_index = match($0, (disassembly_of_section_string sections_to_discard[i]));
if (match_index > 0) # we have a section to discard.
{
current_section = sections_to_discard[i];
getline;
break;
}
i++;
}
if (match (current_section, ".plt"))
{
match_index = 0; # 0 : no match, > 0 : match.
i = 1; # index to externs_to_handle.
while (i <= number_of_externs_to_handle)
{
match_index = match($0, ("<" externs_to_handle[i] "@plt>:"));
if (match_index > 0) # we have an extern to handle.
{
print "extern " externs_to_handle[i];
getline;
break;
}
i++;
}
}
if (match (current_section, ".text"))
{
match_index = 0; # 0 : no match, > 0 : match.
i = 1; # index to the blocks of section .text .
while (i <= number_of_blocks_to_handle_in_text)
{
match_index = match($0, ("<" blocks_to_handle_in_text[i] ">:"));
if (match_index > 0) # we have a block to handle.
{
print "section .text";
print "global main";
print blocks_to_handle_in_text[i] ":";
getline;
while ((length ($0)) > 0)
{
disassembly_without_hex_bytes = substr($0, disassembly_start_byte);
disassembly_without_hex_bytes = gensub(/PTR /, "", "g", disassembly_without_hex_bytes);
disassembly_without_hex_bytes = gensub(/(ds:)([a-z0-9]*)/, "[\\2]", "g", disassembly_without_hex_bytes);
match_index = 0; # 0 : no match, > 0 : match.
j = 1; # index to externs to handle.
while (j <= number_of_externs_to_handle)
{
match_index = match(disassembly_without_hex_bytes, ("<" externs_to_handle[i] "@plt>"));
if (match_index > 0) # we have an extern to handle.
{
current_extern_to_handle = externs_to_handle[j];
"echo '" disassembly_without_hex_bytes "' | sed 's/\\([0-9]*\\)\\( <\\)\\(" current_extern_to_handle "\\)\\(@plt>\\)/\\3/g'" |& getline disassembly_without_hex_bytes;
close("echo '" disassembly_without_hex_bytes "' | sed 's/\\([0-9]*\\)\\( <\\)\\(" current_extern_to_handle "\\)\\(@plt>\\)/\\3/g'");
break;
}
j++;
}
if (match(disassembly_without_hex_bytes, "data32") != 1)
{
print disassembly_without_hex_bytes;
}
getline;
}
break;
}
i++;
}
}
if (match (current_section, ".data"))
{
match_index = 0; # 0 : no match, > 0 : match.
i = 1; # index to the blocks of section .data .
while (i <= number_of_blocks_to_handle_in_data)
{
match_index = match($0, ("<" blocks_to_handle_in_data[i] ">:"));
if (match_index > 0) # we have a block to handle.
{
print "section .data";
getline;
while ((length ($0)) > 0)
{
getline;
hexdump_only = substr($0, hexdump_start_byte, (disassembly_start_byte - hexdump_start_byte));
hexdump_only = gensub(/([[:alnum:]]+)/, "0x\\1", "g", hexdump_only);
hexdump_only = gensub(/(0x[[:alnum:]]+)( )(0x[[:alnum:]]+)/, "\\1, \\3", "g", hexdump_only);
hexdump_only = gensub(/(0x[[:alnum:]]+)( )(0x[[:alnum:]]+)/, "\\1, \\3", "g", hexdump_only);
if (match (hexdump_only, "0x") > 0)
{
print "db " hexdump_only;
}
}
break;
}
i++;
}
}
}
执行 ./ objdump_to_asm objdump_output.txt&GT; 2nd_generation.asm
产生以下汇编文件。与YASM组装,与海湾合作委员会的联系。组装和链接的可执行文件不与原来的一样,实际上它是6496字节,而原来的可执行文件有6568字节大小。
Executing ./objdump_to_asm objdump_output.txt >2nd_generation.asm
produces the following assembly file. Assembles with YASM, links with GCC. The assembled and linked executable is not identical with the original, actually it's 6496 bytes, whereas the original executable has size of 6568 bytes.
[bits 64]
extern printf
section .text
global main
main:
push rbp
mov rbp,rsp
lea rdi,[0x401958]
mov rsi,QWORD [0x401965]
xor eax,eax
call printf
mov eax,0x3c
xor ebx,ebx
syscall
section .data
db 0x61
db 0x62
db 0x63, 0x64, 0x65, 0x66
db 0x20, 0x3d, 0x20, 0x25, 0x64, 0x0a
db 0x00, 0x39
db 0x05, 0x00, 0x00, 0x74, 0x65
db 0x73, 0x74
db 0x20, 0x30
db 0x31, 0x0a
db 0x00, 0x00
这篇关于我可以将所有的章节&QUOT; objdump的-s -d ELF文件&QUOT;生成到一个重新组装能力的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!