The following page is quite intriguing to me:
Hand made ELF.
Quote:"Manually creating an ELF executable
Hello class, and welcome to X86 Masochism 101. Here, you'll learn how to use opcodes directly to create an executable without ever actually touching a compiler, assembler or linker. We'll be using only an editor capable of modifying binary files (i.e. a hex editor) and 'chmod' to make the file executable.[1]
If that doesn't turn you on, I don't know what will.
On a more serious note, this is one of those things that I personally think are a lot of fun. Obviously, you're not going to be using this to create serious million-line programs. However, it can give you an enormous amount of satisfaction to know that you actually understand how this kind of thing really works on a low level. It's also cool to be able to say you wrote an executable without ever touching a compiler or interpreter. Beyond that, there are applications in kernel programming, reverse engineering and (perhaps unsurprisingly) compiler creation.
First of all, let's take a very quick look at how executing an ELF file actually works. A lot of details will be left out. What's important is getting a good idea of what your PC does when you tell it to execute an ELF binary file.
When you tell the computer to execute an ELF binary, the first thing it'll look for are the appropriate ELF headers. These headers contain all sorts of important information about CPU architecture, sections and segments of the file, and much more - we'll talk more about that later. The header also contains information that helps the computer identify the file as ELF. Most importantly, the ELF header contains information about the program header table in the case of an executable, and the virtual address to which the computer transfers control upon execution.
The program header table, in turn, defines several segments in program headers. If you've ever programmed in assembly, you can think of some of the sections such as 'text' and 'data' as segments in an executable. The program headers also define where the data of these segments are in the actual file, and what virtual memory address to assign to them.
If everything's been done correctly, the computer loads all segments into virtual memory based on the data in the program headers, then transfers control to the virtual memory address assigned in the ELF header, and starts executing instructions.
Before we begin with the practical stuff, please make sure you've got an actual hex editor on your computer, and that you can execute ELF binaries and are on an x86 machine. Most hex editors should work as long as they actually allow you to edit and save your work - I personally like Bless. If you're on Linux, you should be fine as far as ELF binaries are concerned. Some other Unix-like operating systems might work, too, but different OSes implement things in slightly different ways, so I cannot be sure. I also use system calls extensively, which further limits compatibility. If you're on Windows, you're out of luck. Likewise if your CPU architecture is anything other than x86 (though x86_64 should work, as it is backwards compatible), since I simply cannot provide opcodes for each and every architecture out there.
There are three phases to creating an ELF executable. First, we'll construct the actual payload using opcodes. Second, we'll build ELF and program headers to turn this payload into a working program. Finally, we'll make sure all offsets and virtual addresses are correct and fill in the final blanks.
A word of warning: constructing an ELF executable by hand can be extremely frustrating. I've provided an example binary myself which you can use to compare your work to, but keep in mind that there is no compiler or linker to tell you what you've done wrong. If (read: when) you screw up, all your computer will tell you is 'I/O Error' or 'Segmentation Fault', which makes these programs extremely hard to debug.
Constructing the payload - let's try to keep the payload simple but sufficiently challenging to be interesting. Our payload should put 'Hello World!' on the screen, then exit with code 93. This is harder than it looks. We'll need both a text segment (containing executable instructions) and a data segment (containing the 'Hello World!' string and some other minor data. Let's take a look at the assembly code we need to achieve this:
..."
Read more:
|