📜 ⬆️ ⬇️

Effective way to protect against piracy

If you are a developer of ios applications, then most likely, the topic of piracy is familiar to you, painful and unpleasant. I hope you will be interested in understanding how to hinder it and what you need to do in order not to see your application in the hackulo.us repository an hour after its release in the appstore.

In search of easy money


To begin with, consider what Apple has done for our protection. This DRM is called FairPlay and its competence includes full encryption of the executable file, which, according to the apple, should prevent reverse engineering and unauthorized copying. In general, the system copes with its tasks, but only until such time as our application gets on iDevice. The fact is that the processor does not know how to execute encrypted instructions, so the operating system, after loading the file into memory and immediately before its execution, performs its full decryption. Exactly this feature is exploited by the entire Cracker software. Waiting for the application to be completely decrypted in memory and ready for execution, the cracker utility dumps its image into a file.

For clarity, I will show how this can be done with gdb:
break main #       command 1 #     ,      output.bin dump memory output.bin 0x2000 cryptsize # cryptsize   otool -l   LC_ENCRYPTION_INFO kill quit end start 

Then, change the pair of service fields in the header of the executable file mach-o and Info.plist. That's all. Our application is ready to go free. But, the most annoying thing is that with the release of fully automated utilities, such as Crackulous, any schoolchild can do this operation, even without having the slightest idea how things work out.

Naturally, this situation could not leave the developer community indifferent. You can easily google a dozen solutions that will help cope with schoolchildren, but are completely helpless against even a novice cracker. Why? Let's take a closer look. The main idea of ​​checks is to track changes in the application bundle. For example, a different creation time of the executable file and Info.plist, or the size of Info.plist is different from the reference, or the _CodeSignature directory is missing. As it should be for ios applications, all these checks are written in ObjC using frameworks.
')
Try to open the executable file of your application in a text editor, and even better through the console utility strings. See you Everything that you use, lies in full view. It is enough to load the binary into IDA and see who and where in the code uses all these NSBundle, NSDate and NSFileSize. Where are the “menacing” warnings of Crack Detected, etc. used? Having found the check, it is not difficult for the hacker to change 1-2 bytes so that the check always returns a convenient value.

The disadvantage of all these methods is that they are very easily found by static analysis, because they use frameworks, methods and classes of ObjC. So, we need a way that could not be found on the general templates, written in pure C, without using classes and frameworks. Here is the best that Google showed me:
 #import <mach-o/dyld.h> #define LC_ENCRYPTION_INFO 0x21 struct encryption_info_command { uint32_t cmd; uint32_t cmdsize; uint32_t cryptoff; uint32_t cryptsize; uint32_t cryptid; }; static BOOL is_encrypted () { //         dladdr(main, &dlinfo),   iphone  , //  ,       dl- struct mach_header *header = 0x1000; struct load_command *cmd = (struct load_command *) (header+1); for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) { /* Encryption info segment */ if (cmd->cmd == LC_ENCRYPTION_INFO) { struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) cmd; /* Check if binary encryption is enabled */ if (crypt_cmd->cryptid < 1) { /* Disabled, probably pirated */ return NO; } /* Probably not pirated? */ return YES; } cmd = (struct load_command *) ((uint8_t *) cmd + cmd->cmdsize); } /* Encryption info not found */ return NO; } 

The idea is that in the mach-o header of the executable file there is a cryptid flag in the LC_ENCRYPTION_INFO section, displaying whether the binary is encrypted or not. Based on its value, a conclusion is drawn about the origin of this application.

At this place, all good ideas in public end, then only private


Despite the fact that the above code is quite difficult to detect with static analysis, an attacker can run our application on his jailbreaked phone under gdb. And in the step-by-step mode, he will be able to unravel any of our protection in record time!
Fortunately, Apple allows us to prohibit such a trace:
 ptrace(PT_DENY_ATTACH, 0, 0, 0); 

After its execution, any attempts to debug our application will be segfolded, “encroached on the holy,” the process. We can say that on this front we won a complete and unconditional victory!
But do not be in a hurry to rejoice, because ptrace is a function, in fact, a wrapper, and not a real system call, it is easy to find and neutralize, for example:
 break ptrace #    ptrace commands 1 return #     ,      continue end run 

How to be? Refuse fancy api and do the system call yourself!
Adepts C may recall:
 #include <sys/syscall.h> syscall(SYS_ptrace, PT_DENY_ATTACH, 0, 0, 0); 

But, firstly, syscall is a function with which you can do the same as with ptrace, and secondly, it is part of the private api and the censors may not miss the program for its use.
So, we have to do a system call without intermediaries, straight into the assembler, the benefit is not at all scary:
 asm { mov r0, #31 // PT_DENY_ATTACH mov r1, #0 mov r2, #0 mov r3, #0 mov ip, #26 // SYS_ptrace svc #0x80 //    } 

But to find and neutralize these instructions will be disproportionately more difficult, especially if there are 5-10 such calls and they are scattered throughout the program code.

The crown of our protection should be the integrity check of the executable file, it is necessary to check the checksum of the section with the code (__text). The point is that even changing one byte in this section will change the checksum, so we will track the attempt to modify the file! Since in normal conditions our file is encrypted and there is no point in trying to read its contents, we will act as hackers and read the section after the operating system loads and decrypts it itself. Necessary information about the displacement and length can be found using:
 otool -l myPrecious.app/binary ... Section sectname __text segname __TEXT addr 0x00002000 size 0x00096980 offset 4096 align 2^2 (4) reloff 0 nreloc 0 flags 0x80000400 reserved1 0 reserved2 0 ... 

The code we are interested in is starting from the address 0x2000 already familiar to us, and the length is respectively 0x96980.
The pattern of this check can be, for example, like this:
 __attribute__((always_inline)) void my_secret_checksum() { u_char *buf = 0x2000; u_int res; for (int i = 0; i < 0x96980; i++) { res += buf[i] ..... //    crc/adler   } if (res != ...) { // Achtung! Partizanen! } } 

Pay attention to the always_inline attribute, it allows in different places of the program to place not just a call to this function, but directly its code. Thus, if we place this check in several places, the hacker will have to find and neutralize them all. And until he does, any attempt to modify the executable file will be stopped. Ideally, it is worth placing it in each of your methods or functions. Reading from memory is a very fast process, so its frequent use will not affect its performance. And the prospect of cutting it out of the entire code should repel even the most purposeful hacker.

Afterword


Defense is countering attack. By opposing one attack, we are not protected from another. Therefore, only a complex of checks can be effective protection. I tried to highlight the required minimum. And I hope this material will inspire the reader to their own searches and research. Good luck to you! And do not let the level of your sales darken romance with a big road!

Literature


A good instruction on the topic of Patching Iphone Application with life examples can be found here .

Source: https://habr.com/ru/post/127875/


All Articles