otool

前言

使用otool 之前有必要对Mach-O 了解一下。可以使用Mach-O文件的可视化工具MachOExplorer进行查看。

  • iPhone app 存放的路径
    #app 下载的app路径
    iPhone:~ root# ls -l  /var/mobile/Containers/Bundle/Application
    total 0
    drwxr-xr-x 3 mobile mobile 170 Dec 17 11:43 15912B70-1938-479E-A21E-624525AEC733/
    #Apple原生的应用路径
    lrwxr-xr-x 1 root admin 32 Apr 23  2017 /Applications -> /var/stash/_.TvfJPY/Applications/
    iPhone:~ root# cd /var/stash/_.TvfJPY/Applications/
    iPhone:/var/stash/_.TvfJPY/Applications root# ls -l
    total 0
    drwxrwxr-x  3 root   admin   272 Sep 27  2014 AACredentialRecoveryDialog.app/
    drwxrwxr-x  3 root   admin   306 Sep 13  2014 AccountAuthenticationDialog.app/
    drwxrwxr-x 42 root   admin  1700 Oct 14  2014 AdSheet.app/
    
  • Universal Binary 通用二进制文件,也称胖二进制文件 Fat headers
    iPhone:/var/stash/_.TvfJPY/Applications/iRE.app root# otool -f iRE2
    Fat headers
    fat_magic 0xcafebabe
    nfat_arch 2
    architecture 0
      cputype 12
      cpusubtype 9
      capabilities 0x0
      offset 16384
      size 67248
      align 2^14 (16384)
    architecture 1
      cputype 12
      cpusubtype 11
      capabilities 0x0
      offset 98304
      size 67264
      align 2^14 (16384)
    
  • Fat Header的数据结构在<mach-o/fat.h>头文件上有定义:
    #define FAT_MAGIC	0xcafebabe
    #define FAT_CIGAM	0xbebafeca	/* NXSwapLong(FAT_MAGIC) */
    struct fat_header {
      uint32_t	magic;		/* FAT_MAGIC */
      uint32_t	nfat_arch;	/* number of structs that follow */
    };
    //说明对应Mach-O文件大小、支持的CPU架构、偏移地址
    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 */
    };
    

    从上面的例子,可以看出胖文件的fat_magic是0xcafebabe;顺便说一下64位的Mach-O文件的魔数值为#define MH_MAGIC_64 0xfeedfacf

  • file 就是根据Magic 来判断的
    devzkndeMacBook-Pro:knMoknKKKKKKokkn.decryptedV5.4.0 devzkn$ file knMoknKKKKKKokkn.decrypted.dec*
    knMoknKKKKKKokkn.decrypted.decrypted: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O executable arm_v7] [arm64]
    knMoknKKKKKKokkn.decrypted.decrypted (for architecture armv7):	Mach-O executable arm_v7
    knMoknKKKKKKokkn.decrypted.decrypted (for architecture arm64):	Mach-O 64-bit executable arm64
    

    magic 存放的位置在/usr/share/file/magic,更多信息请看这里

Mach-O

是Mach object文件格式的缩写,是一种可执行文件、目标代码、共享程序库、动态加载代码和核心DUMP;是a.out格式的一种替代;Mach-O提供更多的可扩展性和更快的符号表信息存取。

  • #include <mach-o/loader.h>

-l print the load commands

这些加载命令在Mach-O文件加载解析时,被内核加载器或者动态链接器调用,指导如何设置加载对应的二进制数据段;

  • Load Commend的数据结构如下:
    struct load_command {
      uint32_t cmd;		/* type of load command */
      uint32_t cmdsize;	/* total size of command in bytes */
    };
    
  • otool -l MKNooJn.dec*
    devzkndeMacBook-Pro:knMoknKKKKKKokkn.decrypted.4.0 devzkn$ 
    knMoknKKKKKKokkn.decrypted.decrypted (architecture armv7):
    Mach header
        magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          9  0x00           2    75       7500 0x00218085
    Load command 0
        cmd LC_SEGMENT
    cmdsize 56
    segname __PAGEZERO
     vmaddr 0x00000000
     vmsize 0x00004000
    fileoff 0
     filesize 0
    maxprot 0x00000000
     initprot 0x00000000
     nsects 0
      flags 0x0
    

    OS X/iOS发展到今天,已经有40多条加载命令,其中部分是由内核加载器直接使用,而其他则是由动态链接器处理。其中几个主要的Load Commend为LC_SEGMENT, LC_LOAD_DYLINKER, LC_UNIXTHREAD, LC_MAIN;LC_SEGMENT 的数据结构的更多信息请查看这里

  • LC_LOAD_DYLIB 、LC_LOAD_WEAK_DYLIB
#define	LC_LOAD_DYLIB	0xc	/* load a dynamically linked shared library */
/*
 * load a dynamically linked shared library that is allowed to be missing
 * (all symbols are weak imported).
 */
#define	LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)

-h print the mach header

  • otool -h MKNooJn.dec*
    Mach header
       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          9  0x00           2    75       7500 0x00218085
    Mach header
       magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedfacf 16777228          0  0x00           2    75       8344 0x00218085
    

-t print the text section (disassemble with -v)

devzkndeMacBook-Pro:knMokssnossV5.4.0 devzkn$ otool -tv knMokssnoss.decrypted
knMokssnoss.decrypted (architecture armv7):
(__TEXT,__text) section
000097b0  f0 b5 03 af   svcge #0x3b5f0
llvm-objdump: warning: invalid instruction encoding
  • __TEXT __cstring
    devzkndeMacBook-Pro:~ devzkn$ otool -sv __TEXT __cstring  /bin/ls
    /bin/ls:
    Contents of (__TEXT,__cstring) section
    

otool -o

一个可执行文件包含多个段, 在每一个段内有一些片段。它们包含了可执行文件的不同的部分, 包含了部分的源码及DATA.

  • otool -o MKNooJn.dec*
    devzkndeMacBook-Pro:knMoknKKKKKKokkn.decrypted.4.0 devzkn$ otool -o MKNooJn.dec* |grep password
                name 0x82b11e passwordTextFieldFrame
                name 0x82b135 passwordPlaceholder
                    name 0x82b11e passwordTextFieldFrame
                    name 0x82b135 passwordPlaceholder
                    name 0x82b11e passwordTextFieldFrame
                    name 0x82b135 passwordPlaceholder
    
  • LC_SEGMENT(__TEXT) Number of Sections + LC_SEGMENT(__DATA) Number of Sections = Sections Number of sections
  • otool -s
    devzkndeMacBook-Pro:knMoknKKKKKKokkn.decrypted.4.0 devzkn$ otool -s __TEXT __const MKNooJn.dec*
    knMoknKKKKKKokkn.decrypted.decrypted (architecture armv7):
    Contents of (__TEXT,__const) section
    00951340	6f6f4d34 3141306e 61724734 6c416564 
    
  • Raw segment data
    一般Mach-O文件有多个段(Segement),段每个段有不同的功能;
    1). __PAGEZERO: 空指针陷阱段,映射到虚拟内存空间的第一页,用于捕捉对NULL指针的引用;<br>
    2). __TEXT: 包含了执行代码以及其他只读数据。该段数据的保护级别为:VM_PROT_READ(读)、VM_PROT_EXECUTE(执行),防止在内存中被修改;<br>
    3). __DATA: 包含了程序数据,该段可写;<br>
    4). __OBJC: Objective-C运行时支持库;<br>
    5). __LINKEDIT: 链接器使用的符号以及其他表<br>
    一般的段又会按不同的功能划分为几个区(section)。
    
  • section的命名规则
    命名规则标识段-区的表示方法为(__SEGMENT.__section)SEGMENT所有字母大写,加两个下横线作为前缀;section为小写,同样加两个下横线作为前缀。
    

Sequence of Steps in Executing an Image

  • flow_of_process_execution Flow of the various process execution functions in OS X 引用自《Mac OS X and iOS Internals》P519
    devzkndeMacBook-Pro:kern devzkn$ open /Users/devzkn/Downloads/kevinsoftware/ios-Reverse_Engineering/xnu-2782.1.97/bsd/kern/kern_exec.c
    
  • parse_machfile()
    (1):解析线程状态,UUID和代码签名。相关命令为LC_UNIXTHREAD、LC_MAIN、LC_UUID、LC_CODE_SIGNATURE 
    (2):解析代码段Segment。相关命令为LC_SEGMENT、LC_SEGMENT_64;
    (3):解析动态链接库、加密信息。相关命令为:LC_ENCRYPTION_INFO、LC_ENCRYPTION_INFO_64、LC_LOAD_DYLINKER
    
  • load 函数是如何被调用的 dyld 是Apple 的动态链接器;在 xnu 内核为程序启动做好准备后,就会将 PC 控制权交给 dyld 负责剩下的工作 (dyld 是运行在 用户态的, 这里由 内核态 切到了用户态).

参考

-machO-tools

  • app 的启动过程
    1、内核(OS Kernel)创建一个进程,分配虚拟的进程空间等等,加载动态链接器。
    2、通过动态链接器加载主二进制程序引用的库、绑定符号。
    3、启动程序
    
  • mach-o_execution:
  • Darwin体系
    Darwin是一种类似unix的操作系统,他的核心是XNU。
    XNU是一种混合式内核。结合了mach与BSD两种内核。
    Mach 是微内核实现。
    BSD 实现在Mach的上层,这一层提供的API 支持了POSIX标准模型。在XNU中主要实现了一些高级的API与模块。
    

iOS安全机制

- 代码签名:
- 强制访问控制(Mandatory Access Control):系统检测安全属性以便确定一个用户是否有权访问该文件
- sandbox: 沙盒在启动的时候可以设置运行的程序是否可以访问网络、文件、目录

转载请注明: > otool

在操作过程或者文章有问题的话欢迎在 原文 里提问或指正。

赞赏支持

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少
最近的文章

html

前言HTML(超文本标记语言——HyperText Markup Language)是构成Web世界的基石。它描述并定义了一个网页的内容。其他除HTML以外的技术则通常用来描述一个网页的表现/展示效果(CSS)或功能(JavaScript)。内联元素和块元素的特点 block(块)元素的特点 ①总是在新行上开始;②高度,行高以及外边距和内边距都可控制;③宽度是它的容器的100%,除非设定一个宽度。④它可以容纳内联元素和其他块元素 inline元...…

html继续阅读
更早的文章

IDA

前言Interactive Disassembler Professional(“交互式反汇编器专业版”) 共有(File , Edit , Jump , Search , View , Debugger , Options , Windows , Help)9个模块.“IDA 目录的结构” /Applications/IDA Pro 7.0/ida64.app/Contents/MacOS /Applications/IDA Pro 7.0/ida64.app/Co...…

iOSre继续阅读
更多