以递归方式删除x64程序集中的文件

问题描述 投票:1回答:1

所以我需要使用x86_64程序集再次删除目录中的文件。这是我的代码,我知道这很糟糕。我的问题是每个系统调用都是单独工作的(我可以单独删除目录或文档),但是一旦我将它们合并在一起,它就不起作用了。 #edit:正如@fuz指出的那样,问题不够具有描述性。所以我想要它打开包含名为“test.txt”的文件的目录,删除该文件,然后删除包含该文件的目录。但是当我用nasm编译它时它就退出了程序。我正在使用Linux薄荷

global _start

section .text

_start:


;open directory
    mov rax,    2       ;sys_open
    mov rdi,    dir     ;pointer to the directory
    mov rsi,    0       ;read only
    syscall


;delete document
    mov rax,    87      ;sys_unlink
    mov rdi,    doc     ;points to the document
    syscall


;delete directory
    mov rax,    84      ;sys_rmdir
    mov rdi,    dir
    syscall


_exit:
    mov rax,    60
    mov rdi,    80
    syscall


section .data
dir: db 'test',0
doc: db 'test.txt',0
linux assembly posix x86-64 system-calls
1个回答
3
投票

你的问题不在于汇编,而在于理解基本的POSIX / Unix文件操作系统调用。 open("dir")以后不会相对于该目录进行unlink / rmdir系统调用,它们仍然相对于您当前的工作目录。你可以用chdir()改变它。

(而且使用C语言比使用asm更容易。对于大多数系统调用,glibc包装器是微不足道的,并将所有args传递给内核。当不是这种情况时,Linux手册页的NOTES部分记录了这一点。 )


系统调用相对于打开的目录文件描述符(而不是CWD)执行操作,其名称为传统的系统调用名称添加了...at后缀。该文档使用C语法来描述系统调用,但是给定ABI,它告诉您如何在asm中调用它们。

  • unlinkat(int dirfd, const char *pathname, int flags)
  • fd-relative rmdir实际上是用unlinkat(fd, path, AT_REMOVEDIR)完成的。 (否则,使用flags=0,unlinkat表现得像常规的unlink)。
  • linkatsymlinkatreadlinkatstatatmkdiratexecveat,...
  • 各种其他的,包括renameat,以及一个有趣的renameat2,它带有标志,允许你在同一个文件系统上原子地交换两个路径名。
  • notes section of the openat man page解释了为什么这些at系统调用首先存在于Rationale for openat()下 - 避免readdir和open之间的竞争条件,如果其他人renames是路径的目录组件。由于chdir()是按进程而不是每个线程,因此允许不同的线程同时在不同的目录中执行相对的操作。

就像Je​​ster所说的那样,使用strace find test -name 'test.txt' -delete或类似的东西来看看如何通过q​​azxswpoi,open(O_DIRECTORY)getdents实际递归目录。

unlinkat是在Linux上构建POSIX getdents接口的原始系统调用。手册页记录了这一点。在asm中,你可以使用对readdir的libc函数调用,或者你必须自己使用readdir


或者因为你实际上没有递归,只是硬编码一些相对路径,你可以只做getdentsunlink("test/test.txt")系统调用。

© www.soinside.com 2019 - 2024. All rights reserved.