I am trying to dynamically allocate memory into the heap and then assign values in those memory addresses. I understand how to allocate the memory but how would I assign for example the value in a register to that first dynamic memory address? This is what I have so far:
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
What would I do, for example, to mov
the value in rax
into brk_firstLocation
others have pointed out a few things that are wrong with your code. I would like to add that you would not add 20 bits to the current breakpoint (or 20 bytes like add rbx, 20
actually does), you would simply add 5 bytes.
Also, your first syscall argument will not be in rbx, it will be in rdi. The 64-bit syscall ABI uses different system call numbers, different registers, and a different instruction (syscall
instead of int 0x80
) than the 32-bit ABI (which is still available in 64-bit processes). See also the x86 tag wiki for more ABI links.
Here's how your code should look:
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
At this point you can use brk_firstLocation as a pointer to whatever 5 byte struct you want to store on the heap. Here's how you would put values in that memory space:
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.
int 80h
is only for 32 bit system calls. Use syscall
for 64 bit instead.
Calling sys_brk twice is redundant - in assembly you always know where your program data ends. Simply put a label there and you will have the address.
Allocating this way memory less than one page is pointless, it will be allocated in blocks of 4KB anyway.
It is important to be understood - sys_brk is not heap management function. It is low level memory management.
There are a number of problems I see:
So you want something like:
mov [brk_firstloaction], _end
mov rbx, [brk_firstlocation]
add rbx, 0x14 ; space for 5 dwords (20 bytes)
mov rax, 12
int 0x80
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With