從macho中解析類名

1什么是macho

2 macho總體描述

3以查詢一個類名為例,說明查找過程

1什么是macho

macho是mac os, ios可執(zhí)行文件格式,類似windows上的pe和linux上的elf滤祖。macho是源碼通過編譯連接產(chǎn)生。

2 macho總體描述

先用文本打開慧邮,來個感官認(rèn)識下,如下圖:


macho也是文件,只不過組織結(jié)構(gòu)文本查看器不能解析鳍鸵。

下面整體看下macho的結(jié)構(gòu)。

文件的開始32個Byte是頭部,頭部包含的信息中包含要加載的指令條數(shù)草讶。

接下來是要加載的指令祭椰。

這些指令以段(Segment)分為多個泥张。

有的段又分為多個區(qū)(Section)莹痢。

上面的Section只是索引种蘸,包含該section在整個文件中的位置和大小,如果要查看section具體的數(shù)據(jù)竞膳,就要通過偏移位置和大小去查找航瞭。

下面是基本結(jié)構(gòu)圖:


接下來具體講解下每部分的含義。

要參考loader.h(/usr/include/mach-o/loader.h或者https://opensource.apple.com/source/xnu/xnu-1456.1.26/EXTERNAL_HEADERS/mach-o/loader.h)

前32Byte可以轉(zhuǎn)換為一個結(jié)構(gòu)體表示坦辟。結(jié)構(gòu)體的定義如下刊侯。

/*

* The 32-bit mach header appears at the very beginning of the object file for

* 32-bit architectures.

*/

struct mach_header {

uint32_tmagic;/* mach magic number identifier */

cpu_type_tcputype;/* cpu specifier */

cpu_subtype_tcpusubtype;/* machine specifier */

uint32_tfiletype;/* type of file */

uint32_tncmds;/* number of load commands */

uint32_tsizeofcmds;/* the size of all the load commands */

uint32_tflags;/* flags */

};

/*

* The 64-bit mach header appears at the very beginning of object files for

* 64-bit architectures.

*/

struct mach_header_64 {

uint32_tmagic;/* mach magic number identifier */

cpu_type_tcputype;/* cpu specifier */

cpu_subtype_tcpusubtype;/* machine specifier */

uint32_tfiletype;/* type of file */

uint32_tncmds;/* number of load commands */

uint32_tsizeofcmds;/* the size of all the load commands */

uint32_tflags;/* flags */

uint32_treserved;/* reserved */

};

2.1.1魔數(shù)標(biāo)識macho文件是多少位的,是不是fat格式(多個架構(gòu)合并),是不是小端序

前4byte為魔數(shù)锉走,根據(jù)魔數(shù)可以判斷macho是32位還是64位,還記錄著是大端序或小端序

#defineMH_MAGIC0xfeedface/* the mach magic number */32

#defineMH_CIGAM0xcefaedfe/* NXSwapInt(MH_MAGIC) */32,解析需要轉(zhuǎn)換成小端序

#defineMH_MAGIC_640xfeedfacf/* the 64-bit mach magic number */64

#defineMH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */64位解析需要轉(zhuǎn)換成小端序

其中0xCAFEBABE為多個架構(gòu)的mach-o

2.1.2 cpu類型滨彻,標(biāo)識該macho需要在哪些類型的cpu上運行

cputype如下,


cputype和cpusubtype具體含義查看頭文件machine.h

2.1.3文件類型filetype標(biāo)識文件的類型挪蹭,是可執(zhí)行文件還是其他類型的文件

部分類型說明如下:詳細的說明參考文件loader.h


2.1.4 flags標(biāo)識macho的一些特性亭饵,比如是否包含未定義的引用,如果是鏡像是否有二級命名空間綁定。

部分定義見下面嚣潜,詳細的定義參考loader.h


2.1.5加載命令的信息ncmdssizeofcmds,依據(jù)這些信息來解析加載命令

ncmds是加載命令的個數(shù)冬骚。sizeofcmds是加載命令索引的大小椅贱。

2.2解析加載命令

2.2.1每一個加載命令至少還有兩個元素,第一個是類型,第二個是大小

具體下面結(jié)構(gòu)體

struct load_command {

uint32_t cmd;/* type of load command */

uint32_t cmdsize;/* total size of command in bytes */

};

cmd懂算,加載命令的類型定義如下(其中動態(tài)庫的定義看文件loader.h)

/* Constants for the cmd field of all load commands, the type */

#defineLC_SEGMENT0x1/* segment of this file to be mapped */

#defineLC_SYMTAB0x2/* link-edit stab symbol table info */

#defineLC_SYMSEG0x3/* link-edit gdb symbol table info (obsolete) */

#defineLC_THREAD0x4/* thread */

#defineLC_UNIXTHREAD0x5/* unix thread (includes a stack) */

#defineLC_LOADFVMLIB0x6/* load a specified fixed VM shared library */

#defineLC_IDFVMLIB0x7/* fixed VM shared library identification */

#defineLC_IDENT0x8/* object identification info (obsolete) */

#define LC_FVMFILE0x9/* fixed VM file inclusion (internal use) */

#define LC_PREPAGE0xa/* prepage command (internal use) */

#defineLC_DYSYMTAB0xb/* dynamic link-edit symbol table info */

#defineLC_LOAD_DYLIB0xc/* load a dynamically linked shared library */

#defineLC_ID_DYLIB0xd/* dynamically linked shared lib ident */

#define LC_LOAD_DYLINKER 0xe/* load a dynamic linker */

#define LC_ID_DYLINKER0xf/* dynamic linker identification */

#defineLC_PREBOUND_DYLIB 0x10/* modules prebound for a dynamically */

/*linked shared library */

#defineLC_ROUTINES0x11/* image routines */

#defineLC_SUB_FRAMEWORK 0x12/* sub framework */

#defineLC_SUB_UMBRELLA 0x13/* sub umbrella */

#defineLC_SUB_CLIENT0x14/* sub client */

#defineLC_SUB_LIBRARY0x15/* sub library */

#defineLC_TWOLEVEL_HINTS 0x16/* two-level namespace lookup hints */

#defineLC_PREBIND_CKSUM0x17/* prebind checksum */

cmdsize包含改命令中的所有內(nèi)容的大小,比如segment中的section。

其中常見的加載命令解釋看下圖:



2.2.2

解析一個

segment

Segment的定義看下面的結(jié)構(gòu)體

struct segment_command { /* for 32-bit architectures */

uint32_tcmd;/* LC_SEGMENT */

uint32_tcmdsize;/* includes sizeof section structs */

charsegname[16];/* segment name */

uint32_tvmaddr;/* memory address of this segment */

uint32_tvmsize;/* memory size of this segment */

uint32_tfileoff;/* file offset of this segment */

uint32_tfilesize;/* amount to map from the file */

vm_prot_tmaxprot;/* maximum VM protection */

vm_prot_tinitprot;/* initial VM protection */

uint32_tnsects;/* number of sections in segment */

uint32_tflags;/* flags */

};

/*

* The 64-bit segment load command indicates that a part of this file is to be

* mapped into a 64-bit task's address space.If the 64-bit segment has

* sections then section_64 structures directly follow the 64-bit segment

* command and their size is reflected in cmdsize.

*/

struct segment_command_64 { /* for 64-bit architectures */

uint32_tcmd;/* LC_SEGMENT_64 */

uint32_tcmdsize;/* includes sizeof section_64 structs */

charsegname[16];/* segment name */

uint64_tvmaddr;/* memory address of this segment */

uint64_tvmsize;/* memory size of this segment */

uint64_tfileoff;/* file offset of this segment */

uint64_tfilesize;/* amount to map from the file */

vm_prot_tmaxprot;/* maximum VM protection */

vm_prot_tinitprot;/* initial VM protection */

uint32_tnsects;/* number of sections in segment */

uint32_tflags;/* flags */

};

segname:是該段的名字,占用16個byte庇麦。

vmaddr:該段所在內(nèi)存的開始虛擬地址。64位虛擬地址的起始值是0x100000000,32位0x4000

fileoff:該段從macho文件開始位置的偏移值,從0開始計算

vmsize:該段占用虛擬內(nèi)存的大小

filesize:該段占用文件中的大小,和vmsize相等。

nsects:該段中包含的區(qū)的個數(shù)欧引。

2.2.3解析一個區(qū)

其中一個區(qū)的定義如下:

struct section { /* for 32-bit architectures */

charsectname[16];/* name of this section */

charsegname[16];/* segment this section goes in */

uint32_taddr;/* memory address of this section */

uint32_tsize;/* size in bytes of this section */

uint32_toffset;/* file offset of this section */

uint32_talign;/* section alignment (power of 2) */

uint32_treloff;/* file offset of relocation entries */

uint32_tnreloc;/* number of relocation entries */

uint32_tflags;/* flags (section type and attributes)*/

uint32_treserved1;/* reserved (for offset or index) */

uint32_treserved2;/* reserved (for count or sizeof) */

};

struct section_64 { /* for 64-bit architectures */

charsectname[16];/* name of this section */

charsegname[16];/* segment this section goes in */

uint64_taddr;/* memory address of this section */

uint64_tsize;/* size in bytes of this section */

uint32_toffset;/* file offset of this section */

uint32_talign;/* section alignment (power of 2) */

uint32_treloff;/* file offset of relocation entries */

uint32_tnreloc;/* number of relocation entries */

uint32_tflags;/* flags (section type and attributes)*/

uint32_treserved1;/* reserved (for offset or index) */

uint32_treserved2;/* reserved (for count or sizeof) */

uint32_treserved3;/* reserved */

};

flag標(biāo)識section的一些特性听系,部分定義看下面

#define S_NON_LAZY_SYMBOL_POINTERS 0x6/* section with only non-lazy symbol pointers */

#define S_LAZY_SYMBOL_POINTERS 0x7/* section with only lazy symbolpointers */

#define S_SYMBOL_STUBS0x8/* section with only symbol stubs, byte size of stub in

the reserved2 field */

#define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function pointers for

initialization*/

#define S_MOD_TERM_FUNC_POINTERS0xa/* section with only function pointers for termination*/

#define S_COALESCED0xb/* section contains symbols that are to be coalesced */

#define S_GB_ZEROFILL0xc/* zero fill on demand section

常見的區(qū)的解釋見下圖



3

解析類名

需要用的工具有MachoViewer和Hopper

用machoViewer打開macho文件。

如下圖:


找到Data Segment中的_objc_classlist對應(yīng)的section


記錄下對應(yīng)的Address


用Hopper打開macho文件

鍵盤輸入大寫字母G(跳到指定地址),或者選擇Navigate-> Go To Address or Symbol進入挑戰(zhàn)頁面睡雇。

輸入_objc_classlist的地址萌衬。

如下圖


點擊Go按鈕跳到_objc_classlist的地址


上圖顯示有三個類,AppDelegate, MasterViewController, DetailViewController

但是從macho文件來解析,這是三個地址,這三個類名是Hopper解析號之后加到顯示的注釋上了它抱。

選擇查看原件秕豫,紅框里面就是MasterViewController對應(yīng)的地址


雙擊_OBJC_CLASS_$_MasterViewController,可以跳轉(zhuǎn)到MasterViewController的引用處。

如下圖:



雙擊MasterViewController_data可以跳轉(zhuǎn)的MasterViewController的詳細信息處观蓄。(同樣這里MasterViewController_data也只是地址)

跳轉(zhuǎn)之后如下圖:



其中有一相是類名混移,這里是地址,雙擊可以到具體類名的地方侮穿。

跳轉(zhuǎn)之后如下圖:


到此查找類名結(jié)束歌径。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亲茅,隨后出現(xiàn)的幾起案子回铛,更是在濱河造成了極大的恐慌,老刑警劉巖芯急,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勺届,死亡現(xiàn)場離奇詭異,居然都是意外死亡娶耍,警方通過查閱死者的電腦和手機免姿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榕酒,“玉大人胚膊,你說我怎么就攤上這事∠胗ィ” “怎么了紊婉?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辑舷。 經(jīng)常有香客問我喻犁,道長,這世上最難降的妖魔是什么何缓? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任肢础,我火速辦了婚禮,結(jié)果婚禮上碌廓,老公的妹妹穿的比我還像新娘传轰。我一直安慰自己,他們只是感情好谷婆,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布慨蛙。 她就那樣靜靜地躺著辽聊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪期贫。 梳的紋絲不亂的頭發(fā)上跟匆,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音通砍,去河邊找鬼贾铝。 笑死,一個胖子當(dāng)著我的面吹牛埠帕,可吹牛的內(nèi)容都是我干的垢揩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼敛瓷,長吁一口氣:“原來是場噩夢啊……” “哼叁巨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呐籽,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤锋勺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后狡蝶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庶橱,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年贪惹,在試婚紗的時候發(fā)現(xiàn)自己被綠了苏章。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡奏瞬,死狀恐怖枫绅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情硼端,我是刑警寧澤并淋,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站珍昨,受9級特大地震影響县耽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜镣典,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一兔毙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骆撇,春花似錦瞒御、人聲如沸父叙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涌乳,卻和暖如春蜻懦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夕晓。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工宛乃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒸辆。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓征炼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親躬贡。 傳聞我的和親對象是個殘疾皇子谆奥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容