How to Move UITextField Up when Keyboard is Showing – Cocoa Touch

Welcome everybody! This tutorial is going to show you how to move a textfield whenever the keyboard pops up! One of the biggest problems with textfields is that when the keyboard pops up, the content gets stuck under the keyboard resulting in the total or partial obstruction of the very textfield that your users are trying to write in!! There are several fixes for this problem, but I will only be showing you my version. So feel free to explain any methods that I didn’t in the comments, or email me so I can include it in the tutorial!

The easiest method of un-obstructing the textfield is simply by moving it. Here is what you do: First you need to make sure that the delegate is selected for the textfield in your interface builder file (xib containing textfield). So under the connections tab in your inspector window, make sure that your text field has the delegate set to self. You can also set it in the code under viewdidload as:

Code:
 /* UITextField Name */ .delegate = self;

But you have to make sure you set it in the .h file in between the brackets like this, or else you get an error:

Code:
 ViewController : UIViewController /* apparently this is also html code because it won't show up but it is the "UIText Field Delegate" without the "'s or the spaces. */ {

The next step is to add these methods into your code:

Code:
- (void)textFieldDidBeginEditing:(UITextField *)textField {	

}
- (void)textFieldDidEndEditing:(UITextField *)textField {

}

These methods will go off whenever your textfield has been touched, and when it is done. So now to move it when touched: Go ahead and add this code in the textFieldDidBeginEditing method above:

Code:
- (void)textFieldDidBeginEditing:(UITextField *)textField {	
[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDuration:0.5];
	[UIView setAnimationBeginsFromCurrentState:YES];
	textfield.frame = CGRectMake(textfield.frame.origin.x, (textfield.frame.origin.y - 100.0), textfield.frame.size.width, textfield.frame.size.height);
	[UIView commitAnimations];
}

Most of the code here is unnecessary because we are simply moving the textfield’s y origin down 100 points, going up. The UIView animations are simply for visual effect, I personally dislike seeing a textfield appear out of thin air. You can also change the y origin’s movement from 100 to any size amount that you need. So go ahead and try it out to see what happens. You should see a nice textfield moving up every time you click on it to change the text, bravo. Now let’s move it back down when you’re done with it.
Add this to your textFieldDidEndEditing method:

Code:
- (void)textFieldDidEndEditing:(UITextField *)textField {	
[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDuration:0.5];
	[UIView setAnimationBeginsFromCurrentState:YES];
	textfield.frame = CGRectMake(textfield.frame.origin.x, (textfield.frame.origin.y + 100.0), textfield.frame.size.width, textfield.frame.size.height);
	[UIView commitAnimations];
}

Easy peasy, looks perfect now doesn’t it? Now what if we had more than 1 textfield what would we do? Try this:

Code:
- (void)textFieldDidBeginEditing:(UITextField *)textField {	
		if (textField == textField1) {
			[UIView beginAnimations:nil context:NULL];
			[UIView setAnimationDelegate:self];
			[UIView setAnimationDuration:0.5];
			[UIView setAnimationBeginsFromCurrentState:YES];
			textfield1.frame = CGRectMake(textfield1.frame.origin.x, (textfield1.frame.origin.y - 100.0), textfield1.frame.size.width, textfield1.frame.size.height);
			[UIView commitAnimations];
		} else if (textField == textField2) {
			[UIView beginAnimations:nil context:NULL];
			[UIView setAnimationDelegate:self];
			[UIView setAnimationDuration:0.5];
			[UIView setAnimationBeginsFromCurrentState:YES];
			textfield2.frame = CGRectMake(textfield2.frame.origin.x, (textfield2.frame.origin.y - 100.0), textfield2.frame.size.width, textfield2.frame.size.height);
			[UIView commitAnimations];
		}
	}
	- (void)textFieldDidEndEditing:(UITextField *)textField {	
		if (textField == textField1) {
			[UIView beginAnimations:nil context:NULL];
			[UIView setAnimationDelegate:self];
			[UIView setAnimationDuration:0.5];
			[UIView setAnimationBeginsFromCurrentState:YES];
			textfield1.frame = CGRectMake(textfield1.frame.origin.x, (textfield1.frame.origin.y + 100.0), textfield1.frame.size.width, textfield1.frame.size.height);
			[UIView commitAnimations];
		} else if (textField == textField2) {
			[UIView beginAnimations:nil context:NULL];
			[UIView setAnimationDelegate:self];
			[UIView setAnimationDuration:0.5];
			[UIView setAnimationBeginsFromCurrentState:YES];
			textfield2.frame = CGRectMake(textfield2.frame.origin.x, (textfield2.frame.origin.y + 100.0), textfield2.frame.size.width, textfield2.frame.size.height);
			[UIView commitAnimations];
		}

Excellent, now let’s do just one more thing: Let’s have it so that the textfield will return whenever you click somewhere else on the screen. I personally dislike having to put text in a textfield every time before the Done button will show up. So here’s what you do: Simply add this code:

Code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	[textfield resignFirstResponder];
}

And.. Wallah that’s it! Now you have a very professional text field that not only moves up and down to avoid being trapped behind the keyboard, it also returns whenever you click out of it. No more having to put unnecessary text in to see the done button!!! Huzzah! Well, that’s all I got for you. Feel free to explain different methods of doing it below, and if you have any questions or concerns at all, feel free to email me at Shmoopiapp@gmail.com

How to Save Your Game (or Any Other Object) in Cocoa Touch

Newcomers to iPhoneDevSDK often ask how to convert a string to bytes for writing to a file and other questions about data persistence that belie their real question: how do I save an object and restore it at a later time? NSUserDefaults is fine for storing some strings or bools, but what about an entire custom object? This is called “archiving.”

In short, as long as an object conforms to the NSCoding protocol you can save it to a file just by calling archiveRootObject:toFile:. Most built-in objects already conform to the protocol; you can save an entire NSArray of NSStrings, NSNumbers, and NSDictiories with that one line of code. If you want to save your own custom objects, though, you must make them conform to the NSCoder protocol by adding two methods – encodeWithCoder and initWithCoder.

How to save an object

In “Dead Panic” I instantly save the game whenever they press the home button, and restore their saved game whenever the game is launched again. To do that I need to save some information about which map they’re on, the player’s progress, and the player and enemy positions and health.

Here is my code for saving the map to a coder:

Code:
//Map.m
//encode the map data
- (void) encodeWithCoder: (NSCoder *)coder
{   

    //code the level name
    [coder encodeObject: currentLevelName forKey:@"currentLevelName" ];

    // code the length of the event list (progress through the level)
    NSNumber *listCount = [NSNumber numberWithInt: [eventList count]];
    [coder encodeObject: listCount forKey:@"eventList.count" ];

    // code the list of players
    [coder encodeObject: charList forKey:@"charList" ]; 

}

Notice I didn’t save anything about the structure of the map or the what it looks like – that’s all static data I can get elsewhere. When I load this object I’ll know the level name, and I can get all of the static data from there.

What about the positions of all of the players? Well, you can see that I’m encoding “charList” above, which is an NSArray of the players. That means encodeWithCoder will be called for each item in that array, so I leave it up to the player class to save the important data for each player. Here’s the code for saving a player:

Code:
//Player.m
//encode a player or monster character
- (void) encodeWithCoder: (NSCoder *)coder
{
    //save type number
    [coder encodeObject: [NSNumber numberWithInt:type] forKey:@"type" ]; 

    //save x and y position
    [coder encodeObject:
        [NSNumber numberWithFloat:position.x] forKey:@"position.x" ];
    [coder encodeObject:
        [NSNumber numberWithFloat:position.y] forKey:@"position.y" ];

    //save health
    [coder encodeObject: [NSNumber numberWithInt: health] forKey:@"health" ]; 

}

You can see that there are many things I save, but there’s more data that I don’t save. I don’t save the maximum health of a character, or weapon range, or firing rate, or information about how he is drawn – that info is already in the default constructor, and there is no need to save it redundantly. Avoiding redundancy helps speed up the save process, and it should reduce bugs – a player loaded from a coder should behave the same as one created from scratch.

How to load an object

Of course we need to load the objects too; here is the code for that

Code:
//Map.m
//init a map from a coder
- (id) initWithCoder: (NSCoder *) coder
{
    [self init];

    // load the level name
    self.currentLevelName = [coder decodeObjectForKey:@"currentLevelName"]; 

    // load the current event number
    int eventsRemaining = [[coder decodeObjectForKey:@"eventList.count"] intValue]; 

    // load level based on level name
    [self loadLevel: currentLevelName];

    //skip events until we get to the current event number
    int length = [eventList count];
    NSRange deletionRange = NSMakeRange(0, length-eventsRemaining);
    [eventList removeObjectsInRange:deletionRange];

    //get the list of characters
    NSArray *tempCharList = [coder decodeObjectForKey:@"charList"]; 

    //add chars to map, set team counts
    for (id newChar in tempCharList)
        [self addChar: newChar];

    return self;
}

There are some tricks to look at there. I call the default init for the class, then I load a level based on the current level name. This is the same loadLevel method that I use when starting a normal game – I try to keep the custom code for loaded games to a minimum. After I load the level I remove items from the event stack until it matches the length of the saved stack. I could have saved the event stack instead, but again, I’m trying not to duplicate any data.

I also restore the list of characters, but then I add them one at a time using another method of this object – that’s because I have some custom code that must be run for every object on the map. Rather than duplicate that code, I call the method the same way it would be called in regular gameplay.

Code:
//Player.m
//init a player or monster from a coder
- (id) initWithCoder: (NSCoder *) coder
{
    type = [[coder decodeObjectForKey:@"type" ] intValue];    //load type number

    //init based on type number
    [self initWithType: type];

    // load x and y position
    position.x = [[coder decodeObjectForKey:@"position.x" ] floatValue];
    position.y = [[coder decodeObjectForKey:@"position.y" ] floatValue];

    health = [[coder decodeObjectForKey:@"health" ] intValue];

    return self;
}

The only trick here is that I find out what type of player I’m dealing with first, and then init the correct type. Other than that both snippets follow the same pattern – init the object with the regular initializer (the same one I would use when starting a new game) and then apply the information from the saved game.

The final part you can’t see is the game information that I discard entirely – like any particles or damage decals on the screen, or currently playing sound effects. These are all short-term effects that don’t affect the gameplay, and the player won’t miss them when the game reloads. Any ongoing effects – like flames that can damage characters or poisonous clouds to be avoided- would have to be saved, though. You have to decide what is just a visual effect, and what is part of the simulation.

Starting the party

In case you’ve forgotten how all these methods get called, we kick it all off with these lines:

Code:
//load the map from disk; its array of players gets loaded too.
//This causes "intiWithCoder" to be called
myMap = [NSKeyedUnarchiver unarchiveObjectWithFile: filePath];

//take some action if myMap == nil (will happen if save file does not exist)

//save the map to disk; it contains an array of players, so they get saved too.
//This caused "encodeWithCoder" to be called
[NSKeyedArchiver archiveRootObject: myMap toFile:filePath];

That’s all there is to it – make your custom objects conform to NSCoder by adding the two methods, try to save only the data that is necessary, and try to use existing initializers and methods wherever possible. Then kick it all off with unarchiveObjectWithFile or archiveRootObject.

*This tutorial written by Smasher
Thanks Smasher!

How to save your game (or any object) on the iPhone

Adding Views to Your iPhone Applications

Hey Everyone! Today I’m going to show you how to add another ViewController and View to your application. Adding additional views is a key concept that many iPhone developers have trouble grasping. This tutorial will show you how to add as many views to your application as you like, simply and easily without hassle. So let’s get started!

The first step to adding a view to your application is adding the viewcontroller files and the xib. In Xcode, click on File, New File, UIView Controller Subclass under the Cocoa Touch Class Tab. You can name your view files whatever you’d like, I named mine Options.  It should look like this:

Next, you’re going to open up your MainViewController.h file (Or whatever View Controller header file you want to add the view to) in your project and add this line:

Code:
- (IBAction)SwitchView:(id)sender;

The name doesn’t necessarily have to be SwitchView, you can name that whatever you want. This will add a button action to interface builder with which you can switch your views.

After you’ve edited the .h file it should look like this:

Code:
//  MainViewController.h
//  Adding Views
//
//  Created by Shmoopi on 04/10/11.
//  Copyright Shmoopi LLC 2011. All rights reserved.
//

#import 

@class MainViewController;

@interface MainViewController : UIViewController {
}
- (IBAction)SwitchView:(id)sender;

@end

When the .h file looks good, you’re going to go into your MainViewController.m file (Or whatever View Controller main file you want to add the view to) in your project, and add these lines:

Code:
#import “Options.h”
//After @implementation
-(IBAction)SwitchView:(id)sender {
Options *OptionsView = [[Options alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:OptionsView animated:YES];
}

Note that if you want the new view to be animated, put YES and if not then put NO. What this code does is import the new view controller header file to your MainViewController.m file and put an action to the previously defined IBAction that we put in the .h file.

Your .m file should look like this when you’re done:

Code:
#import "Options.h"

@implementation MainViewController

-(IBAction)SwitchView:(id)sender {
Options *OptionsView = [[Options alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:OptionsView animated:YES];
}

Now that you’ve added the appropriate code to your MainViewController, the ViewController that is going to open the new view, you need to create a button and link it to the IBAction(SwitchView) in Interface Builder or the equivalent in XCode 4. This step should be pretty self explanatory, but I’ll explain it, add a button to your MainView.xib in interface builder, name the button, “Next View”, next right click the button and click-drag from touch down to the view box in interface Builder or Xcode 4 and link it with SwitchViews.

Now you can click build and run your project to see that when you click the button, the new view opens up!!! Just one more step though, and you’re good to go.

Open up the Options.h file in your project (Or whatever you named your new viewcontroller.h file) and add this line:

Code:
-(IBAction)back:(id)sender;

this line creates a new interface builder option to go back to the main view

It should look like this:

Code:
//  Options.h
//  Adding Views
//
//  Created by Shmoopi on 04/10/11.
//  Copyright Shmoopi LLC 2011. All rights reserved.
//

#import 

@class Options;

@interface Options : UIViewController {
}
- (IBAction)back:(id)sender;

@end

When the .h file looks good, you’re going to go into your Options.m file (Or whatever View Controller main file you want to add the view to) in your project, and add these last three lines:

Code:
-(IBAction)back:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

Note that you can always dismiss the view without animations by changing the YES to a NO in the above code. What this code does is add an Action to the previously defined IBAction that we put in the header file. All this does is dismiss the View to go back to the main view.

The last step is to go into Interface Builder and add the button, naming it “back” (or whatever you like) and link it to the IBAction like we did two steps above.

And you’re finished!!!!! You can go build and run your project, opening and closing your new view to your heart’s desire! This method works with any amount of views you want to add to your application. Simple, fast, and easy.

Thanks for reading my tutorial on Adding Views to Your Application, I hope it helps. If you have any questions, comments, or concerns, please let me know. Thanks!!!

iPhone Piracy Protection Code Part 2

Welcome back everybody! This is the second tutorial on iPhone/iTouch Anti-Piracy code from all over the world. For those of you who are new to Anti-Piracy, let me get you updated: App Store Piracy today is running ramped, with over 5 Million pirates in counting, Developers are losing millions of dollars in revenue every day. Some companies have reported piracy rates of over 95%, after only one day.

*Since this tutorial is a collection of Anti-Piracy methods from all over, credits go to their respective authors. I would also like to add that I’m not going into the ethics of hacking or Anti-Piracy during this tutorial and would appreciate if comments about the ethics of Piracy and Anti-Piracy be omitted. Great, with that out of the way, Let’s do this!

Let’s start with something simple this time. Remember those SignerIdentity checks we did last time? Well, they’re going to become obsolete soon with newer methods of cracking just on the horizon; so I thought we’d focus on other areas this time:

Code:
#if !TARGET_IPHONE_SIMULATOR
int root = getgid();
if (root <= 10) {
	//Pirated
}
#endif

This code is very self explanatory. We are checking to make sure the user is not the iPhone Simulator, we’re grabbing the process id, and checking to make sure it’s not the root. Basically, whenever someone cracks your application, some automated processes run it as root in order to run gdb. We are simply making sure that user is not the root. This problem with this method is that the app does not have to be run as root, therefore many cracking applications can be adjusted around this.

This next method comes from one of our fellow iPhoneDevSDK’ers: javaconvert:

Code:
#define kInfoSize 500
//Place your NSLog Plist Size into the above Define statment
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath ];
NSDictionary *fileInfo = [[NSBundle mainBundle] infoDictionary];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *fileAttributes = [fileManager fileAttributesAtPath:path traverseLink:YES];

if (fileAttributes != nil) {
	NSNumber *fileSize;
	if(fileSize = [fileAttributes objectForKey:NSFileSize]){
		NSLog(@"File Size:  %qi\n", [fileSize unsignedLongLongValue]);
		//Best to see the File Size and change it accordingly first
		NSString *cSID = [[NSString alloc] initWithFormat:@"%@%@%@%@%@",@"Si",@"gne",@"rIde",@"ntity",@""];
		BOOL checkedforPir = false;
		if([fileInfo objectForKey:cSID] == nil || [fileInfo objectForKey:cSID] != nil) {
			if([fileSize unsignedLongLongValue] == kInfoSize) {
				checkedforPir = true;
			}
		}
		if(!checkedforPir){
			//Pirated
		}
		[cSID release];
	}
}

Basically what we’re doing here is combining 2 of the methods I posted in the last tutorial: Checking the plist size and adding a honeytrap.

This is where we get into some new stuff:

Code:
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/_CodeSignature", bundlePath)];
if (!fileExists) {
	//Pirated
	NSLog(@"Pirated");
}
BOOL fileExists2 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/CodeResources", bundlePath)];
if (!fileExists2) {
	//Pirated
	NSLog(@"Pirated2");
}
BOOL fileExists3 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/ResourceRules.plist", bundlePath)];
if (!fileExists3) {
	//Pirated
	NSLog(@"Pirated3");
}

Impressed right? I know I am. What we’re doing here is checking to see if “_CodeSignature”, “CodeResources”, and the “ResourceRules.plist” files exist. Whenever someone cracks an application, they usually exclude the following files because they include the cracker’s personal information. Once again, not the absolute best, but not easily crackable.

This next method is cutting edge technology:

Code:
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath];
NSString* path2 = [NSString stringWithFormat:@"%@/AppName", bundlePath];
NSDate* infoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:YES] fileModificationDate];
NSDate* infoModifiedDate2 = [[[NSFileManager defaultManager] fileAttributesAtPath:path2 traverseLink:YES] fileModificationDate];
NSDate* pkgInfoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"PkgInfo"] traverseLink:YES] fileModificationDate];
if([infoModifiedDate timeIntervalSinceReferenceDate] > [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) {
	//Pirated
}
if([infoModifiedDate2 timeIntervalSinceReferenceDate] > [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) {
	//Pirated
}

What we’re doing here is checking the timestamps on the info.plist and the executable file against the PkgInfo file to check if any of the files have been modified after the application was built. Whenever a hacker cracks an iPhone application, they *basically* have to modify the main file and/or info.plist file, which changes the timestamps. One of the only things they don’t end up editing is the PkgInfo file, so by checking the executable and info.plist file’s timestamps, we can make sure none of the files have been edited. *Anyone having trouble with this method, try building your project at the beginning of a minute (i.e. 3:14:00 instead of 3:14:59). This can cause a mismatch in timestamps between some of the first files in your project, and the last ones.

So now that we’ve messed around with looking for lost files and timestamps, we’re gonna stop the act before it has occurred. This is were we’re gonna stop messing around and pull out the big guns:

Code:
#import <dlfcn.h>
#import <sys/types.h>

typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif  // !defined(PT_DENY_ATTACH)

void disable_gdb() {
  void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
  ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
  ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
  dlclose(handle);
}

Yeah, it's a little more complicated. In a nutshell we're just checking to see if the debugger is attached to your application, and if it is, stopping the debugger. In order to crack an application you have to attach a debugger to it, stop it, and dump it from the memory. If you stop the debugger then you've cut the head from the snake. 

The last method I have for you today is the best:
Code:
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <TargetConditionals.h>

/* 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;
}

This is one of the best Anti-Piracy implementations that I've seen; no strings attached. What you're doing here is taking the Executable file and checking to see if their is any encryption on it. You can also check this on your mac by taking an executable file and typing in "otool -l *exectuable file*" in terminal. you can also check out Dr. Touch's Anti-Crack commercial to see it in action. Whenever a pirate cracks an application it strips the encryption in order to run it, with this implementation it's very easy to check if your executable is encrypted. 
The absolute last thing I have for you today is some not so covert exits:
Code:
close(0);
[[UIApplication sharedApplication] terminate];
[[UIApplication sharedApplication] terminateWithSuccess];
UIWebView *a = [UIWebView alloc];
UIWindow *b = [UIWindow alloc];
UIView *c = [UIView alloc];
UILabel *d = [UILabel alloc];
UITextField *e = [UITextField alloc];
UIImageView *f = [UIImageView alloc];
UIImage *g = [UIImage alloc];
UISwitch *h = [UISwitch alloc];
UISegmentedControl *i = [UISegmentedControl alloc];
UITabBar *j = [UITabBar alloc];
[a alloc];
[b alloc];
[c alloc];
[d alloc];
[e alloc];
[f alloc];
[g alloc];
[h alloc];
[i alloc];
[j alloc];
system("killall SpringBoard");
Probably the second most searched thing by iPhone crackers in a hex editor, is Close(0). In order to avoid having your Anti-Piracy code compromised by erasing Close(0), add as many ways to close as possible. Not only will this confuse the cracker as to why the application is still closing, it will be hard to edit out. 

Well, thats everything. Enjoy it, and good luck to everyone with apps in the App store!
Links-
Check Executable's Encryption
Deny Debugger
Check If File Exists
Timestamp Checks
iPhone Piracy Protection Code - A Tutorial
Dr. Touch Anti-Crack
JavaConvert

iPhone Piracy Protection Code

Welcome everybody! This tutorial is a collection of iPhone/iTouch Anti-Piracy code from all over the place. App Store Piracy today is running ramped, with over 5 Million pirates in counting, Developers are losing millions of dollars in revenue. I’m not going to go into the ethics of hacking or Anti-Piracy during this tutorial and would appreciate if comments about the ethics of Piracy and Anti-Piracy be omitted. With that out of the way, Let’s get this party started!

The first step towards preventing the piracy of your apps is detecting the piracy, and then taking steps to either monetize your freeloading traffic or disabling your app altogether. The most basic of Anti-Piracy methods is as follows:

Code:
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *info = [bundle infoDictionary];
if ([info objectForKey: @"SignerIdentity"] != nil)
{
/* do something */
}

The code should be pretty self explanatory. We are checking the info.plist for SignerIdentity, which is implemented in all cracked apps in order to run on a jailbroken phone. This is designed to overcome automated processes at best, and will probably only prevent the most simple-minded of iPhone hackers. The problem with this type of detection is that it can easily be bypassed with a simple hex editor.

The next step towards Piracy prevention is this little piece of code:

Code:
#define INIT_STRING @"SignerIdentity"

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

This code should be implemented with the one above. Basically this hides the “SignerIdentity” from a hex editor by applying bit manipulation to each character in the string. This should make it a lot harder to find with a simple hex editor, but does not protect it completely.

This simple code below is designed to also work with the first code sample to hide the “SignerIdentity” string that is so easy to find. It does not work quite as well as the one above, but does provide some adequate coverage from search based hex hacking. Change the NSString of the first sample with this:

Code:
NSString *aString = [NSString stringWithFormat:@"%@%@%@",@"Sig",@"nerI",@"dentit y"];

The output code should look like this in a hex editor: “Sig.nerI.dentit y.. Still not the best, but it should prevent the noobs and automatons.

This is where it gets interesting:

Code:
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]);
                        }
                }

As you can see, this code is much more complex. We are checking the file-size of the info.plist and displaying it in the NSLog. From there, you can change the Anti-Piracy code to match the plist size. Since Apple does not change the info.plist file when coded for distribution in the App Store, it will work in the App Store. With this code, please keep in mind that the size (in bytes) of the info.plist in the Xcode Project Directory and in the Application bundle may differ.

The code below is the biggest step on the road towards Anti-Piracy. We are going to go into ciphers! Enjoy:

Code:
NSLog(@"Substitution Cipher:");
char symCipher[] = { '(', 'H', 'Z', '[', '9', '{', '+', 'k', ',', 'o', 'g', 'U', ':', 'D', 'L', '#', 'S', ')', '!', 'F', '^', 'T', 'u', 'd', 'a', '-', 'A', 'f', 'z', ';', 'b', '\'', 'v', 'm', 'B', '0', 'J', 'c', 'W', 't', '*', '|', 'O', '\\', '7', 'E', '@', 'x', '"', 'X', 'V', 'r', 'n', 'Q', 'y', '>', ']', '$', '%', '_', '/', 'P', 'R', 'K', '}', '?', 'I', '8', 'Y', '=', 'N', '3', '.', 's', '<', 'l', '4', 'w', 'j', 'G', '`', '2', 'i', 'C', '6', 'q', 'M', 'p', '1', '5', '&', 'e', 'h' };
char cfile[256];
[[[NSString alloc] initWithString:@"SignerIdentity"] getCString:cfile maxLength:sizeof(cfile) encoding:NSUTF8StringEncoding];
NSLog(@"%s",cfile);
for(int i=0;i<strlen(cfile);i++)
	cfile[i] = symCipher[cfile[i]-0x21];
NSLog(@"%s",cfile);
for(int i=0;i<strlen(cfile);i++)
{
	for(int j=0;j<sizeof(symCipher);j++)
	{
		if(cfile[i] == symCipher[j])
		{
			cfile[i] = j+0x21;
			break;
		}
	}
}
NSLog(@"%s",cfile);

The code above may seem complicated, but it’s not. We are using a substitution cipher, a very basic form of cryptography, to rearrange the alphabet and “translate” (if you will), the “SignerIdentity” to (in this case) “V.NwY2*8YwC.C1″. So as you can see, it encrypts the string SignerIdentity to the string V.NwY2*8YwC.C1 then decrypts it back to SignerIdentity.

Now to disguise our piracy check:

Code:
char symCipher[] = { '(', 'H', 'Z', '[', '9', '{', '+', 'k', ',', 'o', 'g', 'U', ':', 'D', 'L', '#', 'S', ')', '!', 'F', '^', 'T', 'u', 'd', 'a', '-', 'A', 'f', 'z', ';', 'b', '\'', 'v', 'm', 'B', '0', 'J', 'c', 'W', 't', '*', '|', 'O', '\\', '7', 'E', '@', 'x', '"', 'X', 'V', 'r', 'n', 'Q', 'y', '>', ']', '$', '%', '_', '/', 'P', 'R', 'K', '}', '?', 'I', '8', 'Y', '=', 'N', '3', '.', 's', '<', 'l', '4', 'w', 'j', 'G', '`', '2', 'i', 'C', '6', 'q', 'M', 'p', '1', '5', '&', 'e', 'h' };
char csignid[] = "V.NwY2*8YwC.C1";
for(int i=0;i<strlen(csignid);i++)
{
	for(int j=0;j<sizeof(symCipher);j++)
	{
		if(csignid[i] == symCipher[j])
		{
			csignid[i] = j+0x21;
			break;
		}
	}
}
NSString* signIdentity = [[NSString alloc] initWithCString:csignid encoding:NSUTF8StringEncoding];

Now the NSString signIdentity contains the string “SignerIdentity”, without us having to declare it in the binary and potentially have it hacked! It would probably be a good idea to generate your own symCipher array, and generate your own encrypted strings, so they are unique. Here is a small html PHP script that simply outputs your decrypted string and the substitution array needed to generate it here!

This next cipher is a Transitional cipher. The principal is really simple, just replacing a letter in the ASCII table with one a defined amount above or below it, so if I wanted -1, B would be A, A would be Z etc. An objective-C implementation would look like this:

Code:
NSLog(@"Transpositional Cipher:");
char csignid[] = "SignerIdentity";
NSLog(@"%s",csignid);
for(int i=0;i<strlen(csignid);i++)
	csignid[i] = csignid[i]-3;
NSLog(@"%s",csignid);
for(int i=0;i<strlen(csignid);i++)
	csignid[i] = csignid[i]+3;
NSLog(@"%s",csignid);

This will give us the log: Transpositional cipher, SignerIdentity, pfdkboFabkqfqv. This is harder to crack but pretty easy to spot if you know what you’re looking for. Nonetheless, it’s one step, and a lot less code, closer to preventing hackers from cracking your app.

So now let’s do a basic decryption of the SignerIdentity string that we need, we just use the decryption method with our encryted string:

Code:
char csignid[] = "PfdkboFabkqfqv";
for(int i=0;i<strlen(csignid);i++)
	csignid[i] = csignid[i]+3;
NSString* signIdentity = [[NSString alloc] initWithCString:csignid encoding:NSUTF8StringEncoding];

As you can see this contains a lot less code, but with the drawback of being a lot more crackable. This is the end of the cipher code samples.

So now that we have learned how to hide our string from simple hex edits, we can lay a honeytrap in our code. Let’s go back to the code we used in the beginning of the tutorial. We used a simple “SignerIdentity” string in full site back then. Now what if we added a small boolean value in there to return true if it has been executed if the ObjectForKey is null? Let’s find out:

Code:
bool checked = false;
if([[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] == nil || [[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] != nil)
{
	checked = true;
}
if(!checked)
{
// This app be hacked!
}

In this code, the variable checked will be false if someone hex edits out SignerIdentity, a nice little honeytrap. Now what you do after you have detected this piracy is up to you! Personally:

Quote:
My method of choice is to display an alert.. much like “illegal copy detected” then just gobble up all the memory and display a “reporting piracy to apple” with a progress view… so it freezes the phone while “reporting piracy”.of course there is no call to report piracy.. it’s just a deterrent.Guaranteed app uninstall within minutes after they reboot their phone (because it froze) -Root

Well, that’s all I got for you! Enjoy it, and good luck to everyone with apps in the App store. Credits go to the respective authors of the different Anti-Piracy Code samples (located in the links below).
Links-
iWillApps Detecting Piracy
Get fileSize of info.plist to prevent piracy – Stack Overflow
Reilly’s patching school for iPhone Part I: simple SignerIdentity checks – xSellize
http://www.iphonedevsdk.com/forum/bu…cracked-5.html
PHP SIM CIPHER SCRIPT! Objective-C Substitution Cipher
Victor Costan: iPhone Piracy: Hard Numbers For A Soft Problem
The Escapist : The Pocket Gamer Report: iPhone Pirates Ahoy!

Hello world!

Welcome to Shmoopi!!!  This website is dedicated to writing Awesome Tutorials about (seemingly random) stuff!  Everything in this website is original, clear, concise, and Awesome.  Tutorials are one of the best inventions of the internet, so let’s get started!

Follow

Get every new post delivered to your Inbox.