Ошибка сегментации при использовании памяти с пользовательским файлом ELF - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь запрограммировать небольшую программу ELF с пользовательским заголовком ELF, но при записи в память у меня возникает ошибка сегментации.

Почему этот код вызывает ошибку сегментации?

%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

1 Ответ

0 голосов
/ 30 декабря 2018

Хорошо, выяснилось, что в программе отсутствует второй заголовок программы с флагом R / W для раздела data / bss, он описывает второй сегмент памяти для ОС с соответствующими флагами для выполнения во время выполнения.

Вот что добавить после 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

Примечание: Прежде, чем понять это, я ввел в заблуждение относительно важности разделов, я подумал, что, описывая разделы, я мог получить доступ к памяти, но этоОказывается, что заголовки программы - это то, что ищет ОС, код целых разделов можно удалить, и программа все еще работает.

...