删除Linux程序集x86

时间:2017-03-17 20:03:11

标签: linux assembly x86 unlink

我编写此代码,如果从与要删除的文件相同的目录调用文件,它将不会取消链接文件,它将取消链接其他目录中的文件

.section .data
fpath:
    .asciz "/home/user/filename"  # path to file to delete

.section .text
.globl _start
_start:
movl $10, %eax       # unlink syscall 
movl $fpath, %ebx    # path to file to delete
int  $0x80 

movl %eax, %ebx      # put syscall ret value in ebx
movl $1, %eax        # exit syscall
int  $0x80

我想要的是取消所有文件(包括其自身)在其运行目录中的链接。

1 个答案:

答案 0 :(得分:1)

您需要以递归方式删除目录内容,然后才能删除目录本身。以下是C语言,但不使用标准库函数,只使用syscalls:

#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <dirent.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
struct linux_dirent64 {
    ino64_t d_ino;
    off64_t d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[];
};
static void rmrf(int dfd, const char *name) {
    unsigned char buffer[16384];
    struct linux_dirent64 *dirent;
    int fd, off, size;
    fd = syscall(SYS_openat, dfd, name, O_RDONLY | O_DIRECTORY);
    if (fd == -1) {
        syscall(SYS_exit, 1);
    }
    do {
        size = syscall(SYS_getdents64, fd, buffer, sizeof(buffer));
        if (size < 0) {
            syscall(SYS_exit, 1);
        }
        for (off = 0; off < size; off += dirent->d_reclen) {
            dirent = (struct linux_dirent64 *)&buffer[off];
            if (dirent->d_name[0] == '.' &&
                (dirent->d_name[1] == '\0' ||
                 (dirent->d_name[1] == '.' &&
                  (dirent->d_name[2] == '\0')))) {
                continue;
            }
            if (dirent->d_type != DT_DIR) {
                if (!syscall(SYS_unlinkat, fd, dirent->d_name, 0)) {
                    continue;
                }
                if (dirent->d_type != DT_UNKNOWN) {
                    syscall(SYS_exit, 1);
                }
            }
            rmrf(fd, dirent->d_name);
        }
    } while (off);
    syscall(SYS_close, fd);
    if (syscall(SYS_unlinkat, dfd, name, AT_REMOVEDIR)) {
        syscall(SYS_exit, -1);
    }
}
int main() {
    const char fpath[] = "/home/user/filename";
    if (syscall(SYS_unlink, fpath)) {
        rmrf(0, fpath);
    }
    syscall(SYS_exit, 0);
}