Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7076689
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T06:19:44+00:00 2026-05-28T06:19:44+00:00

I’m trying to generate a simple static ELF using libelf, but I seem to

  • 0

I’m trying to generate a simple static ELF using libelf, but I seem to be having troubles.

I do not wish to generate an object file and then link it w/ LD, instead I wish to generate it on my own.

The main purpose of this program is to generate a static ELF with one LOAD segment and to execute the code.

The main problem is not in the shellcode itself,but probably in some of headers I try to produce in a wrong way. When I try to run the generated ELF it gets killed as if the kernel doesn’t manage to find the segment it just loaded, etc.

I would be fond if you guys could hint me.

create_elf.3.c

#include <err.h>
#include <fcntl.h>
#include <libelf.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>

unsigned char code[] =
"\x0b\x58\x99\x52\x66\x68\x2d\x70"
"\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61"
"\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52"
"\x51\x53\x89\xe1\xcd\x80";

int main(int argc, char *argv[])
{
  int           fd;
  Elf           *e;
  Elf_Scn       *scn;
  Elf_Data      *data;
  Elf32_Ehdr    *ehdr;
  Elf32_Phdr    *phdr;
  Elf32_Shdr    *shdr;
  if (argc != 2)
    errx(EX_USAGE,"input... ./%s filename\n",argv[0]);
  if (elf_version(EV_CURRENT) == EV_NONE)
    errx(EX_SOFTWARE,"elf_version is ev_none, wtf? %s\n",elf_errmsg(-1));
  if ((fd = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0)
    errx(EX_OSERR, "open %s\n",elf_errmsg(-1));
  if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL)
    errx(EX_SOFTWARE,"elf_begin %s\n",elf_errmsg(-1));
  if ((ehdr = elf32_newehdr(e)) == NULL)
    errx(EX_SOFTWARE,"elf32_newehdr %s\n",elf_errmsg(-1));
  /*
     without these definitions objdump/readelf/strace/elf loader
     will fail to load the binary correctly
     be sure to pick them carefully and correctly, preferred exactly like the
     ones like the system you are running on (so if you are running x86,
     pick the same values you seen on a regular readelf -a /bin/ls
     */
  ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
  ehdr->e_ident[EI_CLASS] = ELFCLASS32;
  ehdr->e_machine = EM_386;
  ehdr->e_type = ET_EXEC;
  ehdr->e_entry = 0x8040800;
  if ((phdr = elf32_newphdr(e,1)) == NULL)
    errx(EX_SOFTWARE,"elf32_newphdr %s\n",elf_errmsg(-1));
  if ((scn = elf_newscn(e)) == NULL)
    errx(EX_SOFTWARE,"elf32_newscn %s\n",elf_errmsg(-1));
  if ((data = elf_newdata(scn)) == NULL)
    errx(EX_SOFTWARE,"elf32_newdata %s\n",elf_errmsg(-1));
  data->d_align = 4;
  data->d_off = 0LL;
  data->d_buf = code;
  data->d_type = ELF_T_WORD; // code :x
  data->d_size = sizeof(code);
  data->d_version = EV_CURRENT;
  if ((shdr = elf32_getshdr(scn)) == NULL)
    errx(EX_SOFTWARE,"elf32_getshdr %s\n",elf_errmsg(-1));
  shdr->sh_name = 0;
  shdr->sh_type = SHT_PROGBITS;
  shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
  shdr->sh_entsize = 0; // only used if we hold a table
  if (elf_update(e, ELF_C_NULL) < 0)
    errx(EX_SOFTWARE,"elf_update_1 %s\n",elf_errmsg(-1));
  phdr->p_type = PT_LOAD;
  phdr->p_offset = ehdr->e_phoff;
  phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
  phdr->p_vaddr = 0x8040800;
  phdr->p_paddr = 0x8040800;
  phdr->p_align = 4;
  phdr->p_filesz = sizeof(code);
  phdr->p_memsz = sizeof(code);
  phdr->p_flags = PF_X | PF_R;
  elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
  if (elf_update(e, ELF_C_WRITE) < 0 )
    errx(EX_SOFTWARE,"elf32_update_2 %s\n",elf_errmsg(-1));
  elf_end(e);
  close(fd);
  return 1;
}

I would be fond if someone could hint me what’s wrong here

Thanks

edit

Sorry for not giving more details,

The ELF generation seems to be working ok, I do not get any syntax errors etc,
however whenever I try to run ELF I generated, e.g ./create_elf.3 foo14 (and foo14 is the generated ELF)

It gets killed, as if execve/kernel doesn’t wish to load it properly
I tried loading it w/ IDA but IDA shows the disassembled code fine enough

here’s the output from readelf

readelf -a foo14
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8040800
  Start of program headers:          52 (bytes into file)
  Start of section headers:          116 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         2
  Section header string table index: 0
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0] <no-name>         NULL            00000000 000000 000000 00      0   0  0
  [ 1] <no-name>         PROGBITS        00000000 000054 000020 00  AX  0   0  4
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000034 0x08040800 0x08040800 0x00021 0x00021 R E 0x4
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T06:19:45+00:00Added an answer on May 28, 2026 at 6:19 am

    First, it would be a good idea during testing to replace the code
    fragment containing (naughty) shell code with something harmless, say:

    unsigned char code[] = {
        0xBB, 0x2A, 0x00, 0x00, 0x00, /* movl $42, %ebx */
        0xB8, 0x01, 0x00, 0x00, 0x00, /* movl $1, %eax */
        0xCD, 0x80            /* int $0x80 */
    };
    

    On an i386 GNU/Linux system this revised code fragment causes the process
    to immediately exit with an exit code of 42.

    The following ASCII art illustrates the layout of the ELF executable
    being built:

    +----------------------------------+  <- LOADADDR (0x08048000)
    |  The ELF Exec Header.            |  
    +----------------------------------+
    |  The ELF PHDR Table.             |
    +----------------------------------+ <- ehdr->e_entry points here.
    |  The ".text" section.            |
    +----------------------------------+ <- The end of loadable region
    |  The section name string table   |    for this object.
    |  (optional).                     |
    +----------------------------------+
    |  Section headers:                |
    |  - Header for section ".text".   |
    |  - Section name string table     |
    |    header.                       |
    +----------------------------------+
    

    The section name string table is optional. It helps to neaten the
    output of readelf.

    #define LOADADDR    0x08048000
    

    The executable will be loaded at the virtual address named by
    LOADADDR. The value for LOADADDR is system dependent—a value of
    0x08048000 seems to work well on my system.

    The executable code fragment is placed just after the PHDR table. The
    e_entry field of the ELF Executable Header holds the virtual address
    to which control will be transferred to. The value of the field
    should therefore be:

    size_t ehdrsz, phdrsz;
    
    ehdrsz = elf32_fsize(ELF_T_EHDR, 1, EV_CURRENT);
    phdrsz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
    
    /* ... */
    
    ehdr->e_entry = LOADADDR + ehdrsz + phdrsz;
    

    Code segments would use a data type of ELF_T_BYTE and a section type
    of SHT_PROGBITS, with an alignment of 1.

    if ((scn = elf_newscn(e)) == NULL)
        errx(EX_SOFTWARE,"elf32_newscn %s\n", elf_errmsg(-1));
    
    if ((data = elf_newdata(scn)) == NULL)
        errx(EX_SOFTWARE,"elf32_newdata %s\n", elf_errmsg(-1));
    
    data->d_align = 1;
    data->d_off = 0LL;
    data->d_buf = code;
    data->d_type = ELF_T_BYTE;
    data->d_size = sizeof(code);
    data->d_version = EV_CURRENT;
    

    The sh_addr field of the section header table entry holds the
    virtual address of the start of the section’s data.

    if ((shdr = elf32_getshdr(scn)) == NULL)
       errx(EX_SOFTWARE,"elf32_getshdr %s\n", elf_errmsg(-1));
    
    shdr->sh_name = 1;      /* Offset of ".text", see below. */
    shdr->sh_type = SHT_PROGBITS;
    shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
    shdr->sh_addr = LOADADDR + ehdrsz + phdrsz;
    

    The sole entry in the ELF Program Header table covers the area to be
    loaded, starting with the ELF header and including the executable
    code.

    if ((phdr = elf32_newphdr(e,1)) == NULL)
       errx(EX_SOFTWARE,"elf32_newphdr %s\n", elf_errmsg(-1));
    
    phdr->p_type = PT_LOAD;
    phdr->p_offset = 0;
    phdr->p_filesz = ehdrsz + phdrsz + sizeof(code);
    phdr->p_memsz = phdr->p_filesz;
    phdr->p_vaddr = LOADADDR;
    phdr->p_paddr = phdr->p_vaddr;
    phdr->p_align = 4;
    phdr->p_flags = PF_X | PF_R;
    

    A section name string table is optional, and makes for nicer output
    from readelf. A hand-rolled string table suffices:

    unsigned char strtab[] = {
        0, '.', 't', 'e', 'x', 't', 0,
        '.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', 0
    };
    

    The code to add the string table to the executable is:

    /*
     * Allocate a string table for section names.
     */
    if ((scn = elf_newscn(e)) == NULL)
       errx(EX_SOFTWARE,"elf32_newscn %s\n", elf_errmsg(-1));
    
    if ((data = elf_newdata(scn)) == NULL)
       errx(EX_SOFTWARE,"elf32_newdata %s\n", elf_errmsg(-1));
    
    data->d_align = 1;
    data->d_off = 0LL;
    data->d_buf = strtab;
    data->d_type = ELF_T_BYTE;
    data->d_size = sizeof(strtab);
    data->d_version = EV_CURRENT;
    
    if ((shdr = elf32_getshdr(scn)) == NULL)
       errx(EX_SOFTWARE,"elf32_getshdr %s\n", elf_errmsg(-1));   
    
    shdr->sh_name = 7;      /* Offset of ".shstrtab". */
    shdr->sh_type = SHT_STRTAB;
    shdr->sh_flags = SHF_STRINGS;
    

    With these changes the ELF binary created by your program should be
    runnable.

    % cc a.c -lelf
    % ./a.out foo
    % ./foo; echo $?
    42
    

    The structure of the generated executable would be as follows:

    % readelf -a foo
    ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Intel 80386
      Version:                           0x1
      Entry point address:               0x8048054
      Start of program headers:          52 (bytes into file)
      Start of section headers:          116 (bytes into file)
      Flags:                             0x0
      Size of this header:               52 (bytes)
      Size of program headers:           32 (bytes)
      Number of program headers:         1
      Size of section headers:           40 (bytes)
      Number of section headers:         3
      Section header string table index: 2
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .text             PROGBITS        08048054 000054 00000c 00  AX  0   0  1
      [ 2] .shstrtab         STRTAB          00000000 000060 000011 00   S  0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings)
      I (info), L (link order), G (group), x (unknown)
      O (extra OS processing required) o (OS specific), p (processor specific)
    There are no section groups in this file.
    Program Headers:
      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
      LOAD           0x000000 0x08048000 0x08048000 0x00060 0x00060 R E 0x4
     Section to Segment mapping:
      Segment Sections...
       00     .text 
    There is no dynamic section in this file.
    There are no relocations in this file.
    There are no unwind sections in this file.
    No version information found in this file.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
Seemingly simple, but I cannot find anything relevant on the web. What is the
We're building an app, our first using Rails 3, and we're having to build
I'm making a simple page using Google Maps API 3. My first. One marker
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.