将内存与自定义 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 正在寻找的因为,可以删除整个部分代码,程序仍然有效。
我正在尝试使用自定义 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 正在寻找的因为,可以删除整个部分代码,程序仍然有效。