iOS Tampering Techniques Part 1 — Introduction to run-time tampering through THEOS

Max chee
CSG @ GovTech
Published in
5 min readJul 2, 2020

Introduction to run-time tampering

I will be sharing about how attackers can conduct run-time tampering (also known as hooking) on iOS in a two-part series. Run-time tampering, as the name suggests, refers to an unsolicited modification of mobile applications as the apps are running. In particular, I will focus on iOS hooking attacks that use a tool called THEOS.

In Part 1 of the series, I’ll introduce the basics of run-time tampering while Part 2 of the series focuses on advanced run-time tampering techniques.

Part 1 will be in three sections:

  • Section 1 introduces THEOS and explains why it is my preferred tool.
  • Section 2 demonstrates the techniques required to craft tweaks in THEOS to target the two iOS programming languages, Objective-C and Swift; and
  • Section 3 describes measures that developers can adopt to mitigate such hooking attacks

Section 1: What is THEOS and why use it?

THEOS is a tool that enables users to conduct run-time tampering by building patches on jailbroken devices. It requires Cydia Substrate (available through Cydia) and is usually packaged with jailbreak applications.

By creating a tweak through THEOS, a dynamic library (.dylib) will be inserted into the iOS device. When a mobile application is launched, Cydia Substrate’s MobileLoader then inserts itself into running applications. Upon insertion, it loads dynamic libraries specific to the application bundle that are used to override method invocations.

Find out more about how the dynamic library is invoked by referring to Apple’s documentation or Cydia Substrate Wiki.

My colleagues and I prefer to use THEOS in our testing due to the relative limitations of other similar tools. Although mobile testing frameworks such as OWASP’s MSTG (Mobile Security Testing Guide) recommend using tools like Cycript and Frida to conduct run-time tampering, these tools only work well with Objective-C (Cycript) or have few examples on how to get started (Frida).

Section 2: Understanding iOS languages (Objective-C and Swift)

There are two main languages used in iOS development: Objective-C and Swift. In this segment, I will introduce aspects of the two languages that are relevant to run-time tampering.

For applications written in Objective-C, the convention is to implement interface (.h) and implementation (.m) files. In the following example, the Objective-C class, MyClass, contains two files, specifically MyClass.h and MyClass.m. Before we can conduct run-time tampering on Objective-C, we need to first extract the header (.h) file from the application.

By using various class dump tools, such as dsdump and class-dump, we can inspect the class function name, parameters and return type.

Figure 1. MyClass.h Header file
Figure 2. MyClass.m Implementation file

To allow interoperability between Objective-C and Swift programming language, Swift code can be imported into Objective-C through the use bridging headers, In the subsequent example, the swift class (.swift) JailbreakDetectionViewController has a jailbreak function (isJailBroken) and returns a Boolean variable.

To expose Swift functions to existing Objective-C code base, a bridging header(.h) has to implement the interface structure as shown below.

Figure 3. Swift jailbreak code taken from DVIA-V2
Figure 4. Header file taken from DVIA-V2

I will now demonstrate the technique to craft tweaks in THEOS targeting the two languages — starting with Objective C.

Run-time tampering targeting Objective-C

Due to the nature of how Objective-C is built, it allows method invocations to be changed during run time through method swizzling.

Here is a sample code showing how Objective-C hooking can be conducted on MyClass, with the use of Logos functionality in THEOS:

Figure 5. Theos tweak to hook method (sayGoodnightGracie)

In this example, the tweak can be broken down as such:

Run-time tampering targeting Swift

As Swift becomes an increasingly popular programming language, it has also become more interesting to attackers who will update their Tactics, Techniques, and Procedures (TTP). For Swift applications that are configured with symbols, swift hooking can be done by first locating the mangled names through the Unix command nm <app name> (refer to Figure 6).

In this example, I use DVIA-V2, a vulnerable iOS mobile application, to demonstrate bypassing of jailbreak detection in Swift.

Figure 6. Jailbreak detection method implemented in DVIA-V2

The mangled name “__T07DVIA_v232JailbreakDetectionViewControllerC12isJailbrokenSbyF” can be broken down into the following components:

Based on the mangled name, attackers can create a THEOS tweak by providing the original jailbreak detection function’s name (__T07DVIA_v232JailbreakDetectionViewControllerC12isJailbrokenSbyF) and the new implementation method (hook_ViewController_isJailBroken).

Figure 7. Tweak to bypass jailbreak detection in DVIA-V2

In this example, the tweak can be broken down as such:

Running the tweak on the jailbroken device also shows that the mobile application DVIA-V2 no longer detects the phone as being jailbroken.

Figure 8. Jailbreak detection bypassed

Section 3: Measures to mitigate Run-time tampering

Developers can prevent run-time tampering of iOS mobile applications by implementing multiple in-line checks. For example, developers can call up the functions dyld_image_count and dyld_get_image_name to detect extra dynamic libraries and string instances of Frida library names.

Developers should also be aware that a skilled attacker would be able to locate and bypass these detection checks and resources stored locally on the mobile device are susceptible to run-time tampering. As such, critical resources should always seek server-side validation and should not be stored locally on the end user’s mobile device.

Enjoyed this short read? Join us in Part 2 of this series, where we dive deeper into advanced run-time tampering techniques.

--

--