Покрай един курс във ФМИ се зарибих да видя докъде мога да орежа изпълнимия файл на проста програмка като Hello World на езика C. Написах следния сорс:
GeSHi (C):
#include<stdio.h>
int main()
{
return 0;
}
Компилирах с
GeSHi (Bash):
gcc hello1.c -Os -o hello
и се получи следния резултат
GeSHi (Bash):
progrock ~/Programming/tests $ ls -l hello
-rwxr-xr-x 1 progrock users 4646 12 авг 9,43 hello
progrock ~/Programming/tests $ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
Ползвах strip и
GeSHi (Bash):
progrock ~/Programming/tests $ strip -R .note -R .comment hello
progrock ~/Programming/tests $ ls -l hello
-rwxr-xr-x 1 progrock users 2688 12 авг 9,56 hello
Размерът на изпълнимия файл намаля с близо 2000 байта, но все пак 2688 байта за програма от 72 байта ми се видя доста. Инсталирах си dietlibc и промених малко сорса като използвах системния примитив write:
GeSHi (C):
#include<unistd.h>
int main()
{
write(1,"Hello World!\n",13);
return 0;
}
След същата процедура се получи абсолютно същия размер - 2688 байта.
Но след:
GeSHi (Bash):
progrock ~/Programming/tests $ diet -Os gcc -Os hello2.c -o hello
progrock ~/Programming/tests $ strip -R .note -R .comment hello
се получи
GeSHi (Bash):
progrock ~/Programming/tests $ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
progrock ~/Programming/tests $ ls -l hello
-rwxr-xr-x 1 progrock users 1020 12 авг 10,04 hello
Обърнете внимание на statically linked - статично компилирано с glibc се получава над 500KB ::)
Тестовете бяха проведени с GCC 4.4.1, dietlibc 0.32, glibc 2.10.1
Ако някой получи по-добри резултати да си каже :) (чувал съм, че може да се получи към 500-600 байта статично binary на подобна програма на C)
[root@localhost tmp]# cat tst.c
void __libc_csu_init(){}
void __libc_csu_fini(){}
void __libc_start_main()
{
char *hello="Hello world\n";
asm ("mov $0x04, %%eax\n"
"mov %0, %%ecx\n"
"mov $0x1,%%ebx\n"
"mov $13, %%edx\n"
"int $0x80;"
"mov $0x1, %%eax\n"
"int $0x80"
:
: "r"(hello)
: "eax", "ecx", "ebx", "edx", "eax"
);
}
void main(){
};
[root@localhost tmp]# strip -R .init ./tst
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1824 2009-08-12 18:32 ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]# strip -R .strtab -R .symtab -R .bss -R .comment ./tst
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1460 2009-08-12 18:32 ./tst
[root@localhost tmp]# strip -R .data -R .got -R .got.plt -R .jcr ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 1248 2009-08-12 18:33 ./tst
[root@localhost tmp]# strip -R .dtors -R .ctors -R .eh_frame -R .fini ./tst
BFD: ./tst: warning: Empty loadable segment detected, is this intentional ?
[root@localhost tmp]# readelf ./tst -S
There are 6 section headers, starting at offset 0x31c:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .note.ABI-tag NOTE 080480b4 0000b4 000020 00 A 0 0 4
[ 2] .note.gnu.build-i NOTE 080480d4 0000d4 000024 00 A 0 0 4
[ 3] .text PROGBITS 08048130 000130 00017c 00 AX 0 0 16
[ 4] .rodata PROGBITS 080482c8 0002c8 000019 00 A 0 0 4
[ 5] .shstrtab STRTAB 00000000 0002e1 00003a 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
[root@localhost tmp]# strip -R .note.ABI-tag -R .shstrtab ./tst
BFD: ./tst: warning: Empty loadable segment detected, is this intentional ?
[root@localhost tmp]# ls -l ./tst
-rwxr-xr-x 1 root root 984 2009-08-12 18:34 ./tst
[root@localhost tmp]# ./tst
Hello world
[root@localhost tmp]#
984 байта, ама това е голяма клизма. С малко inline assembly, с моя си инициализация и без финализиращ код. Въпреки което както се вижда работи :)
Благодаря за опциите на strip [_]3
GeSHi (Bash):
progrock ~/Programming/tests $ strip -R .data -R .got -R .got.plt hello
progrock ~/Programming/tests $ ./hello
Hello World!
progrock ~/Programming/tests $ ls -l hello
-rwxr-xr-x 1 progrock users 964 12 авг 20,01 hello
964 байта. Според мен може и още ;D
Това ми напомня за Еволюцията на програмиста. http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html ($2)