謎題:打造極小ELF文件輸出文件(使用匯編語言通過系統調用來實現)
接上文《謎題:打造極小ELF文件輸出文件(通過C語言來實現)》
在本篇中,我們要寫出一段直接通過系統調用的方式、且使用盡可能少的指令的匯編代碼來實現目標。
- 可以省略的代碼,就省略。例如,在準備系統調用的參數時,若寄存器中已有需要的內容,則無需重復賦值。
- 能使用低位寄存器,就使用低位寄存器。例如,假設
rax已經清空,賦值一個小于,就可以給al賦值,可節省相應的機器指令長度。 - 系統調用
sys_exit的返回值可以不為零。
根據以上思路,經過一番努力,我們得到了以下匯編代碼。
open.s
.section .bss
.equ bufSIZE, 65535
.lcomm buf, bufSIZE
.section .text
.globl _start
_start:
// 2 sys_open(const char *filename, int flags, int mode)
//xor %rax, %rax
mov $0x2, %al
mov 16(%rsp),%rdi;
//mov $0x0, %rsi
syscall
// 0 sys_read(unsigned int fd, char *buf, size_t count)
mov %rax, %rdi
xor %rax, %rax
mov $buf, %esi
mov $bufSIZE, %dx
syscall
// 1 sys_write(unsigned int fd, const char *buf, size_t count)
mov %rax, %rdx
xor %rax, %rax
mov $0x1, %al
xor %rdi, %rdi
mov $0x1, %dil
syscall
// 3, sys_close(unsigned int fd)
xor %rax, %rax
mov $0x3, %al
syscall
// 60, sys_exit(int error_code)
mov $0x3c, %al
//xor %rdi, %rdi
syscall
通過as命令匯編,ld命令鏈接,我們得到了64位ELF格式的可執行文件,大小952字節。
[root@i-a77ugr2f tmp]# as open.s -o open.o
[root@i-a77ugr2f tmp]# ld open.o -o open
[root@i-a77ugr2f tmp]# ll open
-rwxr-xr-x 1 root root 952 Nov 6 22:48 open
[root@i-a77ugr2f tmp]# ./open /etc/passwd
# 可以正常輸出
通過查閱資料發現,節區表對ELF可執行文件的運行是沒有任何影響的,因此可以直接刪除。這里我們使用現成的工具sstrip來實現。
# 編譯安裝sstrip
[root@i-a77ugr2f tmp]# git clone https://github.com/BR903/ELFkickers
[root@i-a77ugr2f tmp]# cd ELFkickers/sstrip/
[root@i-a77ugr2f tmp]# make
[root@i-a77ugr2f tmp]# cp sstrip /usr/bin/
# 刪除ELF可執行文件的節區表
[root@i-a77ugr2f tmp]# sstrip open
[root@i-a77ugr2f tmp]# ll open
-rwxr-xr-x 1 root root 232 Oct 19 11:15 open
[root@i-a77ugr2f tmp]# ./open /etc/passwd
# 可以正常輸出
到這里,我們獲得了一個232字節的ELF可執行文件。

浙公網安備 33010602011771號