将内存与自定义 ELF 文件一起使用时出现分段错误

Segmentation fault when using memory with custom ELF file

我正在尝试使用自定义 ELF 编写一个小型 ELF 程序 header 但是每当我写入内存时都会出现分段错误。

为什么该代码会触发分段错误?

%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

好吧,发现该程序缺少带有 R/W 数据/bss 部分标志的第二个程序头,它描述了 OS 的第二个内存段,并带有 运行时间执行。

这是在 phdrsz equ $ - phdr 行之后添加的内容:

    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

注意:在理解这一点之前,我被部分的重要性误导了,我认为通过描述部分我可以访问内存,但事实证明程序头就是 OS 正在寻找的因为,可以删除整个部分代码,程序仍然有效。