認(rèn)識(shí)MachO

[TOC]

簡介

MachO文件是mac平臺(tái)上一類文件的簡稱浑槽,它的類型有以下種類,可以在#import <mach-o/loader.h>文件中找到

#define MH_OBJECT   0x1     /* relocatable object file */
#define MH_EXECUTE  0x2     /* demand paged executable file */
#define MH_FVMLIB   0x3     /* fixed VM shared library file */
#define MH_CORE     0x4     /* core file */
#define MH_PRELOAD  0x5     /* preloaded executable file */
#define MH_DYLIB    0x6     /* dynamically bound shared library */
#define MH_DYLINKER 0x7     /* dynamic link editor */
#define MH_BUNDLE   0x8     /* dynamically bound bundle file */
#define MH_DYLIB_STUB   0x9     /* shared library stub for static */
                    /*  linking only, no section contents */
#define MH_DSYM     0xa     /* companion file with only debug */
                    /*  sections */
#define MH_KEXT_BUNDLE  0xb     /* x86_64 kexts */

列舉一些常見的類型

文件類型 含義
MH_OBJECT 目標(biāo)文件,平時(shí).o結(jié)尾的文件
MH_EXECUTE 可執(zhí)行文件丑慎,我們平時(shí)編譯后的包中的執(zhí)行文件
MH_DYLIB 一些動(dòng)態(tài)庫,該文件夾下很多/usr/lib/xxx.dylib
MH_DSYM 符號(hào)文件,編譯成功后XXX.app.dSYM

一竿裂、MachO的分類

這里準(zhǔn)備了一些macho文件玉吁,分別通過MachOView工具來看看,如果你的MachOView會(huì)崩潰铛绰,點(diǎn)擊下載這個(gè)

15427852296930.jpg

分別用MachOView打開如下

15427855943405.jpg
15427856226881.jpg
15427856442658.jpg
15427856577687.jpg

二诈茧、MachO的組成

15433949955546.jpg

每個(gè)Macho文件都會(huì)有個(gè)Header對這個(gè)Macho進(jìn)行整體描述,這個(gè)header根據(jù)你打包的選擇的架構(gòu)又分為Fat HeaderMach Header捂掰,先介紹下如何生成這2個(gè)文件類型

15433953066278.jpg

Architecturesvalid Architectures 的交集就是最后打的包的架構(gòu),Architectures后面是標(biāo)準(zhǔn)的架構(gòu)曾沈,我把項(xiàng)目設(shè)置為iOS8選擇真機(jī)这嚣,將build改成release,會(huì)編譯出一開始的展示的MochO_arm_fat文件放到MachOView中如圖

15433957268022.jpg

然后選擇模擬器將build改成debug ,build會(huì)出現(xiàn)MochO_x86,結(jié)果如圖

15433959756469.jpg

2.1 fat_header

2.1.1 fat_header 結(jié)構(gòu)
struct fat_header {
    uint32_t    magic;      /* FAT_MAGIC or FAT_MAGIC_64 */
    uint32_t    nfat_arch;  /* number of structs that follow */
};

  1. magic: 描述文件類型 值分為2組分別為 FAT_CIGAM(0xbebafeca)塞俱、 FAT_MAGIC(0xcafebabe)FAT_CIGAM_64(0xbfbafeca)姐帚、FAT_MAGIC_64(0xcafebabf),值也就是大小端的區(qū)別障涯;
  2. nfat_arch:描述當(dāng)前fat有多少個(gè)架構(gòu)罐旗。
2.1.2 fat_arch 結(jié)構(gòu)

2.1.1 說到fat_headernfat_arch會(huì)描述有多少個(gè)架構(gòu),其實(shí)架構(gòu)的類型就是fat_arch類型的唯蝶,結(jié)構(gòu)如下

struct fat_arch {
    cpu_type_t  cputype;    /* cpu specifier (int) */
    cpu_subtype_t   cpusubtype; /* machine specifier (int) */
    uint32_t    offset;     /* file offset to this object file */
    uint32_t    size;       /* size of this object file */
    uint32_t    align;      /* alignment as a power of 2 */
};


  1. cputype:說明CPU的類型一般有CPU_TYPE_X86九秀、CPU_TYPE_X86_64CPU_TYPE_ARM64粘我、CPU_TYPE_ARM鼓蜒;
  2. cpusubtype: 對cpu類型的具體劃分一般有CPU_SUBTYPE_I386_ALLCPU_SUBTYPE_X86_ALL征字、CPU_SUBTYPE_ARM_V7都弹、CPU_SUBTYPE_ARM_V7S
  3. offset: 當(dāng)前架構(gòu)的偏移量匙姜;
  4. size:當(dāng)前架構(gòu)的大谐┫帷;
  5. align:對齊大小氮昧。

通過MachOView來看下MochO_arm_fatfat_header

15434008769918.jpg

也可以用otool查看

otool -f /Users/fangshufeng/Desktop/thirdPart/macho/MochO/MochO/exccute/

MochO_arm_fat

Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 12
    cpusubtype 9
    capabilities 0x0
    offset 16384
    size 112048
    align 2^14 (16384)
architecture 1
    cputype 16777228
    cpusubtype 0
    capabilities 0x0
    offset 131072
    size 108624
    align 2^14 (16384)
    

上面可以看到
架構(gòu)architecture 0的偏移地址是16384框杜,也就是16進(jìn)制的0x4000
架構(gòu)architecture 1的偏移地址是131072郭计,也就是16進(jìn)制的0x20000霸琴;

我們來看下是否正確

15434030151535.jpg
15434030281499.jpg

正好是要的值

2.2 mac_header

對于不是fatMacho文件一開始的內(nèi)容就是mac_header

2.2.1 結(jié)構(gòu)
struct mach_header {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
};

  1. magiccputype昭伸、cpusubtype:同上梧乘;

  2. filetype:Macho文件的類型,也就是文章一開始列舉的類型;

  3. ncmds:接下來load commands的數(shù)量选调,后面會(huì)介紹夹供;

  4. sizeofcmds:接下來load commands的大小,后面會(huì)介紹仁堪;

  5. flags:文件的表示信息哮洽,值如下:

    /* Constants for the flags field of the mach_header */
    #define    MH_NOUNDEFS 0x1     /* the object file has no undefinedreferences */
    #define    MH_INCRLINK 0x2     /* the object file is the output of an
                           incremental link against a base file
                           and can't be link edited again */
    #define MH_DYLDLINK    0x4     /* the object file is input for the
                           dynamic linker and can't be staticly
                           link edited again */
    #define MH_BINDATLOAD  0x8     /* the object file's undefined
                           references are bound by the dynamic
                           linker when loaded. */
    #define MH_PREBOUND    0x10        /* the file has its dynamic undefined
                           references prebound. */
    #define MH_SPLIT_SEGS  0x20        /* the file has its read-only and
                           read-write segments split */
    #define MH_LAZY_INIT   0x40        /* the shared library init routine is
    
    

截圖如下

15434129532803.jpg

同樣使用otool也是可以的

?  MochO otool -h exccute/MochO_x86
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777223          3  0x00           2    21       3176 0x00200085
?  MochO

上面顯示該文件的類型為MH_EXECUTELoad Commands的數(shù)量為21個(gè)弦聂,數(shù)一下確實(shí)是21個(gè)鸟辅。

15434132636545.jpg

也就是說mach_header更多的是對load Commands的描述

2.3 load Commands

load Commands是由很多的LC_Type組成的,而LC_Type有很多種,可在文件loader.h文件中查看莺葫,這邊就列出前幾種

/* Constants for the cmd field of all load commands, the type */
#define LC_SEGMENT  0x1 /* segment of this file to be mapped */
#define LC_SYMTAB   0x2 /* link-edit stab symbol table info */
#define LC_SYMSEG   0x3 /* link-edit gdb symbol table info (obsolete) */
[...]

而每個(gè)LC_Type都會(huì)有一個(gè)頭部load_command結(jié)構(gòu)如下

struct load_command {
    uint32_t cmd;       /* type of load command */
    uint32_t cmdsize;   /* total size of command in bytes */
};

是的就是對segment的描述

  1. cmd : 當(dāng)前l(fā)oad command的類型匪凉;
  2. cmdsize:load command的大小。

也就是下面這張圖

15434151220239.jpg
2.3.1 LC_SEGMENT

為了方便管理捺檬,程序在內(nèi)存中是分段管理的再层,先來看看LC_Type其中一種LC_SEGMENT的結(jié)構(gòu)

struct segment_command { /* for 32-bit architectures */
    uint32_t    cmd;        /* LC_SEGMENT */
    uint32_t    cmdsize;    /* includes sizeof section structs */
    char        segname[16];    /* segment name */
    uint32_t    vmaddr;     /* memory address of this segment */
    uint32_t    vmsize;     /* memory size of this segment */
    uint32_t    fileoff;    /* file offset of this segment */
    uint32_t    filesize;   /* amount to map from the file */
    vm_prot_t   maxprot;    /* maximum VM protection */
    vm_prot_t   initprot;   /* initial VM protection */
    uint32_t    nsects;     /* number of sections in segment */
    uint32_t    flags;      /* flags */
};

  1. cmdcmdsize: 就是上面的load_command類型;
  2. segname:就是當(dāng)前segment的名稱
  3. vmaddr:在虛擬內(nèi)存中的地址堡纬,這個(gè)很重要的聂受,以后會(huì)介紹到
  4. vmsize:在虛擬內(nèi)存中所占用的大小烤镐;
  5. fileoff:在文件中的偏移量蛋济;
  6. filesize:在文件中的大小,注意和vmaddr职车、vmsize區(qū)別
  7. maxprot:表示頁面所需要的最高內(nèi)存保護(hù)瘫俊;
  8. initprot:表示頁面初始的內(nèi)存保護(hù);
  9. nsects: 當(dāng)前segment有多少個(gè)sections
  10. flags:表示段的標(biāo)志信息。

常見的LC_SEGMENT有以下幾種

#define SEG_PAGEZERO    "__PAGEZERO"
#define SEG_TEXT    "__TEXT"    /* the tradition UNIX text segment */
#define SEG_DATA    "__DATA"    /* the tradition UNIX data segment */

2.3.1.1 __PAGEZERO

這是一個(gè)不可讀悴灵、不可寫扛芽、不可執(zhí)行的空間,能夠在空指針訪問時(shí)拋出異常积瞒。這個(gè)段的大小川尖,32位上是 0x4000,64位上0000000100000000也就是 4G茫孔,4GB 并不是文件的真實(shí)大小叮喳,但是規(guī)定了進(jìn)程地址空間的前 4GB 被映射為 不可執(zhí)行、不可寫和不可讀缰贝,是從0(也是NULL指針的位置)開始的馍悟,這就是為什么當(dāng)讀寫一個(gè) NULL 指針或更小的值時(shí)會(huì)得到一個(gè) EXC_BAD_ACCESS 錯(cuò)誤。

內(nèi)容如下

15434506392822.jpg
2.3.1.2 __TEXT

這是程序的代碼段剩晴,該段是可讀可執(zhí)行锣咒,但是不可寫侵状。常見的section如下

15434508576543.jpg
2.3.1.3 __DATA

數(shù)據(jù)段,包含了可讀寫數(shù)據(jù)毅整。常見的section如下

15434509398356.jpg
2.3.2 LC_DYLD_INFO_ONLY

LC_DYLD_INFO_ONLYLC_DYLD_INFO是同一個(gè)結(jié)構(gòu)

struct dyld_info_command {
   uint32_t   cmd;      /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
   uint32_t   cmdsize;      /* sizeof(struct dyld_info_command) */
 
   uint32_t   rebase_off;   /* file offset to rebase info  */
   uint32_t   rebase_size;  /* size of rebase info   */
 
   uint32_t   bind_off; /* file offset to binding info   */
   uint32_t   bind_size;    /* size of binding info  */
 
   uint32_t   weak_bind_off;    /* file offset to weak binding info   */
   uint32_t   weak_bind_size;  /* size of weak binding info  */
 
   uint32_t   lazy_bind_off;    /* file offset to lazy binding info */
   uint32_t   lazy_bind_size;  /* size of lazy binding infs */
 
   uint32_t   export_off;   /* file offset to lazy binding info */
   uint32_t   export_size;  /* size of lazy binding infs */
};

這個(gè)commanddyld在將二進(jìn)制文件裝載到內(nèi)存鏈接的時(shí)候使用的

  1. 前面2個(gè)不介紹了趣兄,rebase:由于Macho被加載到內(nèi)存的時(shí)候首地址不是固定的,是隨機(jī)分配的悼嫉,針對這個(gè)做修正的艇潭;
  2. bind:在鏈接的時(shí)候?qū)σ恍┓?hào)進(jìn)行綁定的,比如我們用到了UIKIT框架的api戏蔑,但是二進(jìn)制中又沒有這個(gè)符號(hào)蹋凝,此刻就是做這個(gè)對應(yīng)的工作;
  3. lazy_bind:就是一開始不必要立即綁定辛臊,后面用到的時(shí)候再綁定仙粱。

內(nèi)容如下


15434628271603.jpg

可以通過偏移量找到對應(yīng)的地方

15434628607183.jpg
2.3.3 LC_SYMTAB

這里面記錄著所有的符號(hào)信息

struct symtab_command {
    uint32_t    cmd;        /* LC_SYMTAB */
    uint32_t    cmdsize;    /* sizeof(struct symtab_command) */
    uint32_t    symoff;     /* symbol table offset */
    uint32_t    nsyms;      /* number of symbol table entries */
    uint32_t    stroff;     /* string table offset */
    uint32_t    strsize;    /* string table size in bytes */
};

  1. symoff:符號(hào)表的偏移量;
  2. nsyms:符號(hào)表的元素的數(shù)量彻舰;
  3. stroff:符號(hào)的字符串的偏移量;
  4. strsize:所占的字節(jié)數(shù)候味。
15434724909458.jpg
2.3.3.1 查看Symbol Table

上面說到symbol的偏移量為21568也就是0x0000 5440

選擇如下

15434728268791.jpg

看到下圖

15434728083212.jpg

Symbol Table裝著都是結(jié)構(gòu)nlist_64或者nlist可以see <mach-o/nlist.h>

struct nlist_64 {
    union {
        uint32_t  n_strx; /* index into the string table */
    } n_un;
    uint8_t n_type;        /* type flag, see below */
    uint8_t n_sect;        /* section number or NO_SECT */
    uint16_t n_desc;       /* see <mach-o/stab.h> */
    uint64_t n_value;      /* value of this symbol (or stab offset) */
};

  1. n_strx: 在String Table中的索引值刃唤;
  2. n_type: 可選的值有N_STABN_PEXT白群、N_TYPE尚胞、N_EXT
  3. n_sectsection的類型帜慢,要么就是NO_SECT笼裳;
  4. n_desc
  5. n_value: 符號(hào)對應(yīng)的地址

這里以AppDelegate的符號(hào)_OBJC_CLASS_$_AppDelegate來演示

15434733206364.jpg

根據(jù)圖得出以下信息:

  1. n_sect顯示位于__DATA,__objct_data
  2. value顯示地址為0x100003F48粱玲。

跳到對應(yīng)的地址看到確實(shí)是我們要找的:

15434734789740.jpg

具體的數(shù)據(jù)如圖

15434735103837.jpg

讀出以下信息:

  1. _OBJC_CLASS_$_AppDelegate的isa是OBJC_METACLASS$_AppDelegate;
  2. 父類是UIResponder
  3. 此時(shí)的緩存是空
  4. 緩存的數(shù)量為0
  5. 當(dāng)前類相關(guān)的信息在地址0x100003DC0;

到這是不是覺得特別熟悉呢躬柬,我們把AppDelegate的代碼用c++看下


xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc AppDelegate.m

可以看到

extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_AppDelegate __attribute__ ((used, section ("__DATA,__objc_data"))) = {
    0, // &OBJC_METACLASS_$_AppDelegate,
    0, // &OBJC_CLASS_$_UIResponder,
    0, // (void *)&_objc_empty_cache,
    0, // unused, was (void *)&_objc_empty_vtable,
    &_OBJC_CLASS_RO_$_AppDelegate,
};
static void OBJC_CLASS_SETUP_$_AppDelegate(void ) {
    [...這里刪除了元類的信息]
    
    OBJC_CLASS_$_AppDelegate.isa = &OBJC_METACLASS_$_AppDelegate;
    OBJC_CLASS_$_AppDelegate.superclass = &OBJC_CLASS_$_UIResponder;
    OBJC_CLASS_$_AppDelegate.cache = &_objc_empty_cache;
}

和我們的工具看到的不謀而合

我們繼續(xù)跳到0x100003DC0看下

15434741931169.jpg

確實(shí)看到了我們要的信息,而右邊的又是什么呢抽减,由剛才的C++代碼可以知道0x100003DC0就是_OBJC_CLASS_RO_$_AppDelegate的地址

看下_class_ro_t的結(jié)構(gòu)

struct _class_ro_t {
    unsigned int flags;
    unsigned int instanceStart;
    unsigned int instanceSize;
    const unsigned char *ivarLayout;
    const char *name;
    const struct _method_list_t *baseMethods;
    const struct _objc_protocol_list *baseProtocols;
    const struct _ivar_list_t *ivars;
    const unsigned char *weakIvarLayout;
    const struct _prop_list_t *properties;
};


這個(gè)結(jié)構(gòu)也即是我們截圖的內(nèi)容真好匹配


static struct _class_ro_t _OBJC_CLASS_RO_$_AppDelegate __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    0, 
    __OFFSETOFIVAR__(struct AppDelegate, _window), 
    sizeof(struct AppDelegate_IMPL), 
    0, 
    "AppDelegate",
    (const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_AppDelegate,
    (const struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_$_AppDelegate,
    (const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_AppDelegate,
    0, 
    (const struct _prop_list_t *)&_OBJC_$_PROP_LIST_AppDelegate,
};


所以到這里我們可以知道該類的所有信息了允青,比如我們想看看它得方法列表,由截圖可以知道地址為0x0000000100003C60

15434745008586.jpg

每一個(gè)item對應(yīng)的就是_objc_method

struct _objc_method {
    struct objc_selector * _cmd;
    const char *method_type;
    void  *_imp;
};

比如我們現(xiàn)在想到拿到方法- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions的名稱卵沉,看圖可以知道方法的字符串地址為0000000100001C90

15434747930624.jpg

果然找到了颠锉,其它的信息可以自己嘗試去找找。更多關(guān)于類方面的知識(shí)可以看下我之前的oc主題相關(guān)的文章史汗,現(xiàn)在文章已經(jīng)很長了琼掠,不說這個(gè)了。

2.3.3.2 查看String Table
15434758140872.jpg
2.3.4 LC_DYSYMTAB

這里記錄著所有的動(dòng)態(tài)鏈接時(shí)需要的符號(hào)信息

15434758929962.jpg

同樣我們找到00005C10

15434760343894.jpg

還有很多沒有截取了停撞,比如這些_NSFullUserName這些在鏈接的時(shí)候回去動(dòng)態(tài)解析這些符號(hào)表

這個(gè)Indirect Symbols包含了所有和動(dòng)態(tài)庫相關(guān)的符號(hào)瓷蛙,包括__DATA,__la_symbol_ptr__DATA,__nl_symbol_ptr__DATA,__got速挑,這個(gè)表有以下用處:

  1. 通過這個(gè)表的Symbol可以找到在符號(hào)表Symbol Table的位置谤牡,從而在字符串表String Table中找到名稱;
  2. 通過這個(gè)表的Indirect Address可以在__DATA,__la_symbol_ptr姥宝、__DATA,__nl_symbol_ptr翅萤、__DATA,__got中找到方法的地址

fishook就用到了這個(gè),后面我會(huì)單獨(dú)來介紹這個(gè)庫的實(shí)現(xiàn)原理

2.3.5 LC_MAIN

指定了main函數(shù)的入口地址

15434763840725.jpg

加載到內(nèi)存后增加頭部地址就是函數(shù)的真正地址了

15434764315415.jpg
2.3.6 LC_LOAN_DYLIB

描述了一些動(dòng)態(tài)庫相關(guān)的信息

15434765147302.jpg

struct dylib {
    union lc_str  name; /* library's path name */
    uint32_t timestamp; /* library's build time stamp */
    uint32_t current_version; /* library's current version number */
    uint32_t compatibility_version; /* library's compatibility vers number*/
};

struct dylib_command {
    uint32_t    cmd;        /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB,LC_REEXPORT_DYLIB */
    uint32_t    cmdsize;    /* includes pathname string */
    struct dylib    dylib;      /* the library identification */
};


2.3.7 LC_RPATH

Runpath的簡寫

程序運(yùn)行鏈接路徑

15434770431910.jpg

xcode中可以看到

15434769572907.jpg
2.3.8 LC_FUNCTION_STARTS

方法是從哪里開始的

15434771721891.jpg
15434771848408.jpg

和解析出來的順序也是一致的

15434772180884.jpg
2.3.9 LC_CODE_SINGATURE

簽名相關(guān)的信息

15434773234743.jpg

找到地方0x67E0

15434773374419.jpg

關(guān)于簽名的后面打算單獨(dú)寫一篇

2.4 section

結(jié)構(gòu)如下

struct section_64 { /* for 64-bit architectures */
    char        sectname[16];   /* name of this section */
    char        segname[16];    /* segment this section goes in */
    uint64_t    addr;       /* memory address of this section */
    uint64_t    size;       /* size in bytes of this section */
    uint32_t    offset;     /* file offset of this section */
    uint32_t    align;      /* section alignment (power of 2) */
    uint32_t    reloff;     /* file offset of relocation entries */
    uint32_t    nreloc;     /* number of relocation entries */
    uint32_t    flags;      /* flags (section type and attributes)*/
    uint32_t    reserved1;  /* reserved (for offset or index) */
    uint32_t    reserved2;  /* reserved (for count or sizeof) */
    uint32_t    reserved3;  /* reserved */
};

這里只列舉了section64位的腊满,section可以自己在#include <mach-o/loader.h>查看

  1. sectname:當(dāng)前section的名字;
  2. segname:位于哪個(gè)segment;
  3. addr:當(dāng)前section在內(nèi)存中的地址套么;
  4. size:當(dāng)前的section所占的內(nèi)存大小碳蛋;
  5. offset:當(dāng)前section的偏移量胚泌;
  6. reloff: 抱歉暫時(shí)沒找到實(shí)際的用處,不做解釋,以免誤人子弟肃弟;
  7. nreloc:這個(gè)就是表示上面reloff的數(shù)量玷室;
  8. flags: 這個(gè)是當(dāng)前section的標(biāo)志位,包括sectionTypesectionAttribute,一個(gè)section可以有多個(gè)屬性笤受,但是只能有一個(gè)類型穷缤,這個(gè)很好理解了,可以通過位運(yùn)算分別獲取類型和屬性箩兽,(section->flags & SECTION_TYPE津肛、section->flags & SECTION_ATTRIBUTES
  9. reserved1:這是個(gè)保留字段,它可以表示偏移量也可以用來表示索引汗贫,一般用來表示Indirect Symbol Index也就是間接索引表的位置身坐,你可以在__got__subs等中可以查看落包;
  10. reserved3:也是個(gè)保留字段部蛇,一般表示數(shù)量的,比如在__subssection中就表示subs的個(gè)數(shù)妥色;
  11. reserved3:這個(gè)真是個(gè)保留字段了搪花,暫時(shí)沒什么用處

隨意截取一個(gè)section看下結(jié)構(gòu)吧

15538261885093

本篇完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘹害,一起剝皮案震驚了整個(gè)濱河市撮竿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笔呀,老刑警劉巖幢踏,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異许师,居然都是意外死亡房蝉,警方通過查閱死者的電腦和手機(jī)僚匆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搭幻,“玉大人咧擂,你說我怎么就攤上這事√刺#” “怎么了松申?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長俯逾。 經(jīng)常有香客問我贸桶,道長,這世上最難降的妖魔是什么桌肴? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任皇筛,我火速辦了婚禮,結(jié)果婚禮上坠七,老公的妹妹穿的比我還像新娘水醋。我一直安慰自己,他們只是感情好彪置,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布离例。 她就那樣靜靜地躺著,像睡著了一般悉稠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艘包,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天的猛,我揣著相機(jī)與錄音,去河邊找鬼想虎。 笑死卦尊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舌厨。 我是一名探鬼主播岂却,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼裙椭!你這毒婦竟也來了躏哩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揉燃,失蹤者是張志新(化名)和其女友劉穎扫尺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炊汤,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡正驻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年弊攘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姑曙。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡襟交,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伤靠,到底是詐尸還是另有隱情捣域,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布醋界,位于F島的核電站竟宋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏形纺。R本人自食惡果不足惜丘侠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一隶症、第九天 我趴在偏房一處隱蔽的房頂上張望缺亮。 院中可真熱鬧,春花似錦娩缰、人聲如沸脂新。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽争便。三九已至级零,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滞乙,已是汗流浹背奏纪。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斩启,地道東北人序调。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像兔簇,于是被迫代替她去往敵國和親发绢。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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

  • 1 dyld 1.1 dyld簡介 在iOS系統(tǒng)中垄琐,幾乎所有的程序都會(huì)用到動(dòng)態(tài)庫边酒,而動(dòng)態(tài)庫在加載的時(shí)候都需要用d...
    Kevin_Junbaozi閱讀 11,851評論 4 44
  • Mach-o格式,是Mach操作系統(tǒng)內(nèi)核(Mac此虑、iOS系統(tǒng)的內(nèi)核)主要支持的可執(zhí)行文件格式甚纲。 用otool工具可...
    hhy_082510閱讀 1,564評論 0 0
  • 1什么是macho 2 macho總體描述 3以查詢一個(gè)類名為例,說明查找過程 1什么是macho macho是m...
    rainzhang閱讀 2,012評論 2 2
  • 13. Hook原理介紹 13.1 Objective-C消息傳遞(Messaging) 對于C/C++這類靜態(tài)語...
    Flonger閱讀 1,413評論 0 3
  • 作為一個(gè)大三的歷史系的孩子,考研好像是個(gè)必不可少的經(jīng)歷朦前,考研中會(huì)遇到好多事好多人介杆,在大學(xué)大學(xué)的經(jīng)歷好像又豐富了許多...
    瑗七閱讀 95評論 0 1