iPhone Piracy 101: Steps to Prevent it
**This is a guest article by Will Strafach. Unlike you, this person got off his ass and earned some $$ writing about what he loves. He has accomplished something with his life, he has written for MrCracker.com . What have you done? Click Here to start.**

Now that you know how iPhone piracy works, (if not, click here to read previous article), you probably want to know how you can prevent it. This article will tell you that, but please note this. This is getting published for all to see, including the people that want to crack your application. If I provide you with code or a method to do a certain check in here, do not just copy it verbatim, tweak it a little so that the crackers don’t know exactly what to look for.
Since we know that crackers are going to crack your app anyway, we do not want to look at this in a “we need to stop them” way. You must know that it will happen. We need to think of this in a “hold them off as long as possible” way. The first step would be obfuscation, to confuse them. Save the code attached to the end of this post and save it In a file called “iPhoneOS_swi.S”. Include it in one of your projects and, for example, you want a discrete exit(), simply call swi_exit(); from your code. Crackers will soon catch on to this, but it is at least better then flat out and obviously calling exit(). This will at least cause some confusion. If you want to try further obfuscation, use swi_exit_obfuscated(), but change it around a bit so people can’t do a simple byte search to patch it. I have not tested that one yet, but in theory it should change the “NOP” to “SWI 0×11” in memory. Usually, kernel restrictions block this type of obfuscation, but funnily enough the patch that is needed for WinterBoard and such to work, is what allows this trick to work, in theory. Another less obvious thing you can check is if the app is running as root, which it normally should not be unless a cracker was running it in GDB via SSH like they normally do. So use something like the swi_getgid() to check if it is running as 0, which is root, and if so swi_exit(). Again, I must stress to play with this a bit, because if you do it exactly then it will be obvious for the crackers, as I can safely say they will read this article.
Now, above I am talking about how to exit the app without the cracker seeing the call directly in IDA, but you are probably thinking, “But chronic, in what cases would I actually need to exit the application? What kind of checks can I do?”. This is where things get a little shady. If I specifically give out checks to use, they are useless since they are public and they will be looked for. Instead, I will give you some tips…
- stringWithFormat: is your friend. Use it to construct a string in a buffer letter by letter instead of having the whole string there in your code, easily searchable in IDA Pro. It is comparable to the sprintf(); of Objective-C, you could almost say.
- Excessively use stringWithFormat: to “obfuscate” strings that do other things in your application, even the text of an AlertView or something. The goal would be to annoy the cracker when looking for all of the calls to stringWithFormat:, maybe even to the point where he would not try to take that shortcut if you use it enough times for legitimate strings.
- Keep in mind that Info.plist is modified. You can check the size, the existence of the “SignerIdentity” key…use your imagination. The crackers /need/ to modify this file, so use that to your advantage.
/* * iPhoneOS_swi.S * * Created by Will Strafach on 5/23/09 * Copyright 2009 Chronic Dev. All rights reserved. * * Mini-License: Keep this header here, do not modify it or anything, * and you can use this in your projects. Also, I grant MrCracker.com * permission to use this in their "iPhone Piracy 101" article. */ .global _swi_exit .global _swi_exit_obfuscated .global _syscall_exit .global _syscall_chmod .global _syscall_chown .global _syscall_getpid .global _syscall_getuid .global _syscall_geteuid .global _syscall_access .global _syscall_getegid .global _syscall_getgid _swi_exit: SWI 0x11 BX LR _swi_exit_obfuscated: MOV R0, #0x11 STRB R0, [PC,#0x10] MOV R0, #0x00 STRB R0, [PC,#0x8] STRB R0, [PC,#0x4] MOV R0, #0xEF STRB R0, [PC,#-0x4] NOP BX LR _syscall_exit: MOV R12, #1 SWI 0x80 BX LR _syscall_chmod: MOV R12, #15 SWI 0x80 BX LR _syscall_chown: MOV R12, #16 SWI 0x80 BX LR _syscall_getpid: MOV R12, #20 SWI 0x80 BX LR _syscall_getuid: MOV R12, #24 SWI 0x80 BX LR _syscall_geteuid: MOV R12, #25 SWI 0x80 BX LR _syscall_access: MOV R12, #33 SWI 0x80 BX LR _syscall_getegid: MOV R12, #43 SWI 0x80 BX LR _syscall_getgid: MOV R12, #47 SWI 0x80 BX LR




(3 votes, average: 3.67 out of 5)
iPhone Piracy 101: Steps to Prevent it…
**This is a guest article by Will Strafach. Unlike you, this person got off his ass and earned some $$ writing about what he loves. He has accomplished something with his life, he has written for……
Could you tell me in what programming language your iPhoneOS_swi.S is written, i would like to learn more about your code.
Hey Hans, it’s written in assembly.
When i try to compile the .S file i get an error in every line similar to this one: “bad instruction ‘MOV R12′”
I get the same when i try to use __asm__ (“MOV R12″)
I’m compiling for iPhone OS 2.2.1
I already found out from another website that it should be .globl and not .global
Are there any specific project settings that must be set? Or more importantly: did you ever compile this code in an iPhone project?
Oh … i figured it out. The assembler instructions must be written in lower case, not upper case!
Just to clarify compilation issues for others:
- turn the whole iPhoneOS_swi.s file into lowercase letters
- replace .global with .globl
- to use the code in a C file, write:
extern int swi_exit();
extern int syscall_getgid();
// … and so on with any other function you want to use
// note that the extern functions here have the leading underscore removed!
int main (int argc, char *argv[])
{
#if !TARGET_IPHONE_SIMULATOR
// check if debugger is attached (cracking attempt?)
int root = syscall_getgid();
if (root == 0)
{
swi_exit();
}
#endif
// your code here
return 0;
}
Note: i don’t know if the code belongs directly after main or not. I see it returns 501 with debugger attached by running a debug build with Build & Go (Debug). So it doesn’t quit. But maybe it would if you attempt to crack it? I haven’t checked that.
swi_exit()doesn’t quit for me either. Callsyscall_exit()instead.Leave your response!
MrCracker.com Hacker Newsletter
Subscribe via RSS or Subscribe via email.
Archives
Blogroll
Categories
Recent Posts
Most Commented
Most Viewed