Tuesday, March 2, 2010

Hello World - 讓code size小於512 byts

上一篇中,code size已經縮小到536 bytes。其反組譯的內容為...

$ objdump -S hello2

hello2: file format elf32-i386


Disassembly of section .text:

08048094 <.text>:
8048094: 55 push %ebp
8048095: 89 e5 mov %esp,%ebp
8048097: ba 0e 00 00 00 mov $0xe,%edx
804809c: 8b 0d c8 90 04 08 mov 0x80490c8,%ecx
80480a2: bb 01 00 00 00 mov $0x1,%ebx
80480a7: b8 04 00 00 00 mov $0x4,%eax
80480ac: cd 80 int $0x80
80480ae: 31 db xor %ebx,%ebx
80480b0: b8 01 00 00 00 mov $0x1,%eax
80480b5: cd 80 int $0x80
80480b7: 5d pop %ebp
80480b8: c3 ret
$


這裡有一點需注意...由於編譯、執行時沒有將正確的stack建立,所以_start() function雖然有做stack的動作,但一不小心還是會造成stack錯誤,所以_start中只有push後並沒有做額外的stack存取。
另外...因為int 0x80(eax<1)為程式的結束點,所以可以不需要做return動作。至此...

$ gcc -nostartfiles -nostdlib -static hello2.c -o hello2
$ strip hello2
$ ./hello2
Hello World
$ ls -l hello2
-rwxr-xr-x 1 lungswu lungswu 528 2010-03-01 10:08 hello2
$ $

縮小為528 byte。


再過來...我們觀察編譯後的執行檔結構...

$ objdump -h hello2

hello2: file format elf32-i386

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000025 08048094 08048094 00000094 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 0000000d 080480b9 080480b9 000000b9 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .data 00000004 080490c8 080490c8 000000c8 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .comment 0000002a 00000000 00000000 000000cc 2**0
CONTENTS, READONLY

裡面有一個.comment 的section,其內容為...

$ objdump -s hello2

hello2: file format elf32-i386

Contents of section .text:
8048094 5589e5ba 0e000000 8b0dc890 0408bb01 U...............
80480a4 000000b8 04000000 cd8031db b8010000 ..........1.....
80480b4 00cd805d c3 ...].
Contents of section .rodata:
80480b9 48656c6c 6f20576f 726c640a 00 Hello World..
Contents of section .data:
80490c8 b9800408 ....
Contents of section .comment:
0000 00474343 3a202847 4e552920 332e342e .GCC: (GNU) 3.4.
0010 36202855 62756e74 7520332e 342e362d 6 (Ubuntu 3.4.6-
0020 38756275 6e747532 2900 8ubuntu2).

它是gcc編譯後的額外資料,是否可以將它移除???

答案是肯定的,GNU Binary utility中有一個命令...objcopy...它可以做一些object file(ELF)檔案的處理...

$ man objcopy
OBJCOPY(1) GNU Development Tools OBJCOPY(1)

NAME
objcopy - copy and translate object files

SYNOPSIS
.... 省略 ....
--remove-section=sectionname
Remove any section named sectionname from the output file. This option may be
given more than once. Note that using this option inappropriately may make the
output file unusable.
"--remove-section"這個參數正可以用上...

$ ls -l hello2
-rwxr-xr-x 1 lungswu lungswu 528 2010-03-01 10:08 hello2
$
$ objcopy --remove-section=.comment hello2 hello2.1
$
$ ./hello2.1
Hello World
$ ls -l hello2.1
-rwxr-xr-x 1 lungswu lungswu 436 2010-03-01 10:15 hello2.1
$

所以已經達到初步的目標,Hello world的code size已經小於512 byte,達到436 bytes.

No comments:

Post a Comment