preface

There are tons of plaintext strings in a project, but some of them are sensitive information about the program and if we don’t encrypt and obfuscate them, the uncompiler can easily find our sensitive information. After obtaining these sensitive information, it is easy to analyze our programs and business logic to do some things that may not be very friendly to us. Therefore, it is necessary to encrypt some sensitive plaintext strings to make sensitive information more secure. Especially for some financial apps.

Decompiler tool

Here are a few commonly used ones:

  1. class-dump

It is mainly used to decompile a library file or app method name, property, etc declaration (i.e. H file, powerful decompiled. H file contains not only header file declaration,.m function method name can also be decompiled).

  1. IDA

Mainly used to decompile the implementation of library files (of course method declaration can also decompile out, with class-dump is mainly more image, targeted), this decompile tool is very powerful can be the implementation of the function and logical relations, flow all show, the drawback is to decompile out of the content of assembly language, Need certain assembler foundation ability to understand. It looks like a headache.

  1. Hopper Disassembler

Similar to IDA function, the main function is decompilation view method implementation, the function of this software compared to IDA, much more readable, decompilation content is similar to assembly and OC runtime combination, relatively easy to see the specific implementation of the method. This time also uses this tool for verification.

Code confusion

Before exploring plaintext string encryption, let’s look at code obfuscation:

  1. Method name obfuscation (for key classes, methods, give them names that have nothing to do with the real intention)
  • createshellThe script
  • Declares a list of method names to replace
  • Generates the corresponding unordered string after escaping
  1. Logic confusion (adding useless code snippets that don’t affect logic, confusing the reverse engineer)
  2. Class name method name confusion (e.g. Ios-class-guard)

Warning!!! high energy alert

Guideline 2.3.1 – Performance We discovered that your app contains hidden features. Specifically, It would be appropriate to remove all code obfuscation and selector mangling or to explain in detail the purpose of its inclusion before resubmitting for review.

Apple has reportedly refused to approve apps with confusing codes since 2017. So the confusion over the project’s overall code doesn’t feel significant at this point.

Third-party Hardening

It is not clear how effective the reinforcement of third-party services (such as NetEase Yunyi Shield) will be. Here it is for reference. After all, it has not been used before, and it may depend on the decision of the company.

The third party clearly stated that code obfuscation was used in the reinforcement. I don’t know what kind of black technology was used to obfuscate the reinforcement. It was definitely not in the way of running scripts

String encryption research and attempts

For shelled binaries, the reverse analyst has an important clue to the code, which is the hard-coded plaintext string. For example, if your app is caught and some data request interface is discovered, the reverse engineer can simply copy the character string into Hopper and search for it. By looking at where the character string is referenced, the corresponding logic code can be found quickly. To prevent this step, all you need to do is to encrypt the hard-coded plaintext.

Use static inline C functions

  • inlineFunction avoids the normal function that must be called at assembly timecallFaults.
  • It eliminates the parameter pushing of function, reduces the overhead of calling and improves efficiency. So the execution speed is actually faster than normal function execution speed.

Definition:

UIKIT_STATIC_INLINE NSString *testScheme() {
    return @"testtesttesttest";
}

static inline NSString * testName() {
    return @"test";
}
Copy the code

Use:

@"appId": testRrd(),
@"scheme" : testScheme()
Copy the code

Results:

Obviously the plaintext string is still easy to expose ~ ~, the scheme is passed!

Swift is more secure

  • Jailbreak open source community on decompilationSwiftSupport is also not immediate.
  • Some decompilation tools do not support decompilation of containsSwiftBinary files (e.g.class-dump).
  • Be able to decompileSwiftTools also showSwiftThe safer side.

I tested OC and Swift methods with the same logic and the same code (but different syntax) that contain plaintext strings:

The above comparison clearly shows that the decompilation of OC exposes more information, and the plaintext string is obvious. But if the Swift method adds support for OC (@objc), security is also reduced.

At present, pure Swift code is indeed more secure than pure OC or mixed code.

UAObfuscatedString

There’s an open source code that you can use, UAObfuscatedString, this open source obfuscate code that writes strings that are concatenated in dot syntax.

Grammar:

@"url" : NSMutableString.string.w.w.w.dot.b.a.i.d.u.dot.c.o.m
Copy the code

Test confusion results:

UAObfuscatedString is realized by Category and Extension, which has obvious rules. In addition, it may not have high security because it is open source. For example, it is not meaningful to use this open source library only from the perspective of encryption.

Use xor encryption

Principle: through the bit operation of the xor operator of the string and a specified value operation, so as to change the value of each character in the string, so that you can get an encrypted string; When the encrypted string is used as program input, the xOR operation restores the encrypted string to its original value.

Use:

@"key" : testMethod()
Copy the code
// Key can be an Int from 0 to 255#define XORKEY 0xC9

static void XOREncrypt(unsigned char *str, unsigned char key) {
    unsigned char *p = str;
    while(((*p) ^= key) ! ='\ 0') {
        p++;
    }
}

static id testMethod(void) {
    unsigned char str[] = {(XORKEY ^ 'e'), (XORKEY ^ 'n'), (XORKEY ^ 'c'), (XORKEY ^ 'r'),
        (XORKEY ^ 'y'), (XORKEY ^ 'p'), (XORKEY ^ 't'), (XORKEY ^ '\ 0')};
    XOREncrypt(str, XORKEY);
    static unsigned char result[7];
    memcpy(result, str, 7);
    return [[NSString alloc] initWithFormat:@"%s", result];
}

Copy the code

Here the characters are stored as function pointer members, and the decompilation leaves only the addresses, removing the risk of direct exposure to plaintext strings.

Refer to the link

hopperapp

IOS Security (xXIII) : Objective-C code confusion

ios-class-guard

UAObfuscatedString

Perform security hardening for iOS apps