• 转载一篇debug文章


    http://versprite.com/og/ios-reverse-engineering-part-two-debugging-and-tracing-with-lldb/

    iOS Reverse Engineering Part Two: Debugging and Tracing with LLDB

    Overview

    In our previous post – http://versprite.com/og/ios-reverse-engineering-part-one-configuring-lldb/ – we learned how to configure and setup debugserver and LLDB on your iOS device. In this post we will demonstrate how to use LLDB to perform basic debugging and message tracing.

    objc_msgSend()

    This topic has already been covered numerous times, but lets run through a refresher on Objective-C’s objc_msgSend(). This function is one of the more important items within the libobjc.A.dylib library. During runtime objc_msgSend() is used to send messages to an object within memory. This can be considered the equivalent to calling functions in C.

    The compiler will convert a message expression – [receiver message] into a call on objc_msgSend(). When we take a look at the objc_msgSend() declaration:

    id objc_msgSend (id self, SEL op, arg1, arg2 ..)

    We see as parameters it takes a pointer to the instance of the class that is to receive the message, and the selector of the method that handles the message. objc_msgSend() takes the id type, which is literally just a pointer to a C struct, being identified as objc_object. After an object is created, memory is allocated for the objc_object type that consists if an isa pointer, which is followed by the data for that object. In this usage, the id type is basically a pointer to the receiver’s class instance in memory.

    The second argument SEL, is pretty much the method’s signature string representation. Whew! Hopefully this is making a bit of sense, and now we can move into learning about ARM, and the Procedure Call Standard for the ARM Architecture.

    ARM Calling Conventions

    The ARM architecture contains 16 registers numbered r0 – r15, each 32-bits wide. The procedure call standard state that the first four registers (r0 – r3) are used to pass argument values into a subroutine and to return a result value from a function.

    The prolog for a function call goes something like this:

    – PUSH the value of the link register (LR)(r14) to the stack
    – PUSH the value of the frame pointer (r7) to the stack
    – Update the frame pointer to the value of the stack pointer (SP)
    – PUSH the preserved registers to the stack
    – Make space for local storage

    An example might look like this:

    push    {r4-r7, lr} // save LR, R7, R4-R6
    add     r7, sp, #12 // adjust R7 to point to saved R7
    push    {r8, r10, r11} // save remaining GPRs (R8, R10, R11)
    vstmdb  sp!, {d8-d15} // save VFP/Advanced SIMD registers D8
    sub     sp, sp, #36 // allocate space for local storage
    

    objc_msgSend() Tracing

    In order to start tracing objc_msgSend(), let us combine everything we have learned so far. We know from the declaration that objc_msgSend() takes two parameters, which point to the class instance and method signature. We also know from the ARM calling conventions, that the registers r0, and r1 will probably contain those respective values being passed into the objc_msgSend() function.

    We will be using the Damn Vulnerable iOS App for demonstration. The first thing I am going to do is set breakpoint at [InsecureDataStorageVulnVC saveinPlistFileTapped:], because I only really wanna to trace the objc_msgSend() calls within this subroutine.

    (lldb) b -[InsecureDataStorageVulnVC saveInPlistFileTapped:] Breakpoint 1: where = DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:], address = 0x000e5c2c
    

    Now when we venture over to the application and attempt to save our data in the Plist file:

    * thread #1: tid = 0x145aa, 0x000d0c2c DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:], queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
        frame #0: 0x000d0c2c DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]
    DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]:
    -> 0xd0c2c:  push   {r4, r5, r6, r7, lr}
       0xd0c2e:  add    r7, sp, #0xc
       0xd0c30:  push.w {r8, r10, r11}
       0xd0c34:  sub    sp, #0xc

    To start tracing the objc_msgSend() calls within this subroutine let us disassemble where we are currently located.

    (lldb) di
    DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]:
    -> 0xd0c2c:  push   {r4, r5, r6, r7, lr}
       0xd0c2e:  add    r7, sp, #0xc
       0xd0c30:  push.w {r8, r10, r11}
       0xd0c34:  sub    sp, #0xc
       0xd0c36:  mov    r4, r0
       0xd0c38:  movs   r0, #0x9
       0xd0c3a:  movs   r1, #0x1
       0xd0c3c:  movs   r2, #0x1
       0xd0c3e:  blx    0x291db0                  ; symbol stub for: NSSearchPathForDirectoriesInDomains
       0xd0c42:  mov    r7, r7
       0xd0c44:  blx    0x291e44                  ; symbol stub for: objc_retainAutoreleasedReturnValue
       0xd0c48:  str    r0, [sp, #0x8]
       0xd0c4a:  movw   r1, #0x76b8
       0xd0c4e:  movt   r1, #0x1d
       0xd0c52:  movs   r2, #0x0
       0xd0c54:  add    r1, pc
       0xd0c56:  ldr    r1, [r1]
       0xd0c58:  blx    0x291e28                  ; symbol stub for: objc_msgSend
       0xd0c5c:  mov    r7, r7
    
    

    We can set a breakpoint at the address 0x291e28 for the objc_msgSend() call.

    (lldb) b 0x291e28
    
    Breakpoint 2: where = DamnVulnerableIOSApp`symbol stub for: objc_msgSend, address = 0x00291e28

    However once we hit this breakpoint, we need to perform additional inspection. We can do this by adding a stop-hook:

    (lldb) target stop-hook add
    Enter your stop hook command(s).  Type 'DONE' to end.
    > register read 
    > x/s $r1 
    > expr -o -- $r0 
    > DONE
    Stop hook #1 added.
    

    Through this stoop-hook we will read the values in the current registers, examine the contents of r1 as a string, and print the object description of the pointer located in r0. Remember r1 should contain the selector and r0 should contain the class instance.

    After resuming execution, we hit the next breakpoint that we have set, and our stoop-hook is invoked.

    General Purpose Registers:
            r0 = 0x176f6d70
            r1 = 0x335c9122  "objectAtIndex:"
            r2 = 0x00000000
            r3 = 0x00000000
            r4 = 0x176d50d0
            r5 = 0x001402bf  "saveInPlistFileTapped:"
            r6 = 0x175d8d30
            r7 = 0x27d40528
            r8 = 0x17664620
            r9 = 0x00000000
           r10 = 0x175f1180
           r11 = 0x00000000
           r12 = 0x3d47f1d0  (void *)0x3b627959: _os_lock_handoff_unlock$VARIANT$mp + 1
            sp = 0x27d40504
            lr = 0x000d0c5d  DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:] + 49
            pc = 0x00291e28  DamnVulnerableIOSApp`symbol stub for: objc_msgSend
          cpsr = 0x40000010
    
    0x335c9122: "objectAtIndex:"
    <__NSArrayI 0x176f6d70>(
    /var/mobile/Applications/04A94C51-51CD-4633-9649-ACE1BCCFED72/Documents
    )

    Everything looks to be working, now we have a little homemade tracer, and can start moving through the rest of the calls.

    General Purpose Registers:
            r0 = 0x3b7b8df4  (void *)0x3b7b8dcc: NSMutableDictionary
            r1 = 0x380953cd  "alloc"
            r2 = 0x002aa198  (void *)0x3b7b8df4: NSMutableDictionary
            r3 = 0x00000001
            r4 = 0x176d50d0
            r5 = 0x001402bf  "saveInPlistFileTapped:"
            r6 = 0x175d8d30
            r7 = 0x27d40528
            r8 = 0x17664620
            r9 = 0x17902868
           r10 = 0x175f1180
           r11 = 0x00000000
           r12 = 0x3b011479  libobjc.A.dylib`-[NSObject autorelease] + 1
            sp = 0x27d40504
            lr = 0x000d0ca3  DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:] + 119
            pc = 0x00291e28  DamnVulnerableIOSApp`symbol stub for: objc_msgSend
          cpsr = 0x60000010
    
    0x380953cd: "alloc"
    NSMutableDictionary

    https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/lldb-command-examples.html

  • 相关阅读:
    423. Reconstruct Original Digits from English
    400. Nth Digit
    397. Integer Replacement
    396. Rotate Function
    365. Water and Jug Problem
    335. Self Crossing
    319. Bulb Switcher
    线段树-hdu2795 Billboard(贴海报)
    线段树---求逆序数
    线段树——单点替换区间最值
  • 原文地址:https://www.cnblogs.com/studyNT/p/4591047.html
Copyright © 2020-2023  润新知