円でエンエンエン
MACバイナリーだどーーーんの巻き
前回までのあらすじ
秋葉原に行った岡夫婦、MACG3用のハードディスクを安価で買い上げ、OS−Xにして岡チャン30歳に贈呈。
さて、相変わらずの日本語です。今回はOS−Xの環境が手に入りましたので、カーボンのコンパイル結果であるところのバイナリMach-O(マッハ・オー)のファイルレイアウトに迫ってみましょう。もうめんどくさいんで結果をどうぞ。
みんな気になるマジックナンバーはMACH時代の名残を受けたFEED FACEです。ちなみにFEED FACEというのはこういうFACEのことです。
続いて続く__PAGEZERO, __TEXT,などの大文字がセグメント名、小文字で続くのがセクション名である
さて、恒例の検算のコーナーです。
ここにレイアウトがあるので、それとてらしあわせて結果を見ていくことにしましょう。
Specifies
general attributes of the file.
struct mach_header
{
unsigned long magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
unsigned long filetype;
unsigned long ncmds;
unsigned long sizeofcmds;
unsigned long flags;
};
/* Constant for the magic field of the mach_header */
#define MH_MAGIC 0xfeedface /* the mach magic number */
#define MH_CIGAM NXSwapInt(MH_MAGIC)
Unsigned Long はよいとして、その後に続くcpu_type_t、とかcpu_subtype_tの型が意味不明である。こういう場合は次に続くSegmentのフォーマットを見てみることにしてみたりもする。
struct segment_command
{
unsigned long cmd; /* LC_SEGMENT */
unsigned long cmdsize; /* includes sizeof section structs */
char segname[16]; /* segment name */
unsigned long vmaddr; /* memory address of this segment */
unsigned long vmsize; /* memory size of this segment */
unsigned long fileoff; /* file offset of this segment */
unsigned long filesize; /* amount to map from the file */
vm_prot_t maxprot; /* maximum VM protection */
vm_prot_t initprot; /* initial VM protection */
unsigned long nsects; /* number of sections in segment */
unsigned long flags; /* flags */
};
以上のことからセグメント分として当の__PAGEZEROが登場するまでに8バイトの空間が必要であることがわかる。しかしここでもよくわからないvm_prot_tとかいう型が登場するので、さらにその下のSectionのフォーマットを見ることにした。
struct section
{
char sectname[16]; /* name of this section */
char segname[16]; /* segment this section goes in */
unsigned long addr; /* memory address of this section */
unsigned long size; /* size in bytes of this section */
unsigned long offset; /* file offset of this section */
unsigned long align; /* section alignment (power of 2) */
unsigned long reloff; /* file offset of relocation entries */
unsigned long nreloc; /* number of relocation entries */
unsigned long flags; /* flags (section type and attributes)*/
unsigned long reserved1; /* reserved */
unsigned long reserved2; /* reserved */
};
この場合はセクション名が先頭にきて次に所属するsegnameが16バイトついてくる。
この場合_PAGEZEROは特殊なセグメントらしいので、次の__TEXTセグメントを観察する。__text __TEXTとなっているところがセクションの始まりで、__TEXTとピンで書かれているのがセグメントの定義部だ。いろいろふまえて色づけしたのが上。
struct mach_header
{
unsigned long magic;0xFEEDFACE
cpu_type_t cputype;0x12
cpu_subtype_t cpusubtype;0x00
unsigned long filetype;0x02
unsigned long ncmds;0x0E
unsigned long sizeofcmds;0x06C0
unsigned long flags;0x85
};
__PAGEZEROは読みがいがないなので __TEXTを見てみる
struct segment_command
{
unsigned long cmd; /* LC_SEGMENT */ 0x01
unsigned long cmdsize; /* includes sizeof section structs */ 0x01D0
char segname[16]; /* segment name */ __TEXT
unsigned long vmaddr; /* memory address of this segment */ 0x0100
unsigned long vmsize; /* memory size of this segment */ 0x0100
unsigned long fileoff; /* file offset of this segment */ 0x0000
unsigned long filesize; /* amount to map from the file */ 0x0100
vm_prot_t maxprot; /* maximum VM protection */ 0x07
vm_prot_t initprot; /* initial VM protection */ 0x05
unsigned long nsects; /* number of sections in segment */ 0x06
unsigned long flags; /* flags */ 0x00
};
struct section
{
char sectname[16]; /* name of this section */__text
char segname[16]; /* segment this section goes in */__TEXT
unsigned long addr; /* memory address of this section */0x191C
unsigned long size; /* size in bytes of this section */0x03D8
unsigned long offset; /* file offset of this section */0x0910
unsigned long align; /* section alignment (power of 2) */0x0002
unsigned long reloff; /* file offset of relocation entries */0x0000
unsigned long nreloc; /* number of relocation entries */0x0000
unsigned long flags; /* flags (section type and attributes)*/08000400
unsigned long reserved1; /* reserved */
unsigned long reserved2; /* reserved */
};