コンパクトなハローワールド各種
Redditでこの文章を見ました:Hello from a libc-free world!,面白いと思って、前に見たいろいろな資料を思い出して、ここで整理します.すべての実験環境がLinuxであることに注意してください.
バージョン1:
実際にはアセンブリで書き換えています_start入口、具体的な説明は文章の冒頭に提供された接続を見てください.アセンブリコードは以下の通り、stubstartと命名されています.S
_start: call main movl $1, %eax xorl %ebx, %ebx int $0x80
バージョン2:
バージョン3:
char *str = "Hello world!/n"; void print() { asm( "movl $13, %%edx/n/t""movl %0, %%ecx/n/t""movl $0, %%ebx/n/t""movl $4, %%eax/n/t""int $0x80/n/t"::"r"(str):"edx","ecx","ebx"); } void exit() { asm( "movl $42,%ebx/n/t""movl $1,%eax/n/t""int $0x80/n/t"); } void nomain() { print(); exit(); }
gccインラインアセンブリについては、関連書籍を参照してください.コードは大体nomain()がエントリであることを意味し、print()関数を呼び出し、「Hello world」を印刷し、次にexit()関数を呼び出し、プロセスを終了します.ここでのprint関数はLinuxのWRITEシステム呼び出しを使用し、exitはEXITシステム呼び出しを使用し、すべてインラインアセンブリで実現します.
接続コマンドは次のとおりです.
gcc –c hello.c
ld –static –e nomain –o hello hello.o
ここではコネクタの動作を制御し、-eで入口関数をnomainと指定します.
バージョン4:
次のバージョン3では、objdumpでhelloを表示すると、4つのセグメントがあります.text .rodata .data .comment.
では、彼らを1つのセグメントに統合してもいいですか.このセグメントの属性は実行可能で、読み取り可能で、プログラムのデータと命令を含むことができますか.はい、ld接続スクリプトを使用してスクリプトhelloを作成する必要があります.ldsは次のとおりです.
ENTRY(nomain) SECTIONS { . = 0x804800 + SIZEOF_HEADERS; tinytext : { *(.text) *(.data) *(.rodata) }/DISCARD/: { *(.comment) } }
これは簡単な接続スクリプトです.現在位置0 x 804800+SIZOF_を設定します.HEADERS、後ろにtinytextセグメントが続いていて、他のセグメントはありません.インデントコマンド接続の使用
gcc –c hello.c
ld –static – T hello.lds –o hello hello.o
OK、もっとコンパクトなHelloWorldが完成しました.
バージョン5:
バージョン4は最小ですか?まだまだです...とっくに最小の実行可能ファイルを専門に研究している人がいて、ELFファイルの各バイトから始めました.ここをクリック:Size Is Everything.すごいB、すごいgeekのもの..理論的にはそれが最小の実行可能ファイルです.
以上の各バージョンのhelloworldサイズは、自分で生成してwc–c helloで見ましょう:).さらにobjdumpに合わせてもっと学べます~
参考文献には,与えられた接続のほかに,「プログラマーの自己修養」もある.
OVER、投稿は出典を明記してください
バージョン1:
実際にはアセンブリで書き換えています_start入口、具体的な説明は文章の冒頭に提供された接続を見てください.アセンブリコードは以下の通り、stubstartと命名されています.S
_start: call main movl $1, %eax xorl %ebx, %ebx int $0x80
hello.c (hello.c) 。。 :
gcc -nostdlib stubstart.S -o hello hello.c
OK, libc helloworld 。 _start
バージョン2:
, shellcode ,
typedef int (*sc_fun)(int,int,int,int,int,int,int);
void _start(void) {
char syscall[] = "/x60/x83/xc4/x24/x58/x5b/x59/x5a/x5e/x5f/x5d/xcd/x80/x83/xec/x40/x61/xc3";
((sc_fun)syscall)(4, 0, "Hello, World/n", 13, 0, 0, 0);
((sc_fun)syscall)(1, 0, 0, 0, 0, 0, 0);
}
:
gcc -o nostdlib hello.c -m32 -z execstack –nostdlib
, , -nostdlib, shellcode , write :)
バージョン3:
char *str = "Hello world!/n"; void print() { asm( "movl $13, %%edx/n/t""movl %0, %%ecx/n/t""movl $0, %%ebx/n/t""movl $4, %%eax/n/t""int $0x80/n/t"::"r"(str):"edx","ecx","ebx"); } void exit() { asm( "movl $42,%ebx/n/t""movl $1,%eax/n/t""int $0x80/n/t"); } void nomain() { print(); exit(); }
gccインラインアセンブリについては、関連書籍を参照してください.コードは大体nomain()がエントリであることを意味し、print()関数を呼び出し、「Hello world」を印刷し、次にexit()関数を呼び出し、プロセスを終了します.ここでのprint関数はLinuxのWRITEシステム呼び出しを使用し、exitはEXITシステム呼び出しを使用し、すべてインラインアセンブリで実現します.
接続コマンドは次のとおりです.
gcc –c hello.c
ld –static –e nomain –o hello hello.o
ここではコネクタの動作を制御し、-eで入口関数をnomainと指定します.
バージョン4:
次のバージョン3では、objdumpでhelloを表示すると、4つのセグメントがあります.text .rodata .data .comment.
では、彼らを1つのセグメントに統合してもいいですか.このセグメントの属性は実行可能で、読み取り可能で、プログラムのデータと命令を含むことができますか.はい、ld接続スクリプトを使用してスクリプトhelloを作成する必要があります.ldsは次のとおりです.
ENTRY(nomain) SECTIONS { . = 0x804800 + SIZEOF_HEADERS; tinytext : { *(.text) *(.data) *(.rodata) }/DISCARD/: { *(.comment) } }
これは簡単な接続スクリプトです.現在位置0 x 804800+SIZOF_を設定します.HEADERS、後ろにtinytextセグメントが続いていて、他のセグメントはありません.インデントコマンド接続の使用
gcc –c hello.c
ld –static – T hello.lds –o hello hello.o
OK、もっとコンパクトなHelloWorldが完成しました.
バージョン5:
バージョン4は最小ですか?まだまだです...とっくに最小の実行可能ファイルを専門に研究している人がいて、ELFファイルの各バイトから始めました.ここをクリック:Size Is Everything.すごいB、すごいgeekのもの..理論的にはそれが最小の実行可能ファイルです.
以上の各バージョンのhelloworldサイズは、自分で生成してwc–c helloで見ましょう:).さらにobjdumpに合わせてもっと学べます~
参考文献には,与えられた接続のほかに,「プログラマーの自己修養」もある.
OVER、投稿は出典を明記してください