LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   trying to emulate linux command in x86_64 assembly (https://www.linuxquestions.org/questions/programming-9/trying-to-emulate-linux-command-in-x86_64-assembly-4175654637/)

starboy 05-26-2019 02:37 PM

trying to emulate linux command in x86_64 assembly
 
I really need your help. so i am basicly trying to emulate Linux rm* command using assembly language :

when i ran strace on the command this is what i've got:
Code:

execve("/bin/rm", ["rm", "test1", "test2"], 0x7ffc85aaee50 /* 56 vars */) = 0
brk(NULL) = 0x556102fd1000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=98111, ...}) = 0
mmap(NULL, 98111, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffbf7d17000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffbf7d15000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffbf7717000
mprotect(0x7ffbf78fe000, 2097152, PROT_NONE) = 0
mmap(0x7ffbf7afe000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7ffbf7afe000
mmap(0x7ffbf7b04000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffbf7b04000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7ffbf7d16540) = 0
mprotect(0x7ffbf7afe000, 16384, PROT_READ) = 0
mprotect(0x556102aee000, 4096, PROT_READ) = 0
mprotect(0x7ffbf7d2f000, 4096, PROT_READ) = 0
munmap(0x7ffbf7d17000, 98111) = 0
brk(NULL) = 0x556102fd1000
brk(0x556102ff2000) = 0x556102ff2000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=4584960, ...}) = 0
mmap(NULL, 4584960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffbf72b7000
close(3) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "test1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "test1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "test1", W_OK) = 0
unlinkat(AT_FDCWD, "test1", 0) = 0
newfstatat(AT_FDCWD, "test2", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "test2", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "test2", W_OK) = 0
unlinkat(AT_FDCWD, "test2", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++

here is the code i previously wrote
Code:

global _start

section .text

_start:



mov rax,        87        ;sys_unlink
mov rdi, fname
syscall


exit:
mov rax,        60
mov rdi,        80
syscall

section .data

fname : db "test.txt",0

but as you can see i have to declare file name . and i don't wanna do that. now my assumption is to do something with getdents64 sys_call and list files in some buffer and then unlink them. but i don't actually know how to do that. any help would be appreciated. thank you

astrogeek 05-26-2019 03:03 PM

Welcome to LQ!

Please place your code snippets inside [CODE]...[/CODE] tags for better readability. You may type those yourself or click the "#" button in the edit controls.

berndbausch 05-27-2019 12:51 AM

The asterisk in rm * is interpreted by the shell. The shell performs a directory lookup, and you are right: It's probably getdents. You will have to open the current directory and use the file descriptor thus obtained to make the call to getdents. Then loop over the getdents results and unlink the names.

The getdents man page (see link above) contains a sample C program. I will leave it up to you to turn that into assembly code.

starboy 06-02-2019 04:17 PM

pointer to a filename in linux x86_64 assembly
 
So i am trying to make a program that loops through directory, and deletes every file in it, so i am using getdents64 system call to do this. and since getdents returns number of bytes read from directory. i cannot loop through it. so i obviously need to point to the filename in a directory. but i really don't know how to do it,

this code will not work, when you run strace on it you will get this output, obiously i have put the output of a program running without a loop, you can guess what happens when i run it in a loop

strace output:
Code:

execve("./whiper", ["./whiper"], 0x7ffe7ac97400 /* 58 vars */) = 0
open("test", O_RDONLY)                  = 3
getdents64(3, /* 7 entries */, 2040)    = 224
close(3)                                = 0
unlink(0xe0)                            = -1 EFAULT (Bad address)
exit(80)                                = ?
+++ exited with 80 +++

and here is my code:

Code:

global _start

section .data

        dir : db "test",0
        len: equ 2040                ;define buffer size

section .bss
        buffer:  resb len       


section .text

_start:

       
        ;open folder
        mov rax,        2        ;sys_open
        mov rdi,        dir        ;folder to open
        mov rsi,        0        ;read only
        mov rdx,        0       
        syscall       

        cmp rax,        0      ;if there is no folder go to exit
        jbe exit
list:
        mov rdi,        rax        ;directory in rdi
        mov rax,        217        ;sys_getdents64
        mov rsi,        buffer       
        mov rdx,        len    ;length of the
        syscall
       
        xchg r10,        rax        ;save buffer in r10 to loop through it
        xor rax,        rax        ;zero out rax for the next system call
close:
        mov rax,        3        ;sys_close
        syscall
unlink:
        cmp r10,        0        ;if done, exit the program
        jbe exit   
        mov rax,        87        ;sys_unlink
        mov rdi,        r10          ;list of files
        syscall
        jmp unlink       

exit:
        mov rax,        60        ;sys_exit
        mov rdi,        80
        syscall


astrogeek 06-02-2019 06:05 PM

Please post your thread only once. Posting a single thread in the most relevant forum will make it easier for members to help you and will keep the discussion in one place. This thread is being merged with your previous thread of same subject.


All times are GMT -5. The time now is 11:20 AM.