1

Really quick question here. I'm working in Ubuntu, I have a simple "Hello World!" program in assembly which I have assembled into x86 assembly. Now I want to turn that machine code into an ELF executable which my computer can run. I am aware that I could just assemble directly to ELF, the purpose of my inquiry is to discover how to make ELF binaries out of assembled machine code.

Thanks!

2 Answers 2

1

Final ELF executable files are typically built out of other ELF files, reorganized by the linker. The easiest way, of course, would be to specify ELF as the output format of your assembler.


1) If you really want to do this, you could start with an "empty" ELF file (that you get from compiling or assembling nothing, etc.). Then you could use objcopy --add-section, which allows you to add an arbitrary file as a section in an existing ELF file.

This will create a minimal ELF file:

$ echo "" | gcc -c -o empty.out -xc - 


2) Alternatively, you could include your raw binary into another assembly file using something like nasm's incbin, which would then need to be assembled as an ELF.


3) A third option (the best so far) would be to provide your raw binary to the linker, and use a custom linker script to tell it what section to put it in (determined from the input file name). The -b flag before an input file will tell ld what type of file it is. This should let you use your flat binary file.


One of the first obstacles you're going to face is getting the entry point to point to your code. Off the top of my head I'm not sure how to edit that.

There is a Python library, pyelftools that may help you in your quest.

Sign up to request clarification or add additional context in comments.

4 Comments

If I were, say, interested in tinkering with making my own compiler, but not yet ready to invest the time to write the code to generate an entire ELF file with all of its headers and tables and sections, I might be interested in making an ELF file out of x86 machine code :) Let me try your first suggestion...
@BigEndian Fair enough - that seems like a logical reason to do something like this then. I'll let you know if I come up with any other ideas.
Now my linker has gone all funky on me and it's almost bed time. I think I'll pick this up tomorrow. I can probably edit the entry point pointer with a little bit of Python code. Kludgey solution, but that's what I'm good at.
I can't think of anything short of going in by hand every time and editing the file in a hex editor. I've already made a printout of a simple ELF and marked out all the different pieces. It's not impossible, but that's a serious pain in the butt. 2 isn't really an attractive solution to me, that's kinda a silly way to go about this. 3 doesn't work, I've tried and tried and tried. I'm sceptical of 1 but it may have potential. I have yet to try it.
0

If it's really assembled, then it's already in the ELF format (compilers targeting Linux generally store the object code in ELF object files as well).

However, if you want a fully-functioning executable, you have to feed the object file to a linker.

2 Comments

@BigEndian What do you mean by that? What format is it in? Flat binary? How did you invoke the assembler?
@JonathonReinhart Thanks. Not yet entirely clear, but I suppose we have a flat binary. Alrght, invesitgating.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.