汇编 x86 brk() 调用使用

use*_*262 8 linux assembly x86-64 dynamic-memory-allocation brk

我正在尝试将内存动态分配到堆中,然后在这些内存地址中分配值。我了解如何分配内存,但我如何将例如寄存器中的值分配给第一个动态内存地址?这是我到目前为止:

    push rbp
    mov rbp, rsp            ;initialize an empy stack to create activation records for the rest of the subroutines                                                                                                                        

    mov rax, 0x2d           ;linux system call for brk()                                                                                                                                                                                  
    mov rbx, 0x0            ;to get the adress of the first adress we are allocating we must have 0 in rbx                                                                                                                                
    int 0x80                ;calls the linux operating system kernel for assistance                                                                                                                                                       
    mov [brk_firstLocation], rax ;the first position in the heap will be returned in rax thus i save the first loaction in a varable called brk_firstLocation                                                                             

    mov rbx, rax            ;the memory adress of the start of the heap is moved in rbx                                                                                                                                                   
    add rbx, 0x14           ;we want 5 bytes worth of data alocated in the heap, so the start adress plus 20 bits                                                                                                                         
    mov rax, 0x2d           ;linux system call for brk()                                                                                                                                                                                  
    int 0x80                ;calls the linux operating system kernel for assistance
Run Code Online (Sandbox Code Playgroud)

例如,我会如何处理into 中mov的值raxbrk_firstLocation

小智 9

其他人指出您的代码有一些错误。我想补充一点,你就不会添加20到当前断点(或20个字节add rbx, 20实际上没有),您只需加5个字节。

此外,您的第一个系统调用参数不会在 rbx 中,而是在 rdi 中。 64 位系统调用 ABI使用与 32 位 ABI(在 64 位进程中仍然可用)不同的系统调用号、不同的寄存器和不同的指令(syscall而不是int 0x80)。另请参阅标记 wiki 以获取更多 ABI 链接。

您的代码应如下所示:

push rbp
mov rbp, rsp

;; sys_brk(0)
mov   rax, 12         ; 12 is SYS_brk (/usr/include/asm/unistd_64.h)
mov   rdi, 0          ; rdi for first syscall arg in the 64-bit ABI, not rbx
syscall               ; syscall, not int 0x80, for the 64-bit ABI

mov   qword [brk_firstLocation], rax

;; sys_brk(old_break + 5)
lea   rdi, [rax + 5]  ; add 5 bytes to the break point
mov   rax, 12
syscall               ; set the new breakpoint
Run Code Online (Sandbox Code Playgroud)

此时,您可以使用 brk_firstLocation 作为指向要存储在堆上的任何 5 字节结构的指针。以下是将值放入该内存空间的方法:

mov   rdi, [brk_firstLocation]   ; load the pointer from memory, if you didn't already have it in a register

mov   byte [rdi], 'A'            ; a char in the first byte
mov   [rdi+1], ecx               ; a 32-bit value in the last 4 bytes.
Run Code Online (Sandbox Code Playgroud)


Gen*_*ene 0

正如您所做的那样,调用一次以检索堆的当前底部,然后移动堆的顶部(即 brk 值)。但是,您的代码在使用 64 位寄存器集时不正确r.x。如果您的 Linux 是 32 位(系统调用号使用 45 表示),那么您需要 32 位寄存器集:

mov eax, 45                            ; brk                                                                                                                                                                                  
mov ebx, 0                             ; arg 1: 0 = fail returning brk value in rax                                                                                                                               
int 0x80                               ; syscall
mov dword ptr [brk_firstLocation], rax ; save result
mov eax, 45                            ; brk                                                                                                                                                                                  
mov ebx, 4                             ; arg 1: allocate 4 bytes for a 32-bit int                                                                                                                                
int 0x80                               ; syscall

mov eax, dword ptr [brk_firstLocation] ; reload rax with allocated memory address.
mov dword ptr [eax], 42 ; use result: store 42 in newly allocated storage
Run Code Online (Sandbox Code Playgroud)

当然,您可以根据需要多次重新加载保存的值以供重复使用。