purpose

  • In order to further increase the security of the application, prevent our application from being easily analyzed, cracked and repackaged by attackers, and improve the difficulty of reverse analysis of the application by attackers

Application hardening scheme

  • Data encryption: Encryption of static strings, local storage, and network transfers
  • Static obfuscation: confusion of class names, method names, and properties
  • Dynamic protection: reverse debugging, injection detection, hook detection, jailbreak detection, signature detection, etc
  • Code obfuscation: Breaking code up fast, flattening it, and adding intrusive code to make it harder for the analyst to analyze

The following describes the security hardening schemes based on specific application scenarios

  • Data encryption: We already have it in our application. By encrypting the data, we have essentially made reverse analysis more difficult for the attacker, but it is still possible for the attacker to restore the algorithm by means of dynamic debugging or writing IDA scripts.

  • Static obfuscation: the name of a class and the name of a method in a program. In reverse analysis, you can quickly guess the function of a method from the name by obtaining all classes, defined methods and attributes in the program through class-dump. Therefore, we need to do obfuscation.

    A class is dynamically retrieved from a file, a network, or a string. If it is confused, it will cause an error. Arguments with the same name but different functions will also cause an error

    2. Currently, the AppStore has strict review on application code confusion. Once confusion is made, it may lead to delayed review or direct rejectionConfusing shelving risk reference 1 和 Confused shelf risk reference 2

    You may be unlucky enough to receive such feedback

3. So what to do? Don’t panic, we can mess with the generation of a few key metrics that relate to the core business, and then test it

So how do we do static obfuscation specifically? * Get new skills next ~~~~*

I demonstrate here is the other method name and attribute confusion, essentially is the string replacement, finally thrown out are macro, can run script automatically generated confusion after the chaotic characters, MY script here is online search, of course, have the ability to write yo.

The method of confusing the class name is the same, refer to the link, but whether to confuse the class name can be based on the actual project needs, of course, this pit is also more, to know, about other possible problems still need to explore more

  1. First create a demo project, my name is LFHelpers suppose I now need to UIbutton + LFCategories file imageDirectionWithButtonImageType confused way, There is also confusion with the titles property in the ViewController

The call now looks like this

Before we get confused let’s take a look at my class-dumped demo header. Don’t know how to dump? Don’t worry, you’ll find out at the end of the document.

Well, that perfectly exposes my method names and properties so let’s start confusing them

  1. Open the console, create these two files in the project folder, and drag them into the project project

  1. Copy the following script into the file confection.sh
#! /usr/bin/env bash
TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="func.list"
HEAD_FILE="$PROJECT_DIR/$PROJECT_NAME/codeObfuscation.h"
export LC_CTYPE=C

Maintain the database to facilitate future scheduling
createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
}

insertValue()
{
echo "insert into $TABLENAME values('The $1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
}

query()
{
echo "select * from $TABLENAME where src='The $1';" | sqlite3 $SYMBOL_DB_FILE
}

ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
}

rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable

touch $HEAD_FILE
echo '#ifndef Demo_codeObfuscation_h
#define Demo_codeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
cat "$STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "$line"]].then
ramdom=`ramdomString`
echo $line $ramdom
insertValue $line $ramdom
echo "#define $line $ramdom" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE


sqlite3 $SYMBOL_DB_FILE .dump
Copy the code
  1. Create the PCH file and fill in the relative path in the Prefix Header under Build Settings

CodeObfuscation. H is defined in the script, so comment out #import “codeObfuscation. H “before compiling

  1. Run the script file and add it in Build Phases

  2. Open the console again, open the project directory, and grant the percole.sh permission

Then write the method names and properties to obfuscate in the func.list

  1. #improt “codeObfuscation. H “in PCH, #improt “codeObfuscation. H” in PCH, #improt “codeObfuscation

Let’s see what happens now

Click in to see the specific macro definition

Now that we’ve succeeded, let’s see what class-dump looks like

We can use class-dump to analyze packages with the suffix of app. If you download a package from the App Store, you need to crack the shell

  • Dynamic protection: in fact is to the dynamic protection project, including some narrow detecting debugging, injection, injection, hooks, integrity checking and popular said is the defense, so learn to defense, to attack first We can also add some risk control class of the SDK, can be used to evaluate risk

  • Code obfuscation: assembler, compile-time obfuscation, static string obfuscation, LLVM – based custom code obfuscation:

    • It can be understood as a complete compilation architecture, that is, a compiler. It takes the source code (.c or.cpp or.m file code) and generates machine-independent intermediate code, called IR. Then the generated IR is optimized to generate the corresponding machine assembly language.
    • LLVM is very extensible and can be used to compile your language by customizing the front end or back end by converting the source code to intermediate IR code, or intermediate IR code to specified machine code, i.e. implementing only the specified front end or back end.
    • In the case of LLVM, the front end is Clang, as is the compilation tool used when compiling source files. After generating the intermediate IR code, you need to perform some operations on the IR code, such as adding some code obfuscation functions. LLVM does this by writing passes, which are essentially corresponding classes that do different things. So implementation obfuscation is really just writing functional passes.

To put it simply, the function of LLVM is to add some useless code through code confusion, and add some messy processes. Without confusion, reverse crack will go straight, and with confusion, it will go crooked. This is done to make static analysis more difficult for an attacker

If you are interested, you can find out how to customize code confounding based on LLVM, because it is a bit difficult, so there are three open source frameworks

Ollvm: An open source code obfuscation tool developed based on LLVM, currently based on LLVM-4.0. At present, as long as it can be adjusted to directly use the debugging process will be more complicated, need to slowly fill the pit, the online information is less, this can refer to the reference

  • One last thing about **Static library confusion**

There is no need to confuse static libraries, which are already relatively secure

But you can get the general idea: since compiler obfuscation is based on the intermediate code bitcode, it is necessary to compile and generate a static library with bitcode, which can be directly extracted and obfuscated

Specific practices: Add -fembed-bitcode to Other C Flags in build Settings and generate static library. Then use the command to extract the bitcode generated in the MachOView section and recompile it into the object file using clang with obfuscation (this is based on the ollVM obfuscation tool above). The generated XXX. O is the confused object file, and then XXX. O is repackaged into XXX


The attached:

  • Class-dump: a tool for retrieving information about classes, methods, and properties from executable files. The code is open source, and the header generated by the tool can be used to quickly find the desired method or property during analysis. Github Address Address of the installation package

Installation method:

  1. After opening the installation package, copy class-dump to /usr/local/bin/class-dump

  2. Run the sudo chmod 777 /usr/local/bin/class-dump command on the CLI to grant the execution permission

  3. You can type class-dump to see the usage

  4. Method for extracting header files class-dump -h Frame directory to be exported -o Directory for storing exported header files For example:

Note that the executable must be extracted. The Xcode run project is available in the.app package under Products

If it is downloaded from appstore, it is necessary to crack the shell and obtain the package with the suffix of. App before extracting it

  • In addition, due to the complexity and complexity of code confusion and the harsh audit from Apple, many companies choose to use three-party reinforcement tools except ollVM. The following lists other commonly used three-party tools
    • Love the encryption
    • Netease iOS Hardening
    • 360 ios reinforcement
    • Digital Meld armor iOS hardening
    • Top image iOS hardening For the verification and comparison results of these three hardening schemes, see reference 1 Reference 2 Reference 3

Author’s brief introduction

Worked in the Information Technology Department of Sweet Orange Finance (Wing Payment), responsible for iOS client development