This series is a compilation of my early listening to MJ’s class. Some of the references are quoted, and some may have forgotten to add. If there are some references, please contact me.

IOS Reverse (1) Environment setup iOS Reverse (2) Cycript iOS Reverse (3) Reverse tool iOS Reverse (4) Unshell audit iOS Reverse (5) Theos tool iOS Reverse (6) Dynamic debugging iOS reverse (7) re-signature

What is dynamic debugging

To run the program, through breakpoints, print, and so on, to view parameters, return values, function call flow, and so on.

1.1 Principle of Xcode debugging APP

The LLDB debugger is built in Xcode. Through the connection with iPhone, the debugServer program is installed on iPhone. The DEBUgServer and LLDB communicate with each other, sending debugging instructions and receiving results.

    • Xcode compiler development history: GCC– >LLVM
    • Xcode debugger evolution: GDB– >LLDB
  • The debugServer is initially stored in Mac Xcode
    • /Applications/

ViceSupport / 9.1 / DeveloperDiskImage. DMG/usr/bin/debugserver

  • When Xcode identifies a mobile device, Xcode automatically installs the DebugServer on the iPhone

    • /Developer/usr/bin/debugserver
  • Limitations of Xcode debugging

    • In general, only apps installed through Xcode can be debugged
  • LLDB debugging, see iOS Debugging (2) LLDB

1.2 Principle of dynamic debugging of other Apps

How to debug dynamically

2.1 Permission Problems of the DebugServer

  • By default,/Developer/usr/bin/debugserverLack of certain permissions, can only debug apps installed through Xcode, cannot debug other apps (such as apps downloaded through the APP Store)
  • If you want to debug other apps, you need to re-sign the debugServer and sign two debugging permissions:
    • get-task-allow
    • task_for_pid-allow

2.2 Signing permissions to the DebugServer

The tool used for the signature, LDID, can also be used with CoDesign. The command lDID described earlier is used here.

2.2.1 copydebugserverTo the Mac

IPhone Developer directory is read-only and cannot be directly to/Developer/usr/bin/debugserver file signature, need to copy debugserver to the Mac

2.2.2 Exporting Original Rights

Run the lDID command to export the previous signature permission of the file

$ ldid -e debugserver > debugserver.entitlements
Copy the code

2.2.3 Adding a Permission

Entitlements add get-task-allow and task_for_pID-allow permissions to debugServer. entitlements add get-task-allow and task_for_pid-allow permissions to:

2.2.4 heavy signature

$ ldid -Sdebugserver.entitlements debugserver
Copy the code

Save the debugserver that has been signed to the /usr/bin directory so that you can run the command directly

Codesign command // View permission information codesign− D −− Entitlements − Debugserver // Signature coDesign -d — Entitlements – Debugserver // Signature CoDesign − D −− Entitlements − Debugserver // Signature CoDesign – F-S – — Entitlements Debugserver. // Signature is $COdesign-fs – — Entitlements Debugserver. Entitlements Debugserver

2.3 Setting up the DebugServer Environment

2.3.1 Insufficient Permissions

// Insufficient permission 5s:~ root# debugServer -sh: /usr/bin/debugserver: Permission denied // Add running Permission 5s:~ root# chmod +x /usr/bin/debugserverCopy the code

2.3.2 Attaching to a Process

debugserver Usage:

debugserver host:port [program-name program-arg1 program-arg2 …] debugserver /path/file [program-name program-arg1 program-arg2 …] debugserver host:port –attach= debugserver /path/file –attach= debugserver host:port –attach=<process_name> debugserver /path/file –attach=<process_name>

Debugserver *: port number -a processCopy the code
  • * : the port number

Start the DebugServer service with an iPhone port number (not a reserved port number)

  • – a process

The process ID or name of the app

Here, attach to wechat process with port number 10086:

Note: This is the port number, and then the connection must be established through Mac LLDB.

5s:~ root# debugserver *:10086 -a WeChat
Attaching to process WeChat...
Listening to port 10086 for a connection from *...
Copy the code

Once connected, the iPhone port 10086 listens for programs that connect to the port, as shown above.

2.3.3 LLDB Connects to the DebugServer

  • Start the LLDB ` ` ` bash

$ lldb

##### Python 2.7 bash $LLDB Traceback (most recent call last): File "<string>", line 1, in <module> File "/Applications/", line 98, in <module> import six ImportError: No module named six ....Copy the code

If the above error occurs, try this scheme:

$ brew reinstall python@2
$ pip install six
Copy the code

If PIP encounters the following error, try the scheme on my current system 10.14, Xcode 10:

Traceback (most recent call last):
  File "/usr/local/bin/pip", line 11, in <module>
ImportError: No module named zlib
Copy the code

The solution is as follows:

  1. brew update
  2. Download Command Line Tools for Xcode 10 and install it.
  3. brew reinstall python@2

After that, I started again and still encountered an error:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/ usr/local/Cellar/python / 2.7.15 @ 2 _1 / Frameworks/python framework Versions / 2.7 / lib/python2.7 / copy. Py." ", line 52, in <module>
    import weakref
  File "/ usr/local/Cellar/python / 2.7.15 @ 2 _1 / Frameworks/python framework Versions / 2.7 / lib/python2.7 / weakref. Py." ", line 14, in <module>
    from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Copy the code

Here’s the plan.

Reboot again, perfect!

  • Connect to the debugServer service

(LLDB) Process Connect connect:// Mobile PHONE IP address: debugServer service port number

Here, because the open port above is 10086, the connection needs to wait, the output is as follows: ` ` ` bash (LLDB) process the connect connect: / / process 1844 stopped * thread # 1, queue = '', stop reason = signal SIGSTOP frame #0: 0x0000000198420a40 libsystem_kernel.dylib`mach_msg_trap + 8 libsystem_kernel.dylib`mach_msg_trap: -> 0x198420a40 <+8>: ret libsystem_kernel.dylib`mach_msg_overwrite_trap: 0x198420a44 <+0>: mov x16, #-0x20 0x198420a48 <+4>: svc #0x80 0x198420a4c <+8>: ret Target 0: (WeChat) stopped.Copy the code
  • Optimized the connection to the DebugServer

We are now connected via WiFi, but we can also connect via USB. In our previous script, the script address: bash

This is a comment too

echo ‘———————————————‘ echo ‘SSH login’ echo ‘mac port 10010 connect to iPhone port 22’ echo ‘———————————————‘ echo ‘lldb connect debugserver by mac port 9999 to iPhone port 10086’ echo ‘1. In iPhone: debugserver *:10086 -a App name’ echo ‘2. In Mac: enter lldb’ echo ‘3. In Mac: process connect connect://localhost:9999’ echo ‘———————————————‘ iproxy 10010 22 & iproxy 9999, 10086,

Now, we change the command to connect to the debugserver to: ' '(LLDB) process connect connect://localhost:9999Copy the code
  • Continue to run the program

(lldb) c Process 1844 resumin

Now you can debug your App directly and dynamically using LLDB on your Mac. 1. The Mac call script '' connects the phone via USB; 2. The Mac invokes the script '' to login to the mobile phone. 3. On the mobile phone, the debugServer connects to the running APP. ``` 5s:~ root# debugserver *:10086 -a WeChatCopy the code
  1. On a Mac, LLDB connects to debugServer: bash

$ lldb (lldb) process connect connect://localhost:9999 (lldb) c

5. Debugging..... ASLR Address Space Layout Randomization ASLR Address Space Layout Randomization ASLR is a security protection technology against buffer overflow. By randomizing the layout of linear areas such as heap, stack and shared library mapping, it increases the difficulty of the attacker to predict the destination address and prevents the attacker from locating the attack code directly, so as to prevent overflow attacks. - Mach-O File address layout: Mach-O does not run, does not map to memory, in the file address space; - Mach-o does not use ASLR's memory layout: Mach-o runs, but maps to the address space in memory; - Mach-o uses ASLR memory layout: Mach-O runs with ASLR mapped to the address space in memory; ☞ ** For more information on MACH-O **, Refer to [] Mach - O (1) structure ( and [the Mach - O (2) the distribution of memory] ( The following example uses the 'Segment' of the mach-o File as an example. One Segment: -file Offset: Segment Offset address -file Size: segment Size** Calculation: next segment address File Offset = previous segment Offset + File Size**  | Segment | File Offset | File Size | | --- | --- | --- | | __PAGEZERO | 0x0 | 0x0 | | __TEXT | 0x0 | 0x3910000 | | __DATA | 0 x3910000 | 0 xca8000 | | __LINKEDIT | 0 x45b8000 | 0 x3ab210 | computing __LINKEDIT Offset = __DATA Offset + __DATA Size 0X45B8000 = 0x3910000 + 0xCA8000 The Segment's File Offset and File Size are not used. So memory layout, what we call virtual memory layout, what we call memory in development, is all virtual memory allocated by the system, and the system maps virtual memory to real physical memory, so we don't have to worry about that. ASLR is not used for memory layout, which is determined by **VM Address** and **VM Size** in the Mach-o file. -vm Address: virtual memory start Address, -vm Size: virtual memory Size.  | Segment | VM Address | VM Size | File Offset | File Size | | --- | --- | --- | --- | --- | | __PAGEZERO | 0X0 | 0x100000000 | 0x0 | 0x0 | | __TEXT | 0x100000000 | 0x3910000 | 0x0 | 0x3910000 | | __DATA | 0x103910000 | 0xD48000 | 0 x3910000 | 0 xca8000 | | __LINKEDIT | 0 x104658000 | 0 x3ac000 | 0 x45b8000 | 0 x3ab210 | form accordingly, we draw the following graph:! []( Bject %20Object%5D&originHeight=1040&originWidth=1880&status=done&style=none&width=1880) - __PAGEZERO the size is 0x100000000, which is fixed. - arm64:0x100000000 (8 zeros) - non-arm64:0x4000 (3 zeros) - the size of the __TEXT segment remains unchanged after loading memory, and the function code is stored in the __TEXT segment; - The memory Address of the code segment, such as the VM address-__data segment in LC_SEGMENT(__TEXT), will take up more space when loading into the memory, because the system virtual memory will be aligned to improve the scheduling rate; Use 'size-L-m-x WeChat' to check the memory distribution of the mach-o process at run time The Offset generated randomly by ASLR is 0x3500! []( Bject %20Object%5D&originHeight= 1062&OriginWidth =1898&status=done&style=none&width=1898) - function memory Address (VM Address) = File Offset + ASLR Offset + __PAGEZERO Size - Hopper, IDA Address is not using ASLR VM Address - ```bash (lldb) image list -f -oCopy the code