谜题:打造极小ELF文件输出文件(使用汇编语言通过系统调用来实现)

接上文《谜题:打造极小ELF文件输出文件(通过C语言来实现)》

在本篇中,我们要写出一段直接通过系统调用的方式、且使用尽可能少的指令的汇编代码来实现目标。

  1. 可以省略的代码,就省略。例如,在准备系统调用的参数时,若寄存器中已有需要的内容,则无需重复赋值。
  2. 能使用低位寄存器,就使用低位寄存器。例如,假设rax已经清空,赋值一个小于,就可以给al赋值,可节省相应的机器指令长度。
  3. 系统调用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可执行文件。

posted @ 2022-11-08 00:52  Cathon  阅读(125)  评论(0编辑  收藏  举报