frida

前言

frida
frida-docs
Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Frida提供了一个名为“ FridaGadget.dylib ” 的动态库,可用于在非越狱设备上测试新开发的应用程序。

The Mach-O (iOS binary format) binary structure: /usr/include/mach-o/*.h

Before continuing, it is necessary to have at least a small understanding of the binary structure of an iOS application.

A Mach-O file consists of 2 main pieces: the header and the data. The header is basically a map of the file describing what it contains and the position of everything contained in it. The data comes directly after the header and consists of a number of binary blobs of data, one after the other.


            ,---------------------------,
  Header    |  Mach header              |
            |    Segment 1              |
            |      Section 1 (__text)   | --,
            |---------------------------|   |
  Data      |           blob            | <-'
            '---------------------------'
  • 1、The Mach-O (iOS binary format) binary structure
-1) header structure:The header contains general information about the binary: byte order (magic number), CPU type, amount of load commands, etc.
-2)The load commands section is like a table of contents of the binary: 
it describes the position of the segments, symbols table, dynamic symbols table etc. 
Each load command includes meta-information, such as type of command, its name, position in a binary, etc. 
-3) 链接信息:The data section contains the application code and the data, such as symbol tables, dynamic symbol tables, etc.

官方描述

Header: Specifies the target architecture of the file, such as PPC, PPC64, IA-32, or x86-64.
Load commands: Specify the logical structure of the file and the layout of the file in virtual memory.
Raw segment data: Contains raw data for the segments defined in the load commands.

详情:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/mach-o/loader.h

  • 2、The process to insert a new library involves multiple steps
- 1. Insert the library to the application container

- 2. Insert the load command on the load commands section of the binary

- 3. Increment the load command counter on the header section

- 4. Increase the size binary number on the header section

mach header

  • 1、可以借助otool 查看 mach header
    devzkndeMacBook-Pro:bin devzkn$ otool -h ps
    Mach header
        magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedfacf 16777223          3  0x80           2    16       1696 0x00200085
    

    cputype其定义参见/usr/include/mach/machine.h

  • 2、the filetype field of the mach_header (具体的请查看<mach-o/loader.h>)
#define MH_OBJECT 0x1   /* relocatable object file  gcc -c xxx.c 生成xxx.o文件 */
#define MH_EXECUTE  0x2   /* demand paged executable file */
#define MH_FVMLIB 0x3   /* fixed VM shared library file */
#define MH_CORE   0x4   /* core file 崩溃时的Dump文件 */
#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 内核扩展文件 */

  • 3、flags field of the mach_header
#define MH_PIE 0x200000     /* When this bit is set, the OS will
             load the main executable at a
             random address.  Only used in
             MH_EXECUTE filetypes. */
#define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks 
             in the task will be given stack
             execution privilege.  Only used in
             MH_EXECUTE filetypes. */
#define MH_NO_HEAP_EXECUTION 0x1000000  /* When this bit is set, the OS will
             run the main executable with
             a non-executable heap even on
             platforms (e.g. i386) that don't
             require it. Only used in MH_EXECUTE
             filetypes. */
#define  MH_NOUNDEFS 0x1   /* the object file has no undefined
             references */

load commands: otool -l git

加载命令的数目以及总的大小在header中已经给出。

具体的可以在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_LOAD_DYLIB 0xc /* load a dynamically linked shared library */
#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */
#define LC_CODE_SIGNATURE 0x1d  /* local of code signature */
#define LC_UUID   0x1b  /* the uuid */

LC_SEGMENT 的数据结构

A segment is made up of zero or more sections.每个段可以拥有零个或多个区域(section)。每一个段(segment)都拥有一段虚拟地址映射到进程的地址空间。

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)nsects 标志着segment 包含了多少的sections。 2)flag字段 SG_HIGHVM,SG_FVMLIB,SG_NORELOC,SG_PROTECTED_VERSION_1

Section的数据结构

struct section { /* for 32-bit architectures */
  char    sectname[16]; /* name of this section */
  char    segname[16];  /* segment this section goes in */
  uint32_t  addr;   /* memory address of this section */
  uint32_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) */
};
  • The currently known segment names and the section names in those segments 可以通过otool –s查看某segment的某个section。

段的命名规则是两个下划线紧跟着大写字母(如__TEXT),而section的命名则是两个下划线紧跟着小写字母(__text)。


#define SEG_PAGEZERO  "__PAGEZERO"  /* the pagezero segment which has no */
          /* protections and catches NULL */
          /* references for MH_EXECUTE files */


#define SEG_TEXT  "__TEXT"  /* the tradition UNIX text segment 含有可执行代码和只读的数据。 为了让内核将它 直接从可执行文件映射到共享内存,静态连接器设置该段的虚拟内存权限为不允许写。当这个段被映射到内存后,可以被所有进程共享。(这主要用在frameworks, bundles和共享库等程序中,也可以为同一个可执行文件的多个进程拷贝使用) */
#define SECT_TEXT "__text"  /* the real text part of the text */
          /* section no headers, and no padding */
#define SECT_FVMLIB_INIT0 "__fvmlib_init0"  /* the fvmlib initialization */
            /*  section */
#define SECT_FVMLIB_INIT1 "__fvmlib_init1"  /* the section following the */
                  /*  fvmlib initialization */
            /*  section */

#define SEG_DATA  "__DATA"  /* the tradition UNIX data segment */
#define SECT_DATA "__data"  /* the real initialized data section */
          /* no padding, no bss overlap */
#define SECT_BSS  "__bss"   /* the real uninitialized data section*/
          /* no padding */
#define SECT_COMMON "__common"  /* the section common symbols are */
          /* allocated in by the link editor */

#define SEG_OBJC  "__OBJC"  /* objective-C runtime segment */
#define SECT_OBJC_SYMBOLS "__symbol_table"  /* symbol table */
#define SECT_OBJC_MODULES "__module_info" /* module information */
#define SECT_OBJC_STRINGS "__selector_strs" /* string table */
#define SECT_OBJC_REFS "__selector_refs"  /* string table */

#define SEG_ICON   "__ICON" /* the icon segment */
#define SECT_ICON_HEADER "__header" /* the icon headers */
#define SECT_ICON_TIFF   "__tiff" /* the icons in tiff format */

#define SEG_LINKEDIT  "__LINKEDIT"  /* the segment containing all structs */
          /* created and maintained by the link */
          /* editor.  Created with -seglinkedit */
          /* option to ld(1) for MH_EXECUTE and */
          /* FVMLIB file types only */

#define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */

#define SEG_IMPORT  "__IMPORT"  /* the segment for the self (dyld) */
          /* modifing code stubs that has read, */
          /* write and execute permissions */
devzkndeMacBook-Pro:bin devzkn$ otool -d vi
vi:
Contents of (__DATA,__data) section
devzkndeMacBook-Pro:bin devzkn$ otool -sv  __DATA __data vi
vi:
Contents of (__DATA,__data) section
00000001001a2b20  c0 5b 17 00 01 00 00 00 c8 62 17 00 01 00 00 00 
00000001001a2b30  cf 5b 17 00 01 00 00 00 37 5c 17 00 01 00 00 00 

print the text section (disassemble with -v),当然我们可以借助hopper 和IDA 查看

devzkndeMacBook-Pro:bin devzkn$ otool -tv vi
vi:
(__TEXT,__text) section
0000000100000b34  pushq %rbp
0000000100000b35  movq  %rsp, %rbp
0000000100000b38  pushq %r15
0000000100000b3a  pushq %r14
0000000100000b3c  pushq %r13

install frida on device and mac

  • 1、 install frida-server through Cydia:
    Start Cydia and add Frida’s repository by navigating to Manage -> Sources -> Edit -> Add and entering https://build.frida.re
    apt-get update
    
    -rwxr-xr-x 1 root wheel 11292672 Dec 14 00:54 /usr/sbin/frida-server*
    -rw-r--r-- 1 root wheel 779 Dec 14 00:54 /Library/LaunchDaemons/re.frida.server.plist
    
  • 2、mac里面python自带easy_install pip pip是python的包管理工具
    devzkndeMacBook-Pro:site-packages devzkn$ sudo easy_install pip
    
  • 3、install the Frida Python package on your host machine
    devzkndeMacBook-Pro:site-packages devzkn$ sudo -H pip install frida
    
  • 4、Connect your device via USB and make sure that Frida work
    -U, --usb             connect to USB device
    -a, --applications    list only applications
    -i, --installed       include all installed applications
    devzkndeMacBook-Pro:site-packages devzkn$  frida-ps -Uai
    PID  Name          Identifier                 
    ---  ------------  ---------------------------
    904  Cydia         com.saurik.Cydia           
    856  微信            com.tencent.xin            
    858  邮件            com.apple.mobilemail       
    App Store     com.apple.AppStore         
    
  • 5、 upgrade frida
    devzkndeMacBook-Pro:bin devzkn$ sudo pip install --upgrade frida --ignore-installed six
    

debug

  • 1、pdb.py can be invoked as a script to debug other scripts.
    devzkndeMacBook-Pro:frida-ios-dump-master devzkn$ python -m pdb  ./dump.py 微信
    /Users/devzkn/Downloads/kevin-software/ios-Reverse_Engineering/frida-ios-dump-master/dump.py(7)<module>()
    -> import sys
    
  • 2、Pdb help
    (Pdb) h
    Documented commands (type help <topic>):
    ========================================
    EOF    bt         cont      enable  jump  pp       run      unt   
    a      c          continue  exit    l     q        s        until 
    alias  cl         d         h       list  quit     step     up    
    args   clear      debug     help    n     r        tbreak   w     
    b      commands   disable   ignore  next  restart  u        whatis
    break  condition  down      j       p     return   unalias  where 
    

pdb 常用命令

  • break 或b : 设置断点 设置断点
  • continue或c: 继续执行程序
  • list 或l : 查看当前行的代码段
  • step 或s : 进入函数
  • return 或r : 执行代码直到从当前函数返回
  • exit 或 q : 中止并退出
  • next 或 n : 执行下一行
  • pp : 打印变量的值
    (Pdb) pp os.getcwd()
    '/Users/devzkn/Downloads/kevin\xef\xbc\x8dsoftware/ios-Reverse_Engineering/frida-ios-dump-master'
    
  • help 或者h :
  • 1、python print 汉字
    (Pdb) print sys.argv
    ['./dump.py', '\xe5\xbe\xae\xe4\xbf\xa1']
    (Pdb) print sys.argv[1]
    微信
    

frida-ios-dump-master的使用

  • 1、安装上面步骤install frida on device and mac
  • 2、使用usbmuxd 进行端口转发 本地端口2222 转发到iOS的22端口
  • 3、执行dump.py
    devzkndeMacBook-Pro:bin devzkn$ frida-ps -Uai
     PID  Name          Identifier                 
    ----  ------------  ---------------------------
    1314  App Store     com.apple.AppStore         
    2151  微信            com.tencent.xin            
    2183  淘宝联盟          com.alimama.moon           
    1309  设置            com.apple.Preferences      
    

    必须在dump.py 所在的目录下执行。即使使用ln -l 也会失败。

    devzkndeMacBook-Pro:frida-ios-dump-master devzkn$ ./dump.py 驱蚊大咖
    open target  app......
    start dump target app......
    
  • 4、ln -s dump.py 会仅仅打开app 而已。
    devzkndeMacBook-Pro:bin devzkn$ ln -s /Users/devzkn/decrypted/frida-ios-dump-master/dump.py ./dump.py
    

Q&A

  • 2、 Ignoring Provides line with DepCompareOp for package libstatusbar
    W: Ignoring Provides line with DepCompareOp for package libstatusbar
    W: Ignoring Provides line with DepCompareOp for package libmoorecon
    W: You may want to run apt-get update to correct these problems
    
    iPhone:~ root# apt-get update
    
  • 3、frida-server 没有启动
    iPhone:/usr/sbin root# killall SpringBoard
    iPhone:/usr/sbin root# ps -e |grep frida-server
     2290 ttys000    0:00.01 grep frida-server
    
  • 4、-sh: /usr/sbin/frida-server: Bad CPU type in executable
    installed Frida for 32-bit devices
    
  • 5、 Unable to start server: Error binding to address: Address already in use
    removed
    
  • 6、frida-ps
    devzkndeMacBook-Pro:site-packages devzkn$  frida-ps --help
    Usage: frida-ps [options]
    Options:
    --version             show program's version number and exit
    -h, --help            show this help message and exit
    -D ID, --device=ID    connect to device with the given ID
    -U, --usb             connect to USB device
    -R, --remote          connect to remote frida-server
    -H HOST, --host=HOST  connect to remote frida-server on HOST
    -a, --applications    list only applications
    -i, --installed       include all installed applications
    


问题求救

前言

今天准备接触下frida, 使用下 AloneMonkey/frida-ios-dump的py, 但是发现了一个问题

Failed to spawn: unable to launch iOS app: timeout  

问题具体分析

install frida on device and mac 之后,running the frida-ps command

devzkndeMacBook-Pro:~ devzkn$ frida-ps -Uai
PID  Name          Identifier                 
---  ------------  ---------------------------
824  Cydia         com.saurik.Cydia           
804  设置            com.apple.Preferences      
372  邮件            com.apple.mobilemail       
  • 但是Failed to spawn
    devzkndeMacBook-Pro:~ devzkn$ frida -U -f com.apple.mobilemail 
       ____
      / _  |   Frida 10.6.27 - A world-class dynamic instrumentation framework
     | (_| |
      > _  |   Commands:
     /_/ |_|       help      -> Displays the help system
     . . . .       object?   -> Display information about 'object'
     . . . .       exit/quit -> Exit
     . . . .
     . . . .   More info at http://www.frida.re/docs/home/
    Failed to spawn: unable to launch iOS app: timeout    
    

运行dump.py的时候也没用效果

devzkndeMacBook-Pro:~ devzkn$ /Users/devzkn/Downloads/frida-ios-dump-master/dump.py 邮件
open target app......
devzkndeMacBook-Pro:~ devzkn$

Desktop 运行环境

  • 1、 frida version:10.6.27
    devzkndeMacBook-Pro:~ devzkn$ frida --version
    10.6.27
    
  • Mac version:10.13.1 (17B48)

Device 运行环境

  • iPhone version:8.3
    iPhone:/System/Library/CoreServices root# cat /System/Library/CoreServices/SystemVersion.plist|grep string*
      <string>12F70</string>
      <string>1983-2015 Apple Inc.</string>
      <string>iPhone OS</string>
      <string>8.3</string>
    

使用-P 倒是可以成功:

evzkndeMacBook-Pro:frida-ios-dump-master devzkn$  frida -U -p 1292
     ____
    / _  |   Frida 10.6.27 - A world-class dynamic instrumentation framework
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at http://www.frida.re/docs/home/
                                                                                
}
[iPhone::PID::1292]-> obj
                          ObjC                          
                          Object
  • 1、 使用./dump.py刚才仅仅成功过一次,无法重现了
    devzkndeMacBook-Pro:frida-ios-dump-master devzkn$ ./dump.py xx
    open target app......
    start dump target app......
    

Failed to spawn: unable to launch iOS app: timeout

问题的解决方法

引用iosre的解答

Frida 从 9.0 开始,改 hook launchd 来 spawn process,Frida 8.2.5 以前是利用 dylib 注入的方式来 spawn。

目前解决方法:
1.降回旧版Frida
2.不要使用spawn

我之前也一直在研究这个问题,目前只知道 Frida spawn process 在修改 kernel process flags 时,会导致32-bit 装置重启,不过我还没研究出为什么,大概只能判断 32-bit, 64-bit kernel 处理稍有不同。

有人懂这一块地也希望能一起研究研究

Failed to spawn 的替代方案

  • 1、先使用frida-ps -Uai 查看PID
  • 2、使用 frida -p attach
devzkndeMacBook-Pro:zhangkn.github.io devzkn$ frida -U -p 1262
     ____
    / _  |   Frida 10.6.27 - A world-class dynamic instrumentation framework
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at http://www.frida.re/docs/home/
                                                                                
[iPhone::PID::1262]-> 

frida-ios-dump 失败的原因

刚才进行了pdb ,发现执行到这里

(Pdb) l
108  		script = loadJsFile(session, APP_JS);
109  		name = target.decode('utf8');
110  		script.post(name);
111  		opened.wait();
112  		session.detach();
113  ->		createDir(os.getcwd()+"/"+OUTPUT)
114  		print "start dump target app......"
115  		session = device.attach(name);
116  		script = loadJsFile(session, DUMP_JS);
117  		script.post("dump");
118  		finished.wait();
(Pdb) s
--Return--
> /Users/devzkn/Downloads/kevin-software/ios-Reverse_Engineering/frida-ios-dump-master/dump.py(113)main()->None
-> createDir(os.getcwd()+"/"+OUTPUT)
(Pdb) l
108  		script = loadJsFile(session, APP_JS);
109  		name = target.decode('utf8');
110  		script.post(name);
111  		opened.wait();
112  		session.detach();
113  ->		createDir(os.getcwd()+"/"+OUTPUT)
114  		print "start dump target app......"
115  		session = device.attach(name);
116  		script = loadJsFile(session, DUMP_JS);
117  		script.post("dump");
118  		finished.wait();
(Pdb) s
UnicodeDecodeError: UnicodeD...ge(128)')
> /Users/devzkn/Downloads/kevin-software/ios-Reverse_Engineering/frida-ios-dump-master/dump.py(127)<module>()
-> main(sys.argv[1])
(Pdb) l
122  		if len(sys.argv) < 2:
123  			print "usage: ./dump.py 微信"
124  			sys.exit(0)
125  		else:
126  			try:
127  ->				main(sys.argv[1])
128  			except KeyboardInterrupt:
129  				if session:
130  					session.detach()
131  				sys.exit()
132  			except:
(Pdb) s
> /Users/devzkn/Downloads/kevin-software/ios-Reverse_Engineering/frida-ios-dump-master/dump.py(128)<module>()
-> except KeyboardInterrupt:
(Pdb) pp UnicodeDecodeError
<type 'exceptions.UnicodeDecodeError'>

因此,我换了一个路径,就可以了。

因此问题在于createDi的时候,编码失败了。 以后创建目录命名要小心了。

辅助shell

为了解决目前frida-ios-dump-master的一些小问题,写了一个shell

#!/bin/sh
# frida-ps -Uai 查看,来获取参数
# usage: devzkndeMacBook-Pro:~ devzkn$ kndump 邮件
# dump app   
cd ~/decrypted/frida-ios-dump-master 
rm -rf ./Payload
./dump.py $1
open .
exit 0

参考资源:

frida-scripts Repository including some useful frida script for iOS Reversing Murphy Python 代码调试技巧

mach-o 相关的文档


转载请注明: > frida

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

赞赏支持

取消

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

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

usefulCommand

前言常用的命令和工具dudu 在core utilities 的deb 包中df df -m iPhone:/Applications root# df -mFilesystem 1M-blocks Used Available Use% Mounted on/dev/disk0s1s1 3551 3494 21 100% /devfs 1 1 0 100% /dev/dev/dis...…

tool继续阅读
更早的文章

the static analysis of iOS application

前言  使用iNalyzer进行静态分析并不适合头文件很多的app,因为头文件很多的话,就会导致大量的图表等分析文件,很消耗资源,这种情况可考虑使用hopper进行静态分析。Running dot for graph 1175/42806-rw-r--r--@ 1 devzkn staff 47328989 Dec 10 13:35 static_2017_12_10-13_33_12.zip开篇就讲iNalyzer,是因为iNalyzer 能明显体现出静态分析的流程特点,以及它的安装...…

iOSre继续阅读
更多