Welcome back everyone! This is the third tutorial of iOS Anti-Piracy code from all over the world. This tutorial will, unfortunately, not be showing you a ton of unique, ingenious, and awesome anti-piracy methods like I have in the past.  No, this time I will be showing you only two revised method that I like a lot, I will go over which methods from my last two tutorials are still relevant, and then I will introduce you to my new iOS Anti-Piracy Protection Libraries (yes two)!

For those of you who are new to my tutorials and iOS Piracy, let me update you:  iOS piracy accounts for 90% of the top 100 paid application downloads, as of today over 37,000 applications have been cracked and available for pirating, developers have lost over $110 million dollars in revenue to piracy, and with over six million pirates in counting, the money lost in application sales is rising every day.  No one is safe; every application is vulnerable, including free applications.  This tutorial will dive into two code examples that will help protect your applications from iOS Pirates.

*Since this tutorial is a collection of Anti-Piracy methods and because Piracy is such a strong issue, I would appreciate if comments about the ethics and ideologies about Piracy and Anti-Piracy were omitted. Thank you. With that out of the way, let’s dive in!

In the past two tutorials, I would start with a simple method and work my way towards harder and progressively more complex techniques.  But in this tutorial, with only two methods to show you, I will just lay it all out:

#define CODE_RESOURCES @"CodeResources"
//place your definition of CodeResources above the @implementation in your .m
NSFileManager *myManager = [NSFileManager defaultManager];
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
if ([myManager fileExistsAtPath:[bundlePath stringByAppendingPathComponent:CODE_RESOURCES]]) {
    //Not Pirated
}
else {
    //Pirated
}

The code behind this method is relatively simple.  You are taking the CodeResources file and checking to see if the file exists.  You are also defining the file you are checking for in order to obfuscate the string.  The reason you are doing this check is because iOS Pirates will often delete the coderesources file to protect their privacy.  I know this method was shown off in one of my last tutorials, but since it’s been revised, and because you can use this same method to check for a multitude of files that crackers delete, it makes this method very worthwhile to include.

There are a couple files you may be interested in checking for in order to determine if an application is pirated.  Some of the other files being the resourcerules.plist file, the metadata.plist file, and possibly other important files located in your application such as savegames, pictures, or plists.  In order to check the existence of other files, in this example the ResourceRules.plist file, simply change out the definition statement to this:

#define CODE_RULES @"%@/ResourceRules.plist"

Another method that I have revised since my last tutorial is the User ID method:

if (getuid() == 0) {
    //Pirated
} else {
    //Not Pirated
}

Voila!  There are my two, outstanding, revised piracy protection mechanisms.  Sorry I don’t have more to offer you as of today, but I assure you that there is much more to come in the future.The reason I changed this method is because the last method relied on checking if the process ID was fewer than 10, which wouldn’t show you correctly whether or not the user was running your application as a root user.  This method will show you with 100% certainty whether or not the user is running as root.  The reason this is relevant is because all cracking applications run as the root user, and every manual cracker runs your application from ssh as root.  This will ensure that you catch them.

As far as the methods from my last tutorials that still relevant, here is the list of all known methods that still work 100% effectively:

If some of your users are still on iOS firmware 2.0 or earlier (rare, but in some cases pirates still use those firmwares) then all signer identity methods will still catch them.  Note that it will not catch any pirated users below iOS firmware 3.0:

//Method #1 – Simple SignerIdentity Check
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *info = [bundle infoDictionary];
if ([info objectForKey: @"SignerIdentity"] != nil)
{
/* do something */
}

//Method #2 – Defined SignerIdentity Check
#define INIT_STRING @"SignerIdentity"

NSString *aString = INIT_STRING; ///do this for all of your temp strings

//Method #3 – Obfuscated SignerIdentity check
NSString *aString = [NSString stringWithFormat:@"%@%@%@",@"Sig",@"nerI",@"dentit y"];

The rest of the methods will work for anything above iOS firmware 2.0:

//Method #4 – Plist Size Compare
NSBundle *bundle = [NSBundle mainBundle];
NSString* bundlePath = [bundle bundlePath];

NSFileManager *fileManager = [NSFileManager defaultManager];

NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath ];

NSDictionary *fileAttributes = [fileManager fileAttributesAtPath:path traverseLink:YES];

if (fileAttributes != nil) {
NSNumber *fileSize;

if (fileSize = [fileAttributes objectForKey:NSFileSize]) {
NSLog(@"File size: %qi\n", [fileSize unsignedLongLongValue]);
}
}

//Method #5 – Honey Pot Trap
bool checked = false;
if([[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] == nil || [[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] != nil)
{
	checked = true;
}
if(!checked)
{
// This app be hacked!
}

//Method #6 – CodeResources/ResourceRules.plist/Codesignature Check
NSFileManager *myManager = [NSFileManager defaultManager];
    NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
    if ([myManager fileExistsAtPath:[bundlePath stringByAppendingPathComponent:CODE_RESOURCES]]) {
        //Not Pirated
	}
    else
    {
        //Pirated
	}

//Method #7 – User ID Check
if (getuid() == 0) {
        //Pirated
    } else {
        //Not Pirated
    }

//Method #8 – Application Binary Encryption Check
#import
#import
#import 

/* The encryption info struct and constants are missing from the iPhoneSimulator SDK, but not from the iPhoneOS or
 * Mac OS X SDKs. Since one doesn't ever ship a Simulator binary, we'll just provide the definitions here. */
#if TARGET_IPHONE_SIMULATOR && !defined(LC_ENCRYPTION_INFO)
#define LC_ENCRYPTION_INFO 0x21
struct encryption_info_command {
    uint32_t cmd;
    uint32_t cmdsize;
    uint32_t cryptoff;
    uint32_t cryptsize;
    uint32_t cryptid;
};
#endif

int main (int argc, char *argv[]);

static BOOL is_encrypted () {
    const struct mach_header *header;
    Dl_info dlinfo;

    /* Fetch the dlinfo for main() */
    if (dladdr(main, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) {
        NSLog(@"Could not find main() symbol (very odd)");
        return NO;
    }
    header = dlinfo.dli_fbase;

    /* Compute the image size and search for a UUID */
    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;
}

Well everyone, thank you for reading my third iPhone Piracy Protection tutorial!  I get a kick out of all the comments and feedback so please feel free to ask me anything and if you have anything you would like to ask me directly, please feel free to email me.  Thank you everyone!

And one more thing, my Shmoopi Anti-Piracy Libraries are now available!!!!  I have designed and developed two (yes two!) Static Libraries with all of the iPhone Anti-Piracy Code I have worked on and developed over the years.  It comes in two flavors:  Free!!!! And Paid!!!!!! 

Check them out here:

http://www.shmoopi.net/shmoopiantipiracy/

I worked hard to bring you the top-of-the-line protection at the cheapest cost to you.  If you have any comments, questions, or concerns, do not hesitate to ask.  Thank you very much for reading this tutorial!  Stay tuned for my next tutorial!!