Chapter 3. IELFO - ELF File Producer Interface

The ELFIO library can help you build a very short ELF executable file. This chapter shows how to build an executable file that will run on x86 Linux machines and print "Hello World!" on your console.

Just as with the reader, the first step is to get a pointer onto the ELF File Writer (Producer):

    IELFO* pELFO;
    ELFIO::GetInstance()->CreateELFO( &pELFO );

Before continuing, the library must be informed about the main attributes of the executable file to be built. To do this, declare that the executable ELF file will run on a 32 bit x86 machine; has little endian encoding and uses the current version of the ELF file format:

    // You can't proceed without this function call!
    pELFO->SetAttr( ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
                    ET_EXEC, EM_386, EV_CURRENT, 0 );

Some sections of an ELF executable file should reside in the program segments. To create this loadable segment call the AddSegment() function.

    // Create a loadable segment
    IELFOSegment* pSegment = pELFO->AddSegment( PT_LOAD,
                                                0x08040000,
                                                0x08040000,
                                                PF_X | PF_R,
                                                0x1000 );

The following segment serves as a placeholder for our code section. To create this code section call the AddSection() function:

    // Create code section
    IELFOSection* pTextSec = pELFO->AddSection( ".text",
                                   SHT_PROGBITS,
                                   SHF_ALLOC | SHF_EXECINSTR,
                                   0,
                                   0x10,
                                   0 );

Then, add the executable code for the section:

    char text[] =
    { '\xB8', '\x04', '\x00', '\x00', '\x00',   // mov eax, 4
      '\xBB', '\x01', '\x00', '\x00', '\x00',   // mov ebx, 1
      '\xB9', '\xFD', '\x00', '\x04', '\x08',   // mov ecx, msg
      '\xBA', '\x0E', '\x00', '\x00', '\x00',   // mov edx, 14
      '\xCD', '\x80',                           // int 0x80
      '\xB8', '\x01', '\x00', '\x00', '\x00',   // mov eax, 1
      '\xCD', '\x80',                           // int 0x80
      '\x48', '\x65', '\x6C', '\x6C', '\x6F',   // db 'Hello'
      '\x2C', '\x20', '\x57', '\x6F', '\x72',   // db ', Wor'
      '\x6C', '\x64', '\x21', '\x0A'            // db 'ld!', 10
    };
    pTextSec->SetData( text, sizeof( text ) );

Next, this code section is put into the loadable segment:

    // Add code section into program segment
    pSegment->AddSection( pTextSec );
    pTextSec->Release();
    pSegment->Release();

Finally, define the start address of the program and create the result file:

    // Set program entry point
    pELFO->SetEntry( 0x08040000 );
    // Create ELF file
    pELFO->Save( "test.elf" );
    pELFO->Release();

Please note: Call the Release() functions for each interface you have used. This will free all resources the ELFIO library has created.

Now compile the program and run it. The result is a new ELF file called "test.elf". The size of this working executable file is only 267 bytes! Run it on your Linux machine with the following commands:

    [Writer]$ ./Writer
    [Writer]$ chmod +x test.elf
    [Writer]$ ./test.elf
    Hello, World!

The full text for this program can be found in the "Writer" directory. Also, in the "Examples" directory, two other programs "WriteObj" and "WriteObj2" demonstrate the creation of ELF object files.