在Linux程序集x86中删除文件

时间:2015-04-07 01:16:53

标签: linux assembly x86 delete-file

我正在尝试编写用于Linux程序集x86的汇编程序,该程序从目录中删除文件。有什么提示吗?

3 个答案:

答案 0 :(得分:2)

可能是这样的:

    .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

然后检查命令行的返回值,0表示成功。

    $>echo $?

我尝试了这个代码,如果从同一个文件中调用它,它就不会取消链接 目录作为要删除的文件,它将取消链接其他目录中的文件。 如果您的源文件是un-link.s,这是32位代码,因此在64位操作系统上, 您需要使用以下命令创建可执行文件:

    $> as --32 -gdwarf2 un-link.s -o un-link.o

如果您不需要使用gdb调试器运行它,请忽略-gdwarf2, 然后链接:

    $> ld -m elf_i386 un-link.o -o un-link

希望它适合你

答案 1 :(得分:2)

我看到很多人使用int 0x80这个,这是不推荐的,对于大多数情况,你不应该使用它,因为它非常慢,并且可能在将来的任何时候被删除。您应该使用int 0x80的唯一情况是节省空间比速度更重要或者目标平台(Pentium 4 CPU之前)不支持sysenter的情况。

在x86 Linux中,系统调用的工作方式是在eax中使用syscall代码,在连续的寄存器,ebx,ecx等中使用它的任何参数。系统调用的返回值将放在eax中。

mov eax, 0xa ;0xa is the 'unlink' syscall, which removes a file
mov ebx, <location in memory of a null terminated string containing a path>
push <LABEL TO JUMP TO AFTER SYSENTER IS COMPLETE>
push ecx
push edx
push ebp
mov ebp, esp
sysenter

如果你不关心你的寄存器在系统调用完成后被垃圾填满(例如在你将要立即覆盖这些寄存器的内容的情况下),你可以使用这个技巧来保存一些空间和速度一点点:

mov eax, 0xa ;0xa is the 'unlink' syscall, which removes a file
mov ebx, <location in memory of a null terminated string containing a path>
push <LABEL TO JUMP TO AFTER SYSENTER IS COMPLETE>
lea ebp, [esp-12]
sysenter

答案 2 :(得分:0)

如果要编写从目录中删除文件的汇编代码,可以使用多种方法,但最好的方法之一是使用linux systemcall&#39; unlink&#39;。为了必须使用正确的系统调用,您必须弄清楚您是否拥有x86系统,x86-64系统或任何其他类型的系统。我将仅使用x86 / x86-64指定如何执行此操作。

所以系统调用在linux中的工作方式如下:
1. 您将一个数字放入与系统调用号对应的返回寄存器(eax或rax,具体取决于系统),如$1是x86上的sys_exit而$29是sys_pause,您必须进行编号确保你在%eax中得到正确的号码或者它不会工作。 (我觉得有必要强调一下,这个数字是系统相关的,所以%eax中的x86系统调用号在x86-64系统中不会做同样的事情)。此外,操作系统也可能会篡改此操作,我只会谈论Linux,我不能代表任何其他操作系统。

2。
然后将参数移动到由SYSTEM指定的适当寄存器中,再次找到特定系统的引用,并且您将知道将函数的参数放入哪些寄存器(某些系统调用不需要参数,所以这一步是不必要的,为什么你需要一个sys_exit,idk的参数。

3.
然后最后你使用syscall为你的系统让系统知道运行一个特定的函数(你通过将数字放入%eax /%rax中指定的函数)。

让我们看一下删除两个不同系统中的文件的一些汇编代码的示例,x86和x86-64(windows有自己的方法,但我不会谈论那个,尽管它确实存在)。如果我想删除/取消链接存储在地址0x7fff50的文件(让我们说你不想指定fpath而你知道地址)

在x86中:

movl $10, %eax        # defines which systemcall we are using (10th)
movl $0x7fff50, %ebx  # moves the address of file we want to delete into %ebx (this is where the argument of sys_unlink(x86) is stored)
int  $0x80            # equivalent of syscall that starts the appropriate function

在x86-64中:

movq $87, %rax        # defines which systemcall we are using (87th)
movq $0x7fff50, %rdi  # moves the address of file we want to delete into %rdi (this is where the argument of sys_unlink(x86-64) is stored)
syscall               # starts the appropriate function


如果你更像一个普通人并且不知道你想要删除的文件的绝对地址,我们有一种简单的方法来编写文件本身的相对地址,就像这样(从另一个答案中复制) )
    .section .data
    fpath:
        .asciz "/home/user/filename" # path to file to delete


那么系统本身将找出文件的绝对路径(类似7fff34fb)的位置,并在编译程序集时将其移动到寄存器中。可能看起来像这样

在x86-64中:

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

.section .text
.globl _start
_start:
movq $87, %rax        # defines which systemcall we are using (87th)
movq $fpath, %rdi     # moves the address of file we want to delete into %rdi
                      # (this is where the argument of sys_unlink(x86-64) is stored)
syscall               # starts the appropriate function


您可以通过查看%eax寄存器来访问函数的输出(通常为0表示成功,1表示失败状态)。在每个系统调用之后,在%eax中返回一个整数
您可以将此文本放入文本文件&#39; program.s&#39; (我建议使用notepad / notepad ++,&#39; .s代表汇编代码)并使用带有$ gcc -c program.s的gcc编译它以获取目标代码,然后您可以打印并查看目标代码以及使用$ objdump -d program.o的每个命令所涉及的十六进制密钥 有关如何查找哪个系统调用是哪个号码以及将哪些注册到哪个注册表的更多信息,请转到此处:

对于x86-64:https://filippo.io/linux-syscall-table/