円でエンエンエン

 

MACバイナリーだどーーーんの巻き

 

前回までのあらすじ

 

秋葉原に行った岡夫婦、MACG3用のハードディスクを安価で買い上げ、OS−Xにして岡チャン30歳に贈呈。

 

さて、相変わらずの日本語です。今回はOS−Xの環境が手に入りましたので、カーボンのコンパイル結果であるところのバイナリMach-O(マッハ・オー)のファイルレイアウトに迫ってみましょう。もうめんどくさいんで結果をどうぞ。

 

 

みんな気になるマジックナンバーはMACH時代の名残を受けたFEED FACEです。ちなみにFEED FACEというのはこういうFACEのことです。

 

 

続いて続く__PAGEZERO, __TEXT,などの大文字がセグメント名、小文字で続くのがセクション名である

http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/8rt_file_format/chapter_10_section_1.html#//apple_ref/doc/uid/20001298/BAJBDBBC

 

さて、恒例の検算のコーナーです。

http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/8rt_file_format/chapter_10_section_4.html

ここにレイアウトがあるので、それとてらしあわせて結果を見ていくことにしましょう。

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 */
};