How stack memory works when pushing value to it on x86_64?

249 views Asked by At

I have been writing some code in assembly and i found a bug that was overwriting others memory locations and giving to me a segmentation fault, this trouble was made using the rbp register, but the following example use other register to make easy to understand.

 ; Moving some value to rax and pushing to stack
 mov rax, "romulomo"
 push rax

 ; Moving rbp to same location of rsp that points to "romulomo"
 mov rbp, rsp

 ; Moving a debug byte to position rbp-1
 mov BYTE [rbp-1], "#"

 ; Printing everything
 mov rax, 1
 mov rdi, 1
 lea rsi, [rbp]
 mov rdx, 8
 syscall

 ; Exit from program
 mov rax, 60
 syscall

My questions is: Using the fact that stack increase down, the rbp is pointing to the first byte of sequence (0) or the last byte of sequence (7) on the data pushed using rax register ?

enter image description here

The output of program is:

romulomo

It isn't weird? i put a '#' where should be the first 'o' of 'romulo' and the program prints exactly 'romulomo'.

Something interesting is that if i put the '#' using rbp+1 like in the following example, this works without any troubles, however, doing it, theoretically i put before the entire sequence of bytes...

mov BYTE [rbp+1], "#"

Can anyone help ?

1

There are 1 answers

1
St0rm On

Let's suppose that RSP point to the address : 0xFF1E8

 ; Moving some value to rax and pushing to stack
 mov rax, "romulomo" 
 push rax 

;                                      +-> RSP=0xFF1E98-8
;Low              stack                |         High
;+-------------------------------------+--------+
;|                                     |romulomo| 
;+-------------------------------------+--------+
; RSP=0xFF1E90 | RBP=0xXXXXXXX
 

; Moving rbp to same location of rsp that points to "romulomo"
 mov rbp, rsp

; RSP=0xFF1E90 | RBP=0xFF1E90
 
; Moving a debug byte to position rbp-1
 mov BYTE [rbp-1], "#"

;                                       +-> RBP = RSP = 0xFF1E90
;Low              stack           |RBP-1|         High
;+--------------------------------+-----+--------+
;|                                |  #  |romulomo| 
;+--------------------------------+-----+--------+
; RSP=0xFF1E90 | RBP=0xFF1E90

; mov BYTE [rbp+1], "#" ; to replace the first "o" with "#": r#mulomo

;                                         
;Low              stack           |RBP-1|RBP|RBP+1|      RBP+8
;+--------------------------------+-----+---+-----+------+
;|                                |  #  | r |  o  |mulomo| 
;+--------------------------------+-----+---+-----+------+


 ; Printing everything
 mov rax, 1          ; __NR_write
 mov rdi, 1          ; fd = stdout

 lea rsi, [rbp]      ; mov rsi, rbp  would be more efficient
;            RSI = start of buffer = RBP = RSP = 0xFF1E90
;Low              stack           |RBP-1|         High
;+--------------------------------+-----+--------+
;|                                |  #  |romulomo| 
;+--------------------------------+-----+--------+

 mov rdx, 8          ; length = 8 bytes
 syscall             ; write(1, rsi, 8)

 ; Exit from program
 mov rax, 60
 syscall