flat assembler
Message board for the users of flat assembler.

Index > Linux > Help:Label declaration order, how is this impacting my code?

Author
Thread Post new topic Reply to topic
guitmz



Joined: 11 Jan 2019
Posts: 6
Location: Berlin
guitmz 11 Nov 2019, 16:54
main code
Code:
format ELF64 executable 3

include "utils.inc"

segment readable executable
entry start

macro print msg, msglen {
  mov rax, SYS_WRITE
  mov rdi, 1                 ; STDOUT
  lea rsi, [msg]
  mov rdx, msglen
  syscall
}

start:
    push "."                    ; pushing "." to stack (rsp)
    mov rdi, rsp                ; moving "." to rdi
    xor rsi, rsi                ; cleans rsi so SYS_OPEN doesnt try to use it as argument
    mov rdx, O_RDONLY           ; opening for read only
    mov rax, SYS_OPEN
    syscall                     ; rax contains the fd

    test rax, rax               ; check if fd != 0
    jz stop                     ; if fd = 0, open failed, we should exit

    mov rdi, rax                ; move fd to rdi
    lea rsi, [dirent]           ; struct dirent64
    mov rdx, 1024               ; buf size
    mov rax, SYS_GETDENTS64
    syscall                     ; dirent contains the directory entries

    test rax, rax               ; check directory list was successful
    js stop                     ; if negative code is returned, we failed and should exit

    mov rax, SYS_CLOSE          ; close source fd in rdi
    syscall
    
    xor rcx, rcx                ; will be the position in the directory entries

    print texto, 10            

stop:
    xor rdi, rdi        ; exit code 0
    mov rax, SYS_EXIT   ; sys_exit
    syscall

segment readable writable
dirent  dirent64
texto db "test", 0xA, 0
    


utils.inc

Code:
SYS_EXIT        = 60
SYS_OPEN        = 2
SYS_CLOSE       = 3
SYS_WRITE       = 1
SYS_READ        = 0
SYS_EXECVE      = 59
SYS_MMAP        = 9
SYS_GETDENTS64  = 217

O_RDONLY        = 0
O_DIRECTORY     = 0200000

DT_REG          = 8

struc dirent64 {
        .d_ino      dq ?    ; 64-bit inode number
        .d_off      dq ?    ; 64-bit offset to next struct
        .d_reclen   dw ?    ; size of this dirent
        .d_type     db ?    ; file type
        label .d_name byte
}
    


So like this, this code does not work properly. My string from label "texto" is not printed but something from my struct is instead.

If I invert the order of declaration to:

Code:
segment readable writable
texto db "test", 0xA, 0
dirent  dirent64
    


It works fine. I have a few guesses on whats going on here but can anyone please shed some light for a beginner?

Thanks in advance!
Post 11 Nov 2019, 16:54
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8357
Location: Kraków, Poland
Tomasz Grysztar 12 Nov 2019, 11:41
When you read directory entry, you specify buffer size 1024, but your "dirent64" macro reserves only 19 bytes. Thus you end up overwriting data that follows - in this case your "texto" string. When you swap the definitions, you no longer have anything of value after "dirent" to get overwritten (but there is still some memory available there, because segment size is aligned to 4096 bytes).

Therefore, first and foremost: when you specify a size of a buffer (1024 in this case) always make sure that you actually have that much free space at the address you provide. Otherwise you're likely to get a buffer overflow and overwrite something important.

I would suggest using an additional constant to ensure that you do not indicate more space than you actually reserved:
Code:
DIRENT_BUFSIZE = 1024    
Code:
    mov rdi, rax
    lea rsi, [dirent]
    mov rdx, DIRENT_BUFSIZE
    mov rax, SYS_GETDENTS64
    syscall    
Code:
segment readable writable
dirent  dirent64
        rb DIRENT_BUFSIZE - ($-dirent)    

In addition to that, consider putting your immutable data (like the "texto" string) in a separate segment for read-only data (give it no "writable" attribute).
Post 12 Nov 2019, 11:41
View user's profile Send private message Visit poster's website Reply with quote
guitmz



Joined: 11 Jan 2019
Posts: 6
Location: Berlin
guitmz 12 Nov 2019, 11:55
@Tomasz yeah. That was something inline with what I was guessing, thank you so much! Learned something today.

As for the writable segment, you are also right, thanks for reminding me, I just added the string there to quickly test.

Best regards, thanks for the awesome work!
Post 12 Nov 2019, 11:55
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.