30 Jun 2007
冲刺ELF极限——最小ELF程序
tinyso1.S:
; 最近研究ELF格式,hack了一把。 ; 参考文档: ; 1。 ELF_format.pdf http://www.skyfree.org/linux/references/ELF_Format.pdf ; 2。A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux ; http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html ; 各文件: ;;; ************************************************** ; tinyso1.S ;;; ************************************************** .global _start _start: xor %eax, %eax inc %eax movw $filesize,%bx int $0x80 .equ filesize, . - _start ;;; ************************************************** ; tinyso2.S ;;; ************************************************** /* ELF Header */ ehdr: /* e_ident */ .byte 0x7F,'E,'L,'F .byte 1 # EI_CLASS : ELFCLASS32 .byte 1 # EI_DATA : ELFDATA2LSB .byte 1 # EI_VERSION .rept 9 .byte 0 .endr .word 2 # e_type : ET_EXEC .word 3 # e_machine : EM_386 .int 1 # e_version .int _start # e_entry .int phdr_off # e_phoff .int 0 # e_shoff .int 0 # e_flags .word ehdrsize # e_ehsize .word phdrsize # e_phentsize .word 1 # e_phnum .word 0 # e_shentsize .word 0 # e_shnum .word 0 # e_shstrndx .equ ehdrsize, . - ehdr /* Program Headher */ .equ phdr_off, . - ehdr phdr: .int 1 # p_type : PT_LOAD .int 0 # p_offset .int ehdr # p_vaddr .int ehdr # p_paddr (ignored) .int filesize # p_filesz .int filesize # p_memsz .int 5 # p_flags : r-x .int 0x1000 # p_align .equ phdrsize, . - phdr /* Code */ .global _start _start: xor %eax,%eax inc %eax movw $filesize,%bx int $0x80 .equ filesize, . - ehdr ;;; ************************************************** ; tinyso3.S ;;; ************************************************** /* ELF Header 16 bytes, with embed CODE into preserved area */ ehdr: /* e_ident */ .byte 0x7F,'E,'L,'F .byte 1 # EI_CLASS : ELFCLASS32 .byte 1 # EI_DATA : ELFDATA2LSB .byte 1 # EI_VERSION .global _start /* * <HACK> 1: embed CODE into preserved area * exactly, 9 bytes! */ _start: xor %eax,%eax # 2 bytes inc %eax # 1 bytes movw $filesize,%bx # 4 bytes int $0x80 # 2 bytes .word 2 # e_type : ET_EXEC .word 3 # e_machine : EM_386 .int 1 # e_version .int _start # e_entry .int phdr_off # e_phoff .int 0 # e_shoff .int 0 # e_flags .word ehdrsize # e_ehsize .word phdrsize # e_phentsize /* Program Headher */ .equ phdr_off, . - ehdr phdr: /* * <HACK> 2 : overlap two section * .word 1 # e_phnum * .word 0 # e_shentsize * .word 0 # e_shnum * .word 0 # e_shstrndx */ .int 1 # p_type : PT_LOAD .int 0 # p_offset .equ ehdrsize, . - ehdr .int ehdr # p_vaddr .int ehdr # p_paddr (ignored) .int filesize # p_filesz .int filesize # p_memsz .int 5 # p_flags : r-x .int 0x1000 # p_align .equ phdrsize, . - phdr .equ filesize, . - ehdr
Makefile:
all:tinyso1 tinyso2 tinyso3 tinyso1: tinyso1.S @echo ---------- $@ -------------- gcc -nostdlib $< -o $@ strip -s $@ wc -c $@ @echo --------------------------------- tinyso2: tinyso2.S @echo ----------- $@ --------------- gcc -c $< ld tinyso2.o --oformat binary -o $@ @echo --------------------------------- tinyso3: tinyso3.S @echo ----------- $@ ---------------- gcc -c $< ld tinyso3.o --oformat binary -o $@ @echo --------------------------------- clean: rm -f *.o tinyso1 tinyso2 tinyso3
效果:
hellwolf@cocteau#pts/9%J0S2:tinyso$wc -c tinyso? 264 tinyso1 93 tinyso2 76 tinyso3 433 total hellwolf@cocteau#pts/9%J0S2:tinyso$for i in $(seq 1 3);do ./tinyso$i;echo $?;done 9 93 76 hellwolf@cocteau#pts/9%J0S2:tinyso$
文档2中还有更hack的手法,能压缩到42个字节, lol