stackoverflowというサイトは確か前回も参考にしたし、たまーに見かけるところだったんだけど、噂によると世界規模のプログラム系のFAQサイトだったようだ。今回はそこで有益な情報を見つけてようやくリベンジに成功しました。
英語は分からないけど、コードを読めばなんとかなるのがプログラムのいいところ。
どういう事かは分からないけど、出力するワードをmessageに入れていた事と、ヌルバイトを取り除く作業が不要だったらしい。
良く分からんけど動いたからいいとするか。
では順番に追いかけてみようと思います。
しばらくの間は前回のプログラムを修正しながら追っかけて進めてました。
[takeken@32bittest]$ xxd -i ./hello2 unsigned char __hello2[] = { 0x31, 0xd2, 0xb0, 0x04, 0xb9, 0x14, 0x00, 0x00, 0x00, 0xb2, 0x0d, 0xcd, 0x80, 0xb0, 0x01, 0xcd, 0x80, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a }; unsigned int __hello2_len = 33; リストファイルを作ってみる。 [takeken@32bittest]$ nasm hello2.asm -l con.list [takeken@32bittest]$ cat con.list 1 section .text 2 global _start 3 4 BITS 32 5 6 foo equ 1 7 bar equ 4 8 9 _start: 10 00000000 31D2 xor edx, edx 11 00000002 B004 mov al,bar ; write 12 00000004 B9[00000000] mov ecx, msg ; address 13 00000009 B20D mov dl, len 14 0000000B CD80 int 0x80 15 16 0000000D B001 mov al,foo ; sys_exit 17 0000000F CD80 int 0x80 18 19 section .data 20 00000000 68656C6C6F2C20776F- msg db 'hello, world',0xa 21 00000009 726C640A 22 len equ $ - msg 23
こんな風にしてずんどこずんどこ進めていたんだけど、セグメントエラーがずっと続いていた。msg db ‘hello, world’,0xa セグメントエラーについてはこれかなあと思う。
参考にしたのはこちら
Linux Shellcode “Hello, World!”
はっきり言うと答えが書いてあるんだけど、コピーしたわけじゃなくて、コードを読んで自分のを書き換えたからコピーのように見えるがコピーではないのだ。
修正したコードをdumpしたものがこちら
[takeken@32bittest]$ objdump -d hello3 [/home/takeken/nasm] hello3: file format elf32-i386 Disassembly of section .text: 08048060 <_start>: 8048060: e9 0f 00 00 00 jmp 8048074 <MESSAGE> 08048065 <GOBACK>: 8048065: 31 d2 xor %edx,%edx 8048067: b0 04 mov $0x4,%al 8048069: b3 01 mov $0x1,%bl 804806b: 59 pop %ecx 804806c: b2 0f mov $0xf,%dl 804806e: cd 80 int $0x80 8048070: b0 01 mov $0x1,%al 8048072: cd 80 int $0x80 08048074 <MESSAGE>: 8048074: e8 ec ff ff ff call 8048065 <GOBACK> 8048079: 48 dec %eax 804807a: 65 gs 804807b: 6c insb (%dx),%es:(%edi) 804807c: 6c insb (%dx),%es:(%edi) 804807d: 6f outsl %ds:(%esi),(%dx) 804807e: 2c 20 sub $0x20,%al 8048080: 57 push %edi 8048081: 6f outsl %ds:(%esi),(%dx) 8048082: 72 6c jb 80480f0 <MESSAGE+0x7c> 8048084: 64 21 0a and %ecx,%fs:(%edx)
call以下のところを表示させてみているので、こちらもやってみた。
48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0a "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a" [takeken@32bittest]$ printf "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a" Hello, World!
おおおおー! ちょっと感動です。
期待しながら実行!
[takeken@32bittest]$ ./hc [/home/takeken/nasm] ^C
帰ってこない・・・どこにいった。
あ、終了がなかった。と思い出したので
mov bh, 0
↑ のように終了をつけたした。
[takeken@32bittest]$ ./hello3 [/home/takeken/nasm] Hello, World!
実行もできた。
が
[takeken@32bittest]$ ./hc [/home/takeken/nasm] ^C
やっぱ帰ってこない!!!
もうやけくそになって、ヌルとかついてていいので(参考サイトにはヌルがある)、alやblとかちっちゃいレジスタは使わないようにしてeaxとかを使った形式に変更した。
[takeken@32bittest]$ cat hello4.asm [/home/takeken/nasm] section .text global _start BITS 32 _start: jmp MESSAGE GOBACK: xor edx, edx mov eax, 4 mov ebx, 1 pop ecx mov edx, 0xf int 0x80 mov eax, 1 mov edx, 0 int 0x80 MESSAGE: call GOBACK db "Hello, World!",0xa [takeken@32bittest]$ nasm -f elf hello3.asm && ld hello3.o -o hello3 [/home/takeken/nasm] [takeken@32bittest]$ ./hello3 [/home/takeken/nasm] Hello, World! [takeken@32bittest]$ cat hoge.c [/home/takeken/nasm] char code[] = "\xe9\x20\x00\x00\x00\x31\xd2\xb8\x04" "\x00\x00\x00\xbb\x01\x00\x00\x00\x59" "\xba\x0f\x00\x00\x00\xcd\x80\xb8\x01" "\x00\x00\x00\xba\x00\x00\x00\x00\xcd" "\x80\xe8\xdb\xff\xff\xff\x48\x65\x6c" "\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a"; int main(int argc, char **argv) { (*(void(*)())code)(); return 0; } [takeken@32bittest]$ cc -z execstack hoge.c -o hoge [/home/takeken/nasm] [takeken@32bittest]$ ./hoge [/home/takeken/nasm] Hello, World!
やっと動いてくれた。
なんだよ、これで動くのかよっていう思いもありますけど、今までのよくわからない苦労はいつの日か役に立つはず。
結構前になるけど、自作OSの本を買ってやろうかなぁと思ってたんだけど、アセンブラなんてやらんやろなと思って中止にしたんだけど。
ちょこっと見たら分かりそうだったんで、それもやっちゃおうかなぁ・・・
TCP/IP > Kernerl > アセンブラとやってアセンブラはちょっとだけよと思ってたんだけど、どうやらまだ続く・・・かもしれない。
夏ごろにPing-tにLpic303が追加される予定らしい(予定らしいってどうなのか)ので、夏にJavaとかC++とかをやっといて、夏過ぎ頃にはまたサーバーのことをやろうと思うんだけど、その通りいくのかなあ。