我正在嘗試編寫一個程序集,用於從目錄中刪除文件的Linux程序集x86。有小費嗎?刪除Linux程序集中的一個文件x86
回答
也許是這樣的:
.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 $?
我嘗試這樣的代碼,如果來自同一 目錄中的文件調用來刪除它不會解除鏈接的文件時,它會從其他迪爾斯取消鏈接文件。 這是32位代碼,以便在64位操作系統,如果你的源文件是聯合國link.s, 你需要創建一個可執行文件:
$> as --32 -gdwarf2 un-link.s -o un-link.o
離開了-gdwarf2如果你不這樣做需要使用gdb調試器中運行, 然後用鏈接:
$> ld -m elf_i386 un-link.o -o un-link
希望它爲你工作
*我試過這段代碼,如果從與要刪除的文件相同的目錄中調用該文件,它將不會取消鏈接,它將取消與其他dirs *文件的鏈接。你的例子總是調用['unlink(「/ home/user/filename」)](http://man7.org/linux/man-pages/man2/unlink.2.html),這是絕對路徑當然,不管當前目錄是什麼,它都會執行相同的操作。如果你想讓它使用相對路徑,你可以'unlink(「filename」)'。使用'strace'來查看你正在做什麼系統調用。 –
如果你想寫一個從目錄中刪除一個文件彙編代碼,您可以使用多種方法,但我最好的方法之一s使用linux系統調用'unlink'。爲了必須使用適當的系統調用,您必須弄清楚您是否有x86系統或x86-64系統或任何其他類型的系統。我將指定如何僅使用x86/x86-64來完成此操作。
所以系統調用的工作,如Linux的以下幾點:
1.
你把一個數字對應於一個系統調用的數量,像$1
返回寄存器(EAX或RAX取決於系統)是在x86和$29
是sys_exit sys_pause,你必須確保你在%eax中得到正確的數字,否則它將不起作用。 (我覺得需要強調這一點,這個數字是系統依賴的,所以%eax中的x86系統調用號碼在x86-64系統中不會做同樣的事情)。此外,操作系統也可能會篡改這一點,我只會談論Linux,我不能說任何其他操作系統。
2.
然後您將參數插入了由系統指定了正確的寄存器,再次找到適合您的特定系統的引用,你就會知道哪些寄存器把你的論據,功能分爲(一些系統調用不需要參數,所以這一步是不必要的,爲什麼你需要一個sys_exit參數,idk)。
3.
然後最後使用系統調用讓系統知道運行特定函數(通過將數字放入%eax /%rax指定的函數)。
讓我們看看一些彙編代碼的例子,它刪除了兩個不同系統,x86和x86-64中的文件(windows有自己的方法,但我不會談論那個,儘管它確實存在)。如果我想刪除/取消鏈接存儲在地址0x7fff50的文件(讓我們說你不想指定fpath,你知道地址)
在86:
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
您可以將此文本放入一個文本文件'program.s'(我建議使用notepad/notepad ++,'.s'代表彙編代碼)並使用gcc進行編譯與$ gcc -c program.s
獲取目標代碼,並且您可以使用$ objdump -d program.o
打印並查看目標代碼和每個命令使用的十六進制密鑰有關如何查找哪個系統調用是哪個數字以及將哪個註冊表進行爭論的更多信息在,去這裏:
對於X86-64:https://filippo.io/linux-syscall-table/
即時絕對地址對於一個例子來說是一個非常奇怪的選擇。在x86-64上,函數調用約定與syscall調用約定幾乎相同,因此它可能已經在rdi中。否則,我會建議asm新手例子使用的通常的靜態存儲,所以'mov $ path_buffer,%rdi'或'mov path_pointer,%rdi' –
編輯添加更多有用的版本 –
我想你應該拿出奇怪的版本,而不是先顯示出來,然後按照正常的方式。 –
我看到很多的使用int 0x80
這個人,這是一個過時d對於大多數情況,你不應該使用它,因爲它非常緩慢,將來可能會在任何時候被刪除。您應該使用int 0x80
的唯一情況是節省空間比速度更重要或者目標平臺上不支持sysenter(Pentium 4之前的CPU)。
在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
[Linux有嚴格的不中斷用戶空間策略](http://stackoverflow.com/questions/25954270/what-does-it-mean-to-break-user-space)。除非您完全不支持32位ABI(在x86-64內核中),否則「int 0x80」將永遠消失。另外值得一提的是,32位glibc通過內核VDSO頁面使用sysenter,因此您可能希望建議調用由內核導出的sysenter包裝。 –
我認爲你在第二個塊中有一個bug:LEA放入EBP的值會被覆蓋而不被使用。 –
真的最好的建議是編寫64位代碼並使用'syscall'指令(使用不同的寄存器來傳遞參數和不同的系統調用號碼。請參閱[x86標記wiki](http://stackoverflow.com/tags/) x86/info)用於ABI文檔)。 'syscall'不需要在用戶空間和內核之間進行復雜的跳舞,這很像'int 0x80',所以對初學者來說很容易。 32位的x86大多已經過時了(特別是在沒有有效的register-args/non-x87 32位ABI的Linux上),所以我認爲編碼32位'sysenter'更像是一個「有趣的事實」比通常有用的東西。 –
- 1. 刪除程序集中的文件
- 2. Linux X86-64程序集和printf
- 3. 的Linux:刪除每個文件比一個特殊的文件
- 4. 從linux文件中刪除^ @個字符
- 5. 在Linux程序集中創建一個資源文件
- 6. VS2015從Windows程序中刪除Linux上的文件
- 7. 程序集x86 movsb
- 8. ATOI在x86 NASM Linux程序集中的問題
- 9. Linux x86-64中的日誌庫bx程序集
- 10. Linux x86引導程序
- 11. 在Linux中刪除多個文件的名稱的一部分
- 12. 從程序集中排除程序集中的文件
- 13. 使用linux刪除文件名中的第一個字
- 14. 在x86程序集中讀取文件(DOS上的NASM)
- 15. 如何從擴展名爲.bin的C程序中查看x86程序集 - Linux
- 16. 初始化yasm x86程序集中的一個結構體
- 17. 將x86轉換爲x86-64程序集
- 18. 程序文件(x86)問題
- 19. 無法刪除Linux中的文件
- 20. Linux Ubuntu中無法刪除的文件?
- 21. 從Linux上的文件中刪除com.apple.quarantine
- 22. 刪除文件與程序
- 23. Linux無法刪除文件
- 24. Linux文件刪除錯誤
- 25. 正確的用戶輸入 - x86 Linux程序集
- 26. X86機器上的程序集,Windows vs Linux
- 27. 從Linux中的多個文件中刪除文本行
- 28. x86程序集中的mov指令
- 29. 程序集x86 - 代碼
- 30. 循環x86程序集
您需要調用'unlink'系統調用,或從libc的類似命名的函數,或libc的'remove'函數。不知道爲什麼你找不到這些信息... – Jester
搜索'在Linux程序集中的系統調用'或其他一些,這很容易找到。 – teppic
或者創建一個調用'unlink'的簡單C程序,用'gcc -S'編譯它,並查看輸出。 –