KENJI’S BLOG このページをアンテナに追加 RSSフィード

Freezed...

2009-03-14

MacOSXでも少しずつカーネルを触り始めてみるテスト

ぶっちゃけ全然分かりませんが、根はFreeBSDだからきっとなんとかなる。

$ cat >w.c
int main()
{
        write(1, "test", 4);
	return 0;
}
^C
$ gcc w.c
$ gdb a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct  2 04:07:49 UTC 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done

(gdb) b write
Breakpoint 1 at 0x380a4
Note: breakpoint 1 also set at pc 0x380a4.
Breakpoint 2 at 0x380a4
Breakpoint 3 at 0x29e94
warning: Multiple breakpoints were set.
Use the "delete" command to delete unwanted breakpoints.
(gdb) r
Starting program: /Users/kenji/Source/a.out 
Reading symbols for shared libraries ++. done
Breakpoint 1 at 0x91aec0a4
Breakpoint 2 at 0x91aec0a4
Breakpoint 3 at 0x91adde94

Breakpoint 1, 0x91aec0a4 in write$NOCANCEL$UNIX2003 ()
(gdb) x/4i $eip
0x91aec0a4 <write$NOCANCEL$UNIX2003>:	mov    $0xc018d,%eax
0x91aec0a9 <write$NOCANCEL$UNIX2003+5>:	call   0x91ab5cf4 <_sysenter_trap>
0x91aec0ae <write$NOCANCEL$UNIX2003+10>:	jae    0x91aec0be <write$NOCANCEL$UNIX2003+26>
0x91aec0b0 <write$NOCANCEL$UNIX2003+12>:	call   0x91aec0b5 <write$NOCANCEL$UNIX2003+17>
(gdb) si
0x91aec0a9 in write$NOCANCEL$UNIX2003 ()
(gdb) si
0x91ab5cf4 in _sysenter_trap ()
(gdb) x/4i $eip
0x91ab5cf4 <_sysenter_trap>:	pop    %edx
0x91ab5cf5 <_sysenter_trap+1>:	mov    %esp,%ecx
0x91ab5cf7 <_sysenter_trap+3>:	sysenter 
0x91ab5cf9 <_sysenter_trap+5>:	nopl   (%eax)
(gdb)

とりあえず、sysenter方式を採用してた。

MacOSXのカーネルモジュールの作り方が分からないので、検索したら、appleのサイトに詳細な解説がありました。apple自らこんなに分かりやすい解説サイトを作っているなんて、appleとても親切だ!

#include <sys/systm.h>
#include <mach/mach_types.h>

kern_return_t HelloKernel_start (kmod_info_t *ki, void *d)
{
	unsigned long addr;

	// printf("KEXT has loaded!");
	
	__asm
	{
		mov ecx, 0x176
		rdmsr
		mov addr, eax
	}
	
	printf("SYSENTER: 0x%08X", addr);
	return KERN_SUCCESS;
}


kern_return_t HelloKernel_stop (kmod_info_t *ki, void *d)
{
	printf("KEXT will be unloaded");
	return KERN_SUCCESS;
}

ビルド、実行。

/var/log/system.logを見てみると

Mar 11 02:27:27  sudo[631]:    kenji : (省略) COMMAND=/sbin/kextload -v HelloKernel.kext/
Mar 11 02:27:28  kernel[0]: SYSENTER: 0x001BCEE0

SYSENTERのとび先が結構若いアドレス(0x001BCEE0)だった。MacOSXのカーネルは低位置にあるっぽい?

トラックバック - http://d.hatena.ne.jp/kenjiaiko/20090314/1236994032