IOS reverse engineering: Hopper + LLDB debugging third-party App, javasperlldb

Source: Internet
Author: User

IOS reverse engineering: Hopper + LLDB debugging third-party App, javasperlldb

LLDB is short for Low Level Debugger. LLDB is often used in iOS debugging, and LLDB is a built-in dynamic debugging tool of Xcode. You can use LLDB to debug your application dynamically. If you do not perform other operations, you can only use LLDB to debug your own App because the debugserver lacks the task_for_pid permission. In this blog, we need to use LLDB to debug apps downloaded and installed from the AppStore, and use Hopper to analyze the internal structure of third-party apps. The combination of LLDB and Hopper will let you see different things. This blog will share with you the charm of LLDB and Hopper.

  I. SSH USB connection-USB muxd

Previously, we connected iOS devices through ssh Through the LAN, that is, WiFi. When the network environment is poor, input a command line card, therefore, we need a faster way to access the iOS device, that is, using a USB connection. In this blog, whether we connect iOS devices through SSH or connect to iOS devices through LLDB, we use USB to access devices, which means the speed will not work. The first part of this blog is to introduce how to use USB for device SSH connection. This part is also the basis of this blog, but the content is still simple.

1. Obtain usbmuxd

Although the latest version of usbmuxd is 1.1.0, version 1.1.0 and version 1.0.9 only support Linux, that is to say, we have to download version v1.0.8 Mac, (usbmuxd-v1.0.8 ). After the download, decompress the downloaded file. The content is as follows:


 

2. Use USB muxd to connect to the iOS jailbreak device (1) Use the USB muxd forwarding Interface

Switch to the python-client directory in the preceding folder and run the following command to forward port 22 on iOS to port 2221 on the current device, as shown below.

./tcprelay.py -t 22:2221

The following is the result of executing the preceding command:


 

(2) connect to the jailbreak Device Using ssh

ssh root@localhost -p 2222

The above command is followed by the command-p for ssh connection by the above-mentioned forwarding port. After executing the command, the result is as follows:


You can use USB muxd to connect to our iOS jailbreak device. The LLDB below connects to the iOS device through USB. For more information, see the following section.

 

Ii. Configure debugserver

During iOS development, you can enter the LLDB command on the Mac to control the iOS App because there is a debugserver server in our iOS client. Debugserver is used to connect to the Mac LLDB client, receive commands provided by LLDB, and execute the commands accordingly. If your iOS device has been debugged on a real machine, the device will be installed with debugserver, but the debugserver can only be used to debug your own applications. If you want to debug the App obtained from the AppStore, you need to process the debugserver on the iOS device. This part is to process our debugserver.

1. Get debugserver

First, we need to find the debugserver In the iOS device and copy it to the Mac for processing. below is the debugserver in the/Developer/usr/bin directory. This debugserver only supports debugging our own apps. If you need to debug apps of others, you need to process the debugserver. The process is described below.


 

2. debugserver slimming

lipo -thin arm64 debugserver -output debugserver

Go to the directory where debugserver is located in Mac and execute the above command. After-thin, enter the corresponding ARM architecture of your testing machine, because my testing machine is iPhone 6 Plus, it is the arm64 architecture, so the parameter here is arm64. If you are an iPhone 5 device, it is armv7s.

 

3. Add the task_for_pid permission to debugserver.

After adding the task_for_pid permission to the debugserver, we can use LLDB to debug other apps. In this section, we need an xml file that stores configuration information. The content of this file is as follows. You can copy the text below and store it as ent. xml.

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>com.apple.springboard.debugapplications</key>
        <true/>
        <key>get-task-allow</key>
        <true/>
        <key>task_for_pid-allow</key>
        <true/>
        <key>run-unsigned-code</key>
        <true/>
</dict>
</plist>

When the debugserver is authorized, we need to use the ldid command. If the ldid command is not installed on your Mac, use brew to install it. Execute the command line below to grant the task_for_pid permission to our debugserver. Note that-S and ent. xml file names do not contain spaces.

ldid -Sent.xml debugserver

The following describes how to process debugserver:


 

4. Copy the debugserver to the iOS device.

The last step is to copy the processed debugserver to our jailbreak device and grant the executable permission to the debugserver. Because the debugserver in the/Developer/usr/bin directory is read-only, you cannot copy the processed debugserver to the preceding file, you need to copy the processed debugserver to the/usr/bin/directory (Here we use IFunBox to copy the file ).

Copy the debugserver to the/usr/bin directory, execute the command assigned permissions below, and grant the executable permissions to the debugserver, as shown below:

chmod +x debugserver

After assigning permissions, you can use the debugserver command to enable debuserver, as shown below:


 

3. Enable connection between debugserver and LLDB 1. Enable debugserver

In the jailbreak device, we can enable the debugserver through the command line below. Here we take the App debugging as an example. The command below is to start debugserver to listen for access from any IP address. The access port of the iOS device is 12345, and the App to be debugged is WeChat ". The command is as follows:

debugserver *:12345 -a "WeChat"

The effect of executing the above command on our iOS device is as follows. After executing the above command, our iOS device will wait for the access of the Mac terminal LLDB.


2. LLDB connects to debugserver

LLDB can connect to debugserver using WIFI, but WIFI is unstable and extremely slow. Therefore, we need to use usbmuxd to connect LLDB to debugserver.

(1) port forwarding

Similar to the content in the first part, we use usbmuxd to forward the port and connect the above "12345" port to a local port of the Mac. Here we use port 12345. Go to the python-client under the usbmuxd-1.0.8 directory and execute the command below.

./tcprelay.py -t 12345:12345

The procedure is as follows:


 

(2) Access to Mac LLDB

After port forwarding, we start to enter the lldb mode and then connect to the debugserver. First, enter the lldb command on terminal, and then enter the address below to connect. Because we use USB muxd for port forwarding, we can use the local loop test address to connect to the debugserver.

process connect connect://127.0.0.1:12345

The following figure shows the connection result. After LLDB and debugserver are established, we can use lldb to debug this application.


 

Iv. Hopper + LLDB

In the previous blog, "iOS reverse engineering: Shelling WeChat", we have already implemented shelling. Therefore, it is no problem to use Hopper for processing. In this part, we need to combine Hopper and LLDB to make full use of them. This part is also part of the practice in this blog.

1. View WeChat in the thread

After LLDB connects to debugserver, we first use the following command to view all modules in the current process. From the output information, we can find the offset of the "WeChat" Process in the virtual memory to the module base address.

image list -o -f

After lldb connects to the debugserver, some output results are as follows. In the lower part, the first one is information about the "WeChat" program. The red box on the left is the ASLR offset (random offset). The ASLR offset is actually the actual address of the virtual memory, and the offset relative to the base address of the module. The address in the red box on the right is the address after the offset.

The introduction of address is to familiarize yourself with the two concepts of the lower-end OPERATOR:

  • Module start address in memory ---- Module Base Address
  • ASLR offset-the offset between the starting address of the virtual memory and the base address of the module

From the output result below, we can know that the ASLR offset is 0x5b000, and the base address after the module offset is 0x5f000.


 

The following is the decrypted installation package opened by Hopper. The starting address is 0x4000, which is the address before the module offset, that is, the starting address of the module in the virtual memory. From Hopper, we can know that the base address before the module offset is 0x4000.


From the above two groups of data, we can conclude that:

Base address after module offset (0x5f000) = ASLR offset (0x5b000) + base address before module offset (0x4000)

The above formula is particularly important, because the Hopper shows "module offset base address", while LLDB requires "module offset base address ". Therefore, from Hopper to LLDB, we need to convert the address offset. This will be used multiple times below. Of course, it should be noted that the number of bits of the AMR architecture selected by Hopper and LLDB is the same, either 32-bit or 64-bit. If the number of BITs does not match, the calculated memory address is definitely incorrect.

 

2. Use LLDB to add a breakpoint (1) for logon, and analyze before adding a breakpoint

"Breakpoint" is a frequently used item in iOS development. Next we need to add a breakpoint when clicking login to jump to the page. It is to add a breakpoint when you click the logon button on the left to jump to the right page. Now we will add the breakpoint to the initialization method on the right page.

WCAccountPhoneLoginControlLogic, from the class name, we can easily infer that this class is most likely the "Mobile Account Logon" page we are looking.


After the above analysis, we decided to add a breakpoint for the class "initWithData" (which must be an initialization method) using LLDB.

 

(2) locate the breakpoint address

After finding the method in the class for adding a breakpoint, We need to calculate the memory address of the method, and then use LLDB to add a breakpoint to the address. With Hopper, we can easily locate the position of the above "initWithData:" method, as shown below. The base address with an asterisk in the lower part is the base address before the offset of "initWithData. Based on the formula above, we can easily calculate the "base address after offset", that is, the real memory address. The algorithm is as follows:

InitWithData memory address = 0x1304b60 + 0x5b000 (ALSR offset) = 0x135FB60


 

(3) Add a breakpoint

Run the following command to add a breakpoint for the preceding address. After the breakpoint is added, click the logon button to go to the "mobile phone number Logon" page and the breakpoint is executed. The red box below shows the effect of the "breakpoint" operation. From the bottom, we can see that the Breakpoint number is 1, and the Breakpoint is followed by the Breakpoint number. This number will be used to operate the Breakpoint, And the instance will be given below.

br s -a 0x135FB60


 

(4) One-Step breakpoint execution (ni, si)

You can use nexti (abbreviated as ni) and stepi (abbreviated as si) for single-step debugging. Ni will not jump to the jump, and si will jump to the corresponding branch. Below is the single-step debugging through si AND ni.


 

(5) Open and execute this breakpoint (c)

Command c can execute this breakpoint. In this case, if the c command is executed, because there is only one breakpoint, after the breakpoint is executed, it will jump to the "mobile phone number logon page ".

 

(6) Disable and enable breakpoint

As mentioned above, the number of the breakpoint created above is 1. We need to disable and enable the breakpoint. The specific command is as follows:

Br dis 1 -- disable a breakpoint numbered 1

Br en 1 -- enable a breakpoint numbered 1

Br dis -- disable all breakpoints

Br en -- enable all breakpoints

The specific operation result is as follows. When the breakpoint is disabled, clicking the login button will not trigger the breakpoint. When the breakpoint is restarted, clicking the logon button will still trigger the breakpoint. The specific effect is as follows:


 

(7) breakpoint Deletion

Br del 1 -- delete a breakpoint numbered 1

Br del -- delete all breakpoints


 

3. output register value (p, po)

In iOS development, we often use the po command to output the value of a variable or constant when using LLDB for debugging. When using LLDB to debug WeChat, we can also use some commands to output values in registers. We use $ to access the value in a register and print it using the p command. Below is the p command to print the content stored in the r1 register, convert the $ r1 type before printing, and the po command outputs the Objective-C object, p outputs data of the C language type. As follows:


We can also print the value of an address. The following command outputs the value of the address location indicated by the $ sp pointer:

p/x $sp


 

4. Modify the value in the register

We can not only view the values in some registers, but also modify the values in the registers using the following commands.

Register write register value

Next we will use an instance to practice the register write command. By analyzing the login module in Hopper, we can easily find "handleAuthResponse" in the "WCAccountManualAuthControlLogic" class: "method is used to process" login authentication response. That is to say, "handleAuthResponse:" is responsible for processing the network response of the login business logic, and there is a comparison (cmp r0, r1) in front of this function ), jump based on the comparison results of r0 and r1.


The next thing we need to do is to change the value in the r1 register when comparing the values in the registers r0 and r1, and then observe the running effect of the App. Below is the message displayed when you enter your mobile phone number and password. That is, the following dialog box is displayed for the normal process.


What we need to do next is0x1063a24 + 0x5b000 = 0x10BEA24 (cmp)Add a breakpoint for this memory address, and then modify the value of register r1. Below is a breakpoint added to the memory address 0x10BEA24, and after entering the mobile phone number and password, click Login to execute the breakpoint we added, as shown below. We can clearly see the cmp r0 and r1 ARM commands at the break point.


Next, print the values in r0 and r1,$ R0 = 8, $ r1 = 351. Then, we changed the value in $ r1 to 8 and input c to continue the execution. We found that the alter of the previous normal process would not pop up, but instead made a new network request.


 

The above example is made on a 32-bit system. If you are using a arm64-architecture device, such as iPhone6Plus, your address will be doubled from the above address. The two below are labs using the iPhone 6 Plus jailbreak device. They can be compared with the above steps. Although they are different, the above content is also applicable when debugging the following content.



 

Here is the content of this blog. At this point, you should be able to combine LLDB with Hopper. Today, we take "" as an example. It doesn't mean anything else. I just want to implement it in a real instance. The reason for the experiment is that it is safe enough. After all, the team is very strong. After using the jailbreak device to complete the above experiment, the jailbreak device cannot log on to the account anymore. It must have been detected by the background that the "jailbreak device" is abnormal, in this way, some security measures are taken.

"Attack and Defense" is like "spear and shield.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.