起因如上……
额,先把平台放一下,因为有些代码设计系统架构,如果你是x86 的架构需要自己修改代码:
首先是平时调用glibc 的C 程序:
#include <stdio.h>
int
main (void) {
printf ("Hello World!\n");
return 0;
}
看一下大小,哇,足足有将近7KB:
阶段1:在平时的基础上使用strip
恩不错,还剩4K 多一点:
阶段2:不使用glibc 并且strip
哇!只剩下520B 了有木有!直接调用系统调用竟然把可执行文件的体积缩小了这么多!
.section .data
aStr: .ascii "Hello World!\n"
aStrEnd:
.section .text
.global _start
_start:
movq $1, %rdi
movq $aStr, %rsi
movq $(aStrEnd-aStr), %rdx
movq $1, %rax
syscall
movq $0, %rdi
movq $60, %rax
syscall
阶段3:克勤克俭用指令体积
我们应该尽量减少指令编译后形成机器码的体积,尽量使之最小!
哇!通过精心的挑选指令,ELF 文件体积减小到了496 B:
.section .data
aStr: .ascii "Hello World!\n"
aStrEnd:
.section .text
.global _start
_start:
movw $1, %di
movl $aStr, %esi
movb $(aStrEnd-aStr), %dl
movb $1, %al
syscall
xor %di, %di
movb $60, %al
syscall
阶段4:不再使用段
就是这样,喵,当然strip 还是要的,看看怎么样,哇,新的记录368 字节:
aStr: .ascii "Hello World!\n"
aStrEnd:
.global _start
_start:
movw $1, %di
movl $aStr, %esi
movb $(aStrEnd-aStr), %dl
movb $1, %al
syscall
xor %di, %di
movb $60, %al
syscall
阶段5:目标文件中“没用”的东西统统扔掉!
上面分别使用syscall 代替了glibc,调整了指令的大小,并且去掉了分段,接下来在这个基础上对ELF 下手吧!
先看看有用的东西(ELF 头、程序头和节头)有多少,64+56+64 = 184B:
只留下这184B,剩下的统统不要了!
最后的到了什么?瞧!一个不到200 字节的Hello World!让我们掐去脑袋,它可以给你提供……