iOS 逆向-macho文件和LLDB

作者: meryin | 来源:发表于2018-05-08 10:40 被阅读62次

    一 利用class-dump导出所有头文件

    1. 安装class-dunmp

    可以直接安装class-dump 或者安装MonkeyDev
    安装MonkeyDev过后设置环境变量:因为本人用的zsh,所以vim ~/.zshrc加上export PATH=/opt/MonkeyDev/bin:$PATH

    2. 导出头文件

    把ipa用归档实用工具打开,显示包内容,找到同名macho文件,进入文件目录,然后class-dump -H QQMusic -o new(新的目录文件中)

    二 拆分和合并macho二进制文件

    1. 拆分

    当用多个架构打包后,会生成一个fat macho文件,用以下命令拆分:

    lipo QQMusic -thin arm64 -output macho_arm64
    lipo QQMusic -thin armv7 -output macho_armv7
    

    把QQMusic二进制的arm64架构拆分并输出为新的名字为macho_arm64的文件

    2. 查看二进制文件信息

    file QQMusic

    3. 合并

    lipo -create macho_armv7 macho_arm64 -output newQQMUSIC

    三 xcode选择编译架构

    1.png

    build active architecture only设置debug和release版本编译是,是否编译多个架构;Architecture和valid Architecctures的交集,决定编译时编译哪些架构

    四 LLDB

    1. 代码断点

    • 设置断点
      2.png
      设置多个oc方法的断点:breakpoint set -n "-[ViewController save:]" -n "-[ViewController pauseGame:]"
    • 查看断点 breakpoint list
    • 继续程序 c
    • 禁用断点 breakpoint disable 2.1禁用第二组的第一个断点
    • 启用断点 breakpoint enable 2.1
    • 删除断点:只能删除某组断点breakpoint delete 3,如果breakpoint delete 3.1起到的是禁用3.1的作用
    • 查看lldb指令:help
    help breakpoint
         Commands for operating on breakpoints (see 'help b' for shorthand.)
    
    Syntax: breakpoint
    
    The following subcommands are supported:
    
          clear   -- Delete or disable breakpoints matching the specified source
                     file and line.
          command -- Commands for adding, removing and listing LLDB commands
                     executed when a breakpoint is hit.
          delete  -- Delete the specified breakpoint(s).  If no breakpoints are
                     specified, delete them all.
          disable -- Disable the specified breakpoint(s) without deleting them.  If
                     none are specified, disable all breakpoints.
          enable  -- Enable the specified disabled breakpoint(s). If no breakpoints
                     are specified, enable all of them.
          list    -- List some or all breakpoints at configurable levels of detail.
          modify  -- Modify the options on a breakpoint or set of breakpoints in
                     the executable.  If no breakpoint is specified, acts on the
                     last created breakpoint.  With the exception of -e, -d and -i,
                     passing an empty argument clears the modification.
          name    -- Commands to manage name tags for breakpoints
          read    -- Read and set the breakpoints previously saved to a file with
                     "breakpoint write".  
          set     -- Sets a breakpoint or set of breakpoints in the executable.
          write   -- Write the breakpoints listed to a file that can be read in
                     with "breakpoint read".  If given no arguments, writes all
                     breakpoints.
    
    For more help on any particular subcommand, type 'help <command> <subcommand>'.
    
    • 设置所有的save:方法的断点 breakpoint set --selector save:

    • 设置某个文件中的save:方法的断点:breakpoint set --file ViewController.m --selector save:

    • 全局遍历项目中所有方法名中包含某字段的断点:breakpoint set -r Game:

    • 根据内存地址给方法-[ViewController eatWithObjc:] 下断点:
      image list得到:

    [  0] 9DC999FC-3D7D-37A2-A57D-F33622E4FB43 0x0000000101378000 /Users/mac/Library/Developer/Xcode/DerivedData/003--Demo1-euekigzuynuvedgnvqwopomnhaam/Build/Products/Debug-iphoneos/003--Demo1.app/003--Demo1
    

    那么ALSR偏移量为:0x1378000,在ida中得到-[ViewController eatWithObjc:]的地址为:

    _text:0000000100006688 ; void __cdecl -[ViewController eatWithObjc:](ViewController *self, SEL, id)
    __text:0000000100006688 __ViewController_eatWithObjc__          ; DATA XREF: __objc_const:0000000100008170↓o
    

    最终得到方法在内存中的真实地址为:0x100006688+0x1378000
    下断点:b -a 0x100006688+0x1378000

    2. 执行代码进行调试

    • expression 简写p
    (lldb) expression self.view.subviews
    (NSArray *) $0 = 0x0000000159e38920
    (lldb) p self.view.backgroundColor = [UIColor yellowColor]
    (UIColor *) $1 = 0x0000000159e837f0
    (lldb) c
    Process 80637 resuming
    2018-05-07 16:20:42.198488+0800 001--LLDB[80637:7308534] XPC connection interrupted
    2018-05-07 16:21:00.038626+0800 001--LLDB[80637:7308097] Status bar could not find cached time string image. Rendering in-process.
    

    打印对象:po self.view.subviews

    • 举个例子🌰:

    在数组中加入新的Person对象

    (lldb) p [self.models addObject:[Person new]];
    (lldb) p (Person *)self.models.lastObject
    (Person *) $3 = 0x0000000101508080
    (lldb) p $3.name = @"meryin"
    (NSString *) $4 = 0xa006e697972656d6
    (lldb) p $3.age = 20
    (int) $5 = 20
    (lldb) po $3.name
    meryin
    

    设置变量然后再添加:

    (lldb) p Person *p4 = [Person new]; //按住control和回车键,继续代码
    p4.name = @"tom";p4.age = 25;
    [self.models addObject:p4];//最后回车
    

    3. 内存断点

    • 给某对象的某属性下断点:
      (lldb) watchpoint set variable p1->_name
      或者利用内存地址下断点:
    (lldb) frame variable
    (ViewController *) self = 0x0000000105ec23b0
    (SEL) _cmd = "viewDidLoad"
    (Person *) p1 = 0x0000000105ea8190
    (Person *) p2 = 0x0000000000000010
    (Person *) p3 = 0x000000016f3e5528
    (lldb) p &p1->_name
    (NSString **) $2 = 0x0000000105ea81a0
    (lldb) watchpoint set expression 0x0000000105ea81a0
    Watchpoint created: Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
        new value: 4305584416
    (lldb) watchpoint list
    Number of supported hardware watchpoints: 4
    Current watchpoints:
    Watchpoint 2: addr = 0x105ea81a0 size = 8 state = enabled type = w
        new value: 4305584416
    (lldb) 
    

    4. 断点后执行指令

    (lldb) break command add 1
    Enter your debugger command(s).  Type 'DONE' to end.
    > p self //回车
    > p self.models //回车
    > DONE //回车
    

    在1组处打了断点,断点执行到1后会执行p self等指令
    breakpoint command list查看断点 用法和breakpoint一样

    5. 查看堆栈信息

    • 函数调用栈:bt
    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
      * frame #0: 0x000000010092e388 001--LLDB`-[ViewController touchesBegan:withEvent:](self=0x0000000100e69740, _cmd="touchesBegan:withEvent:", touches=0x0000000100fa54d0, event=0x0000000100f644d0) at ViewController.m:85
        frame #1: 0x000000018ea61870 UIKit`forwardTouchMethod + 340
        frame #2: 0x000000018e9077c8 UIKit`-[UIResponder touchesBegan:withEvent:] + 60
        frame #3: 0x000000018e901830 UIKit`-[UIWindow _sendTouchesForEvent:] + 1892
        frame #4: 0x000000018e8f68f8 UIKit`-[UIWindow sendEvent:] + 3160
        frame #5: 0x000000018e8f5238 UIKit`-[UIApplication sendEvent:] + 340
        frame #6: 0x000000018f0d6c0c UIKit`__dispatchPreprocessedEventFromEventQueue + 2340
        frame #7: 0x000000018f0d91b8 UIKit`__handleEventQueueInternal + 4744
        frame #8: 0x000000018f0d2258 UIKit`__handleHIDEventFetcherDrain + 152
        frame #9: 0x0000000184af7404 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
        frame #10: 0x0000000184af6c2c CoreFoundation`__CFRunLoopDoSources0 + 276
        frame #11: 0x0000000184af479c CoreFoundation`__CFRunLoopRun + 1204
        frame #12: 0x0000000184a14da8 CoreFoundation`CFRunLoopRunSpecific + 552
        frame #13: 0x00000001869f7020 GraphicsServices`GSEventRunModal + 100
        frame #14: 0x000000018e9f578c UIKit`UIApplicationMain + 236
        frame #15: 0x000000010092e54c 001--LLDB`main(argc=1, argv=0x000000016f4d79d8) at main.m:14
        frame #16: 0x00000001844a5fc0 libdyld.dylib`start + 4
    
    • 查看某一个函数: frame select 1
    • 查看上一个函数:(lldb) up
    • 查看下一个函数:(lldb) down
    • 查看参数:
    (lldb) frame variable
    (ViewController *) self = 0x0000000100e69740
    (SEL) _cmd = "touchesBegan:withEvent:"
    (NSSet *) touches = 0x0000000100fa54d0
    (UIEvent *) event = 0x0000000100f644d0
    (NSString *) str = 0x0000000100e96820
    (Person *) p1 = 0x0000000100faa7b0
    (lldb) p str = @"xxx";
    (lldb) po str
    xxx
    
    • 回滚上一个函数并不再执行:thread return

    6. stop-hook

    在每次断住程序的时候去执行一些命令,只对breadpoint,watchpoint生效

    (lldb) target stop-hook add -o "frame variable"
    Stop hook #1 added.
    (lldb) target stop-hook list
    Hook: 1
      State: enabled
      Commands: 
        frame variable
    

    当某个断点触发后,会执行"frame variable"指令
    target stop-hook用法和breakpoint 一样,list查看,delete删除 删除某组还可以用(lldb) undisplay 1
    还可以用配置文件,不用每次运行Xcode都要写指令:
    找到.lldbinit或者touch .lldbinit在此文件中配置自己的指令。

    4.png
    vim .lldbinit然后target stop-hook add -o "frame variable"保存退出,用cat .lldbinit可以看到target stop-hook add -o "frame variable"

    7. image lookup查看库,类和崩溃等信息

    (lldb) help image lookup
         Look up information within executable and dependent shared library images.
    
    Syntax: 
    
    Command Options Usage:
      target modules lookup [-Av] -a <address-expression> [-o <offset>] [<filename> [<filename> [...]]]
      target modules lookup [-Arv] -s <symbol> [<filename> [<filename> [...]]]
      target modules lookup [-Aiv] -f <filename> [-l <linenum>] [<filename> [<filename> [...]]]
      target modules lookup [-Airv] -F <function-name> [<filename> [<filename> [...]]]
      target modules lookup [-Airv] -n <function-or-symbol> [<filename> [<filename> [...]]]
      target modules lookup [-Av] -t <name> [<filename> [<filename> [...]]]
    
           -A ( --all )
                Print all matches, not just the best match, if a best match is
                available.
    
           -F <function-name> ( --function <function-name> )
                Lookup a function by name in the debug symbols in one or more
                target modules.
    
           -a <address-expression> ( --address <address-expression> )
                Lookup an address in one or more target modules.
    
           -f <filename> ( --file <filename> )
                Lookup a file by fullpath or basename in one or more target
                modules.
    
           -i ( --no-inlines )
                Ignore inline entries (must be used in conjunction with --file or
                --function).
    
           -l <linenum> ( --line <linenum> )
                Lookup a line number in a file (must be used in conjunction with
                --file).
    
           -n <function-or-symbol> ( --name <function-or-symbol> )
                Lookup a function or symbol by name in one or more target modules.
    
           -o <offset> ( --offset <offset> )
                When looking up an address subtract <offset> from any addresses
                before doing the lookup.
    
           -r ( --regex )
                The <name> argument for name lookups are regular expressions.
    
           -s <symbol> ( --symbol <symbol> )
                Lookup a symbol by name in the symbol tables in one or more target
                modules.
    
           -t <name> ( --type <name> )
                Lookup a type by name in the debug symbols in one or more target
                modules.
    
           -v ( --verbose )
                Enable verbose lookup information.
         
         This command takes options and free-form arguments.  If your arguments
         resemble option specifiers (i.e., they start with a - or --), you must use
         ' -- ' between the end of the command options and the beginning of the
         arguments.
    
    'image' is an abbreviation for 'target modules'
    
    • 查看崩溃信息
      比如数组越界的崩溃信息:
    *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 4 beyond bounds [0 .. 2]'
    *** First throw call stack:
    (0x184b4ed8c 0x183d085ec 0x184ae7750 0x184ad48cc 0x1007ae328 0x18ea61870 0x18e9077c8 0x18e901830 0x18e8f68f8 0x18e8f5238 0x18f0d6c0c 0x18f0d91b8 0x18f0d2258 0x184af7404 0x184af6c2c 0x184af479c 0x184a14da8 0x1869f7020 0x18e9f578c 0x1007ae52c 0x1844a5fc0)
    libc++abi.dylib: terminating with uncaught exception of type NSException
    

    用image lookup -a查看信息,找到崩溃的方法-[ViewController touchesBegan:withEvent:]

    (lldb) image lookup -a 0x184b4ed8c
          Address: CoreFoundation[0x0000000180ef6d8c] (CoreFoundation.__TEXT.__text + 1313804)
          Summary: CoreFoundation`__exceptionPreprocess + 228
    (lldb) image lookup -a 0x1007ae328 
          Address: 001--LLDB[0x0000000100006328] (001--LLDB.__TEXT.__text + 1796)
          Summary: 001--LLDB`-[ViewController touchesBegan:withEvent:] + 160 at ViewController.m:86
    (lldb) image lookup -a 0x18ea61870
          Address: UIKit[0x000000018ae09870] (UIKit.__TEXT.__text + 3699592)
          Summary: UIKit`forwardTouchMethod + 340
    
    • 查看类信息
      image lookup -t Person
    • image list查看当前用到的库

    8. 其他指令

    • 单步运行(子函数当成整体):n
    • 单步运行(进入子函数):s
    • 汇编的单步(子函数当成整体):ni
    • 汇编的单步(进入子函数):si


      3.png

    相关文章

      网友评论

        本文标题:iOS 逆向-macho文件和LLDB

        本文链接:https://www.haomeiwen.com/subject/onxvrftx.html