gpt4 book ai didi

linux - 在 i386 Linux 上的汇编中提高 BRK

转载 作者:太空宇宙 更新时间:2023-11-04 04:45:59 24 4
gpt4 key购买 nike

我发现并研究了x86 memory access segmentation fault它在我的代码中不起作用。区别可能在于我不使用单独的 .text 和 .data 段,而是通过创建自定义 ELF header 将所有内容保留在单个段中。这可以解释为什么 SYS_BRK 调用失败吗?

然后程序继续执行内存页读/写/执行等操作。我试图找到说明问题的最小代码示例。

在 kdbg 中,示例确实有效,但从命令行启动时无效,因此会打印消息。

            cpu   386
bits 32

; System calls used
%assign SYS_EXIT 1
%assign SYS_WRITE 4
%assign SYS_BRK 45
%assign SYS_MPROTECT 125

; flags for SYS_MPROTECT
%assign PROT_READ 1
%assign PROT_WRITE 2
%assign PROT_EXEC 4

%assign STDOUT 1

memstart: org 0x08048000

ehdr: ; Elf32_Ehdr (see https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)
db 0x7F, "ELF" ; e_ident[EI_MAG0..EI_MAG03]
db 1 ; e_ident[EI_CLASS]
db 1 ; e_ident[EI_DATA]
db 1 ; e_ident[EI_VERSION]
db 0 ; e_ident[EI_OSABI]
db 0 ; e_ident[EI_ABIVERSION]
times 7 db 0 ; e_ident[EI_PAD]
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw ehdrsize ; e_ehsize
dw phdrsize ; e_phentsize
dw 1 ; e_phnum
dw 0 ; e_shentsize
dw 0 ; e_shnum
dw 0 ; e_shstrndx
ehdrsize equ $ - ehdr

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

memsize: dd 16*4096 ; = 16 * 4K pages
memtop: dd 0


start: ;int 3
xor ebx, ebx ; find the amount of allocated memory
mov eax, SYS_BRK
int 0x80 ; eax contains current memtop

sub eax, memstart ; got enough memory?
test eax, [memsize]
ja memgood

mov eax, memstart ; raise memory limit to memstart + memsize
add eax, [memsize]
mov ebx, eax
mov ecx, eax ; save requested memory size in ecx
mov eax, SYS_BRK
int 0x80
cmp eax, ecx
jne brk_error ; raising memory limit failed

memgood: mov edx, (PROT_READ | PROT_WRITE | PROT_EXEC)
mov ecx, [memsize] ; make memory read/write/execute
mov ebx, memstart
mov eax, SYS_MPROTECT
int 0x80
test eax, eax
js bailout

jmp launch ; lets start the party


brk_error: mov edx, brkelen
mov ecx, brke
mov ebx, STDOUT
mov eax, SYS_WRITE
int 0x80
jmp bailout
brke: db 'SYS_BRK failed, bye', 10
brkelen equ $ - brke

bailout: mov eax, SYS_EXIT
xor ebx, ebx
int 0x80

launch: mov edx, succlen
mov ecx, succ
mov ebx, STDOUT
mov eax, SYS_WRITE
int 0x80
jmp bailout
succ: db 'Success with mem config, bye', 10
succlen equ $ - succ

filesize equ $ - $$

最佳答案

您应该在此处使用 cmp 而不是 test:

    sub     eax, memstart               ; got enough memory?
test eax, [memsize]
ja memgood

SYS_BRK 描述的内存区域在可执行文件之后启动 0 到 0x02000000 的随机偏移,除非禁用地址空间布局随机化,我怀疑您的调试器会这样做。您可以使用 mmap 在指定地址分配内存(不要设置 MAP_FIXED,除非您想覆盖现有映射)。

但是,使用 brkmprotect 进行的整个练习似乎毫无意义,因为除了程序启动时的堆栈之外,内存完全按照 ELF header 指定的方式进行分配,相反,您可以:

phdr:                                           ; Elf32_Phdr
dd 1 ; p_type
dd 0 ; p_offset
dd $$ ; p_vaddr
dd $$ ; p_paddr
dd filesize ; p_filesz
dd 16*4096 ; p_memsz
dd 7 ; p_flags
dd 0x1000 ; p_align
phdrsize equ $ - phdr

关于linux - 在 i386 Linux 上的汇编中提高 BRK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36386504/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com