before kernel
ftp and fetch
OpenBSDのftpは拡張されてるって事を前回知った。ならばFreeBSDの場合は? やはり、拡張されてた。横の繋がりは良好だな。でも一抹の不安があったので検証。だって説明によればftpのプロトコルそのもので通信してるっぽいからね。相手先がftp言語を話してくれないと、意思不通になると思ったのさ。
[sakae@fb /tmp]$ ftp https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz ftp: Can't lookup `https:ftp': Name does not resolve ftp: Can't connect or login to host `https:?' [sakae@fb /tmp]$ fetch https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz gforth-0.7.3.tar.gz 2464 kB 1403 kBps 01s
さもありなんと言うエラーだった。よって、FreeBSD特製のfetchを取出したよ。
vbox$ ftp https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz Trying 150.65.7.130... Requesting https://ftp.jaist.ac.jp/pub/GNU/gforth/gforth-0.7.3.tar.gz 100% |**************************************************| 2464 KB 00:00 2523433 bytes received in 0.69 seconds (3.48 MB/s)
OpenBSDの方は、何の問題もなく動いた。FreeBSDはfetchがあるから、そちらを使えって事なんだな。勿論OpenBSDには、fetchなんてコマンドは用意されていない。ftp命って事ですな。同じBSD族でも性格が違うのね。
change kernel
boot時にkernelを切り換えられると言うので、試してみる。
boot> boot hd0a:/bsd02 NOTE: random seed is being reused. booting hd0a:/bsd02: 9304599+2241540+225288+0+1126400 [97+544944+575197]=0xd60a8 entry point at 0x201000 [ using 1120776 bytes of bsd ELF symbol table ] Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. Copyright (c) 1995-2022 OpenBSD. All rights reserved. https://www.OpenBSD.org OpenBSD 7.1 (SEE) #0: Mon Oct 3 13:40:16 JST 2022 : qm$ ls -l /bsd* -rwx------ 2 root wheel 17916863 Oct 9 14:23 /bsd* ;; SEE#1 -O0 -rwx------ 2 root wheel 17916863 Oct 9 14:23 /bsd.booted* -rwx------ 1 root wheel 14998741 Oct 3 14:10 /bsd.org* ;; RELEASE -rw------- 1 root wheel 4021133 Sep 29 14:09 /bsd.rd -rwx------ 1 root wheel 12896745 Oct 3 14:09 /bsd02* ;; SEE#0 -O2
3種類のカーネルを用意した。
boot> 0 RETを叩くと、すぐに起動してしまうので注意の事。慌てずにhelpと叩くべし。 help commands: # boot echo env help hexdump ls machine reboot set stty time machine: boot comaddr diskinfo memory boot> booting hd0a:/bsd: 13912599+2241540+241672+0+1130496 [97+802512+713363]=0x122b3c entry point at 0x201000 [ using 1516508 bytes of bsd ELF symbol table ] Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. Copyright (c) 1995-2022 OpenBSD. All rights reserved. https://www.OpenBSD.org OpenBSD 7.1 (SEE) #1: Sat Oct 8 15:30:33 JST 2022
bootで使えるコマンドを試してみる。
boot> machine diskinfo Disk BIOS# Type Cyls Heads Secs Flags Checksum fd0 0x0 *none* 80 2 36 0x4 0x0 hd0 0x80 label 779 128 63 0x2 0xc26c94d7 boot> machine memory Region 0: type 1 at 0x0 for 639KB Region 1: type 2 at 0x9fc00 for 1KB Region 2: type 2 at 0xf0000 for 64KB Region 3: type 1 at 0x100000 for 64384KB Region 4: type 2 at 0x3fe0000 for 128KB Region 5: type 2 at 0xfffc0000 for 256KB Low ram: 639KB High ram: 64384KB Total free memory: 65023KB boot> ls drwxr-xr-x 0,0 512 . drwxr-xr-x 0,0 512 .. -rwx------ 0,0 17916863 bsd -rw------- 0,0 4021133 bsd.rd drwxr-xr-x 0,0 512 usr drwxr-xr-x 0,0 512 altroot drwxr-xr-x 0,0 1024 bin drwxr-xr-x 0,0 19456 dev drwxr-xr-x 0,0 1536 etc drwxr-xr-x 0,0 512 home drwxr-xr-x 0,0 512 mnt drwx------ 0,0 512 root drwxr-xr-x 0,0 1536 sbin drwxrwxrwt 0,0 512 tmp drwxr-xr-x 0,0 512 var -rw-r--r-- 0,0 578 .cshrc -rw-r--r-- 0,0 468 .profile stat(hd0a:/./sys): No such file or directory ;; sys@ -> usr/src/sys -rw-r--r-- 0,0 88304 boot -rwx------ 0,0 17916863 bsd.booted -rwx------ 0,0 14998741 bsd.org -rwx------ 0,0 12896745 bsd02
何だかbootってリナで言うgrubだな。幾つもカーネルを登録しておいて、それを切り換えて使うって発想はgrubでは余り見られないみたいだけど。せいぜい新しいカーネルを作って、それがまずい場合、古いカーネルを起動するって使いかたみたい。そんなんじゃ、もったいないぞ。
patch2
前回は変数領域にある、とある変数を見つけ出す方法をやった。今度はそれを書き換えてみよう。書き換えられたら容易に観測出来るやつを選ぶ事にする。で、目を付けたのがcopyrightな奴。起動時にさりげなく表示されるあれだ。実際に使われるのは、 init_main
の中。
ob$ nm bsd | grep copyright d101ea2c R copyright d0e41470 T dvd_read_copyright
属性がRになってるのがそれ。ReadOnlyな奴ね。
ob$ objdump -h bsd Sections: Idx Name Size VMA LMA File off Algn 2 .rodata 00220f80 d0f45000 00f45000 00d45000 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA ob$ gdb -q (gdb) p/x (0xd101ea2c - 0xd0f45000 + 0x00d45000) $1 = 0xe1ea2c
ob$ hexedit bsd Ctl-g New position ? 0xe1ea2c 00E1EA20 10 4C 29 D0 40 50 29 D0 10 51 29 D0 43 6F 70 79 .L).@P)..Q).Copy 00E1EA30 72 69 67 68 74 20 28 63 29 20 31 39 38 32 2C 20 right (c) 1982, 00E1EA40 31 39 38 36 2C 20 31 39 38 39 2C 20 31 39 39 31 1986, 1989, 1991 00E1EA50 2C 20 31 39 39 33 0A 09 54 68 65 20 52 65 67 65 , 1993..The Rege 00E1EA60 6E 74 73 20 6F 66 20 74 68 65 20 55 6E 69 76 65 nts of the Unive 00E1EA70 72 73 69 74 79 20 6F 66 20 43 61 6C 69 66 6F 72 rsity of Califor 00E1EA80 6E 69 61 2E 20 20 41 6C 6C 20 72 69 67 68 74 73 nia. All rights 00E1EA90 20 72 65 73 65 72 76 65 64 2E 0A 43 6F 70 79 72 reserved..Copyr 00E1EAA0 69 67 68 74 20 28 63 29 20 31 39 39 35 2D 32 30 ight (c) 1995-20 00E1EAB0 32 32 20 4F 70 65 6E 42 53 44 2E 20 41 6C 6C 20 22 OpenBSD. All 00E1EAC0 72 69 67 68 74 73 20 72 65 73 65 72 76 65 64 2E rights reserved. 00E1EAD0 20 20 68 74 74 70 73 3A 2F 2F 77 77 77 2E 4F 70 https://www.Op 00E1EAE0 65 6E 42 53 44 2E 6F 72 67 0A 00 CC 00 00 55 AA enBSD.org.....U.
TABして文字列領域に移動し、カーソルキーで書き換え場所を指定、書き換え、Ctl-x でファイルをセーブ。 書き変わったか確認。
ob$ strings bsd | grep 2050 : Copyright (c) 1995-2050 OpenBSD. All rights reserved. https://www.OpenBSD.org
末永くOpenBSDのプロジェクドが続くように 2022 を 2050 にさりげなく変更した。後はこのカーネルを実機に転送するだけ。書き換えたOSを起動。
[ using 1516508 bytes of bsd ELF symbol table ] Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. Copyright (c) 1995-2050 OpenBSD. All rights reserved. https://www.OpenBSD.org
バイナリーパッチ大成功。でも、これでいいのか。悪い人が勝手に改変したらどうなる? ELFエリアのチェックサムぐらいは実施して、ファイルの破損を検出して欲しいなあ。
そう言えば、boot やーいって事で楽しんできたけど、その舞台裏はどうなってるの? 少し調べてみるか。
boot OpenBSD
と言う事で、見付たのがこれ。良質な資料を見つけ出すのも技術の一つかな。
stand/mbr
起動時のメッセージの痕跡が定義されてた。
Using drive 0, partition 3.
純粋な悪石向けなんで、目が汚れるな。
stand/biosboot (pbr)
同じく悪石スタイル。必要なら、biosboot(8)を読むべし。
Loading......
stand/boot
ブート時のメッセージ担当。
probing: pc0 com0 apm pci mem[639K 62M a20=on] disk: fd0 hd0+ >> OpenBSD/i386 BOOT 3.44 :
これに呼応して、下記の痕跡を発見。ここら辺は機種依存なので、arch/i38/stand/bootとかに鎮座している。
stand/boot/conf.c
const char version[] = "3.44"; struct i386_boot_probes probe_list[] = { { "probing", i386_probe1, nitems(i386_probe1) }, { "disk", i386_probe2, nitems(i386_probe2) } };
そして、機種に依存しないコードは、/sys/stand の下。昔ながらのboot/と、新式のefi/に分れている。ここら辺まで來るとC言語になっている。
installboot
mbrにしろpbrにしろbootにしろ、カーネルは全く知らない事だ。でも、これらはDISKの中に鎮座してる必要がある。で、鎮座させる為のプログラムがinstallbootって奴だ。 下記は、それのドライラン。
qm$ installboot -nv wd0 Using / as root would install bootstrap on /dev/rwd0c using first-stage /usr/mdec/biosboot, second-stage /usr/mdec/boot would copy /usr/mdec/boot to //boot looking for superblock at 65536 found valid ffs2 superblock //boot is 6 blocks x 16384 bytes fs block shift 2; part offset 64; inode block 312, offset 12912 expecting 64-bit fs blocks (incr 4) master boot record (MBR) at sector 0 partition 3: type 0xA6 offset 64 size 6291392 /usr/mdec/biosboot will be written at sector 64
元ネタは下記にある。色々と対応してるな。
ob$ ls -l /usr/mdec/ total 1188 -r-xr-xr-x 1 root bin 126464 Apr 12 2022 BOOTIA32.EFI* -r-xr-xr-x 1 root bin 141838 Apr 12 2022 BOOTX64.EFI* -r-xr-xr-x 1 root bin 5268 Apr 12 2022 biosboot* -r-xr-xr-x 1 root bin 88136 Apr 12 2022 boot* -rw-r--r-- 1 root bin 89300 Apr 12 2022 cdboot -rw-r--r-- 1 root bin 2048 Apr 12 2022 cdbr -r-xr-xr-x 1 root bin 46712 Apr 12 2022 fdboot* -r-xr-xr-x 1 root bin 512 Apr 12 2022 mbr* -rw-r--r-- 1 root bin 98652 Apr 12 2022 pxeboot
mbrは盲腸みたいなもの。昔はbiosbootだけでやってたみたいだけど、互換性の問題で、mbrを挟むようになったらしい。 また一族にBOOTX64.EFIなんてのが伺えるので、GPTにも対応しているんだな。今は、こちらが主流か。
このinstallbootは、インストール時の最後のステップで実行されるようだ。
ob$ cd /usr/src/usr.sbin/installboot ob$ ls Makefile installboot.8 softraid.c bootstrap.c installboot.c sparc64_installboot.c efi_installboot.c installboot.h sparc64_installboot.h hppa_installboot.c landisk_installboot.c sparc64_softraid.c i386_installboot.c loongson_installboot.c stubs.c i386_installboot.h macppc_installboot.c util.c i386_nlist.c octeon_installboot.c i386_softraid.c powerpc64_installboot.c
boot FreeBSD
OpenBSDばかりでは、井の中の蛙になっちまうのでFreeBSD方面も調べて億。で、まずは登場人物を確認。 boot(8)
FILES /boot.config parameters for the boot blocks (optional) /boot/boot1 first stage bootstrap file /boot/boot2 second stage bootstrap file /boot/loader third stage bootstrap /boot/kernel/kernel default kernel /boot/kernel.old/kernel typical non-default kernel (optional)
簡単な素性調査。
[sakae@fb /boot]$ ls -l boot* loader* -r--r--r-- 1 root wheel 8192 May 19 07:03 boot -r--r--r-- 1 root wheel 512 Apr 9 2021 boot0 -r--r--r-- 1 root wheel 512 Apr 9 2021 boot0sio -r--r--r-- 1 root wheel 512 May 19 07:03 boot1 -r-xr-xr-x 1 root wheel 125440 May 19 07:03 boot1.efi* -r--r--r-- 1 root wheel 7680 May 19 07:03 boot2 -r-xr-xr-x 3 root wheel 495616 Sep 4 05:47 loader* -r--r--r-- 1 root wheel 7812 Apr 9 2021 loader.4th -rw-r--r-- 1 root wheel 55 Sep 15 06:58 loader.conf -r-xr-xr-x 2 root wheel 824832 Sep 4 05:47 loader.efi* -r--r--r-- 1 root wheel 394 Apr 9 2021 loader.rc -r-xr-xr-x 1 root wheel 434176 Sep 4 05:47 loader_4th* -r-xr-xr-x 1 root wheel 750592 Sep 4 05:47 loader_4th.efi* -r-xr-xr-x 3 root wheel 495616 Sep 4 05:47 loader_lua* -r-xr-xr-x 2 root wheel 824832 Sep 4 05:47 loader_lua.efi* -r-xr-xr-x 1 root wheel 372736 Sep 4 05:47 loader_simp* -r-xr-xr-x 1 root wheel 690688 Sep 4 05:47 loader_simp.efi*
boot0ってのは多分mbrだろう。loader.4thなんてのがきになる。 loader(8)
NAME loader – kernel bootstrapping final stage DESCRIPTION The program called loader is the final stage of FreeBSD's kernel bootstrapping process. On IA32 (i386) architectures, it is a BTX client. It is linked statically to libstand(3) and usually located in the directory /boot. :
フォースの力だけじゃなくて、月の力も利用出来るとな。深入りすると、NHKの沼にはまってから出演依頼が來そうなので止めておく。あそこに出て来るゲストはU20ぐらいの人達だからね。まあ、年寄は呼ばれる事無から安心しろ。