Skip to content
Advertisement

Segmentation fault when using memory with custom ELF file

I am trying to program a small ELF program with a custom ELF header but have a segmentation fault whenever i am writing to memory.

Why would that code trigger a segmentation fault ?

%assign LOAD_ADDRESS 0x08048000

BITS 32
    org LOAD_ADDRESS ; load address

ehdr:                         ; Elf32_Ehdr
    db 0x7F, "ELF", 1, 1, 1   ;   e_ident
    times 9 db 0 ; some places to run code ?
    dw 2                      ;   e_type
    dw 3                      ;   e_machine
    dd 1                      ;   e_version
    dd _start                 ;   e_entry
    dd phdr - $$              ;   e_phoff
    dd shent - $$             ;   e_shoff
    dd 0                      ;   e_flags
    dw ehdrsz                 ;   e_ehsize
    dw phdrsz                 ;   e_phentsize
    dw 1                      ;   e_phnum
    dw shentsize              ;   e_shentsize
    dw 3                      ;   e_shnum
    dw 2                      ;   e_shstrndx
ehdrsz equ $ - ehdr

phdr:                         ; Elf32_Phdr
    dd 1                      ;   p_type
    dd 0                      ;   p_offset
    dd $$                     ;   p_vaddr
    dd $$                     ;   p_paddr
    dd filesz                 ;   p_filesz
    dd filesz                 ;   p_memsz
    dd 5                      ;   p_flags
    dd 0x1000                 ;   p_align
phdrsz equ $ - phdr

shent: ; sections table
    ; data
    dd 0 ; unamed
    dd 1 ; PROGBITS
    dd 2|1 ; ALLOC / WRITE
    dd data
    dd data - LOAD_ADDRESS
    dd datasz
    dd 0
    dd 0
    dd 4
    dd 0

shentsize equ $ - shent ; length of a single section entry

    ; bss
    dd 6 ; unamed
    dd 8 ; NOBITS
    dd 2|1 ; ALLOC / WRITE
    dd bss
    dd bss - LOAD_ADDRESS
    dd bsssz
    dd 0
    dd 0
    dd 4
    dd 0

    ; shstrtab
    dd 11 ; unamed
    dd 3 ; STRTAB
    dd 0
    dd shstrtab
    dd shstrtab - LOAD_ADDRESS
    dd shstrtabsz
    dd 0
    dd 0
    dd 1
    dd 0
; ELF end

section .shstrtab
shstrtab:
    db ".data",0
    db ".bss",0
    db ".shstrtab",0
shstrtabsz equ $ - shstrtab

_start:
    mov eax,0
    mov [test],eax ; segmentation fault

    xor eax,eax
    inc eax
    int 0x80

section .data
data:
    test:
        db 1
datasz equ $ - data

section .bss
bss:
bsssz equ $ - bss

filesz equ $ - $$
nasm -f bin -o small_program small_program.asm

Advertisement

Answer

Okay found out that the program was missing a second program header with R/W flag for the data / bss section, it describe a second memory segment for the OS with the appropriate flags for run time execution.

Here is what to add after phdrsz equ $ - phdr line :

    dd 1                      ;   p_type
    dd data - LOAD_ADDRESS    ;   p_offset
    dd data                   ;   p_vaddr
    dd data                   ;   p_paddr
    dd datasz                 ;   p_filesz
    dd datasz + bsssz         ;   p_memsz
    dd 6                      ;   p_flags (R/W)
    dd 0x1000                 ;   p_align

Note : Before understanding this i was mislead on the importance of the sections, i thought that by describing the sections i could access the memory but it turns out that the program headers is what the OS is looking for, the whole sections code can be dropped and the program still work.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement