]> Dogcows Code - chaz/thecheat/commitdiff
The Cheat 1.0b1 v1.0b1
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Thu, 3 Apr 2003 19:00:00 +0000 (12:00 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Thu, 3 Apr 2003 19:00:00 +0000 (12:00 -0700)
16 files changed:
AppController.h [new file with mode: 0644]
AppController.m [new file with mode: 0644]
English.lproj/InfoPlist.strings [new file with mode: 0644]
English.lproj/MainMenu.nib/classes.nib [new file with mode: 0644]
English.lproj/MainMenu.nib/info.nib [new file with mode: 0644]
English.lproj/MainMenu.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/MainMenu.nib/objects.nib [new file with mode: 0644]
English.lproj/MainMenu~.nib/classes.nib [new file with mode: 0644]
English.lproj/MainMenu~.nib/info.nib [new file with mode: 0644]
English.lproj/MainMenu~.nib/keyedobjects.nib [new file with mode: 0644]
English.lproj/MainMenu~.nib/objects.nib [new file with mode: 0644]
Read Me.txt [new file with mode: 0644]
The Cheat.pbproj/chaz.pbxuser [new file with mode: 0644]
The Cheat.pbproj/project.pbxproj [new file with mode: 0644]
The_Cheat_Prefix.h [new file with mode: 0644]
main.m [new file with mode: 0644]

diff --git a/AppController.h b/AppController.h
new file mode 100644 (file)
index 0000000..7917887
--- /dev/null
@@ -0,0 +1,69 @@
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Project:   The Cheat
+//
+// File:      AppController.h
+// Created:   Wed Aug 13 2003
+//
+// Copyright: 2003 Chaz McGarvey.  All rights reserved.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#import <Cocoa/Cocoa.h>
+
+
+// constants
+enum
+{
+       TYPE_STRING, TYPE_INTEGER, TYPE_FLOAT
+};
+
+enum
+{
+       SIZE_8_BIT, SIZE_16_BIT, SIZE_32_BIT, SIZE_64_BIT
+};
+
+
+@interface AppController : NSObject
+{
+       BOOL                    cheating;
+       
+       NSArray                 *processList;
+       
+       NSMutableArray  *addressList;
+       BOOL                    searching;
+       
+       IBOutlet id             window;
+       IBOutlet id             processPopup;
+       IBOutlet id             searchTextField;
+       IBOutlet id             changeTextField;
+       IBOutlet id             searchButton;
+       IBOutlet id             changeButton;
+       IBOutlet id             typePopup;
+       IBOutlet id             sizePopup;
+       IBOutlet id             statusText;
+       IBOutlet id             statusBar;
+       IBOutlet id             addressTable;
+}
+
+- (void)reset;
+
+- (void)firstSearch:(id)nothing;
+- (void)search:(id)nothing;
+
+- (void)change;
+
+- (void)updateProcessPopup;
+- (void)updateTypePopup;
+- (void)updateSizePopup;
+- (void)updateSearchButton;
+- (void)updateChangeButton;
+- (void)updateStatusText;
+
+- (void)rebuildProcessList;
+
+- (IBAction)processPopup:(id)sender;
+- (IBAction)typePopup:(id)sender;
+- (IBAction)searchButton:(id)sender;
+- (IBAction)changeButton:(id)sender;
+
+@end
\ No newline at end of file
diff --git a/AppController.m b/AppController.m
new file mode 100644 (file)
index 0000000..d5de59e
--- /dev/null
@@ -0,0 +1,912 @@
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Project:   The Cheat
+//
+// File:      AppController.m
+// Created:   Wed Aug 13 2003
+//
+// Copyright: 2003 Chaz McGarvey.  All rights reserved.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#import "AppController.h"
+
+#include <mach/vm_map.h>
+#include <mach/mach_traps.h>
+
+
+// defines
+#define PID_SELECTED   [[[processList objectAtIndex:[processPopup indexOfSelectedItem]] objectForKey:@"NSApplicationProcessIdentifier"] intValue]
+#define TYPE_SELECTED  [typePopup indexOfSelectedItem]
+#define SIZE_SELECTED  [sizePopup indexOfSelectedItem]
+
+
+@implementation AppController
+
+- (id)init
+{
+       if ( self = [super init] )
+       {
+               
+       }
+
+       return self;
+}
+
+- (void)awakeFromNib
+{
+       NSNotificationCenter    *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
+
+       [self rebuildProcessList];
+       [self updateProcessPopup];
+       [self updateTypePopup];
+       [self updateSizePopup];
+       [self updateChangeButton];
+       [self updateStatusText];
+
+       [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidLaunchApplicationNotification" object:nil];
+       [nc addObserver:self selector:@selector(processListChanged:) name:@"NSWorkspaceDidTerminateApplicationNotification" object:nil];
+       
+       [self reset];
+}
+
+
+- (void)reset
+{
+       if ( cheating )
+       {
+               cheating = NO;
+
+               [addressList release], addressList = nil;
+
+               // update the interface
+               [typePopup setEnabled:YES];
+               [sizePopup setEnabled:YES];
+               [searchTextField setStringValue:@""];
+               [changeTextField setStringValue:@""];
+               [addressTable reloadData];
+       }
+}
+
+
+- (void)firstSearch:(id)nothing
+{
+       NSAutoreleasePool                       *pool = [[NSAutoreleasePool alloc] init];
+       
+       pid_t                                           pid = (pid_t)PID_SELECTED;
+       vm_map_t                                        task;
+
+       kern_return_t                           result;
+
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+
+       char unsigned                           *data;
+       vm_size_t                                       dataCnt;
+
+       char unsigned                           *string8bit = (char unsigned *)[[searchTextField stringValue] lossyCString];
+       long unsigned                           stringSize = strlen( string8bit );
+       char                                            integer8bit = (char)[searchTextField intValue];
+       short                                           integer16bit = (short)[searchTextField intValue];
+       long                                            integer32bit = (long)[searchTextField intValue];
+       long long                                       integer64bit = (long long)[searchTextField intValue];
+       float                                           float32bit = (float)[searchTextField floatValue];
+       double                                          float64bit = (double)[searchTextField doubleValue];
+
+       BOOL                                            done = NO;
+
+       if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
+       {
+               NSLog( @"task_for_pid returned error: %i", result );
+               return;
+       }
+
+       addressList = [[NSMutableArray alloc] init];
+
+       while ( !done )
+       {
+               if ( (result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+
+                       done = YES;
+               }
+
+               //NSLog( @"address: %X, size: %i", address, size );
+
+               if ( (info.protection & VM_PROT_READ) && ((info.protection & VM_PROT_WRITE) >> 1) )
+               {
+                       data = (char unsigned *)malloc( size );
+                       dataCnt = size;
+
+                       if ( (result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               done = YES;
+                       }
+
+                       if ( result == KERN_SUCCESS )
+                       {
+                               long unsigned   i, max = (long unsigned)dataCnt;
+
+                               //NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
+
+                               switch ( TYPE_SELECTED )
+                               {
+                                       case TYPE_STRING:
+                                               switch ( SIZE_SELECTED )
+                                               {
+                                                       case SIZE_8_BIT:
+                                                       {
+                                                               long unsigned   maxString = max - stringSize;
+
+                                                               for ( i = 0; i < maxString; i += sizeof(char unsigned) )
+                                                               {
+                                                                       if ( strncmp( string8bit, data+i, stringSize ) == 0 )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+                                               }
+                                               break;
+
+                                       case TYPE_INTEGER:
+                                               switch ( SIZE_SELECTED )
+                                               {
+                                                       case SIZE_8_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(char) )
+                                                               {
+                                                                       if ( integer8bit == *((char *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+
+                                                       case SIZE_16_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(short) )
+                                                               {
+                                                                       if ( integer16bit == *((short *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+
+                                                       case SIZE_32_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(long) )
+                                                               {
+                                                                       if ( integer32bit == *((long *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+
+                                                       case SIZE_64_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(long long) )
+                                                               {
+                                                                       if ( integer64bit == *((long long *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+                                               }
+                                               break;
+
+                                       case TYPE_FLOAT:
+                                               switch ( SIZE_SELECTED+2 )
+                                               {
+                                                       case SIZE_32_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(float) )
+                                                               {
+                                                                       if ( float32bit == *((float *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+
+                                                       case SIZE_64_BIT:
+                                                       {
+                                                               for ( i = 0; i < max; i += sizeof(double) )
+                                                               {
+                                                                       if ( float64bit == *((double *)(data+i)) )
+                                                                       {
+                                                                               [addressList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                       }
+                                                               break;
+                                               }
+                                               break;
+                               }
+                       }
+
+                       free( data );
+               }
+
+               address += size;
+       }
+
+       searching = NO;
+
+       // update the interface
+       [statusBar stopAnimation:self];
+       [self updateProcessPopup];
+       [self updateSearchButton];
+       [self updateTypePopup];
+       [self updateSizePopup];
+       [self updateChangeButton];
+       [self updateStatusText];
+       [addressTable reloadData];
+
+       [pool release];
+}
+
+- (void)search:(id)nothing
+{
+       NSAutoreleasePool                       *pool = [[NSAutoreleasePool alloc] init];
+       
+       pid_t                                           pid = (pid_t)PID_SELECTED;
+       vm_map_t                                        task;
+
+       kern_return_t                           result;
+
+       vm_address_t                            address = 0x0;
+       vm_size_t                                       size = 0;
+       vm_region_basic_info_data_t     info;
+       mach_msg_type_number_t          infoCnt = 8;
+       mach_port_t                                     object_name = 0;
+
+       char unsigned                           *data;
+       vm_size_t                                       dataCnt;
+
+       char unsigned                           *string8bit = (char unsigned *)[[searchTextField stringValue] lossyCString];
+       long unsigned                           stringSize = strlen( string8bit );
+       char                                            integer8bit = (char)[searchTextField intValue];
+       short                                           integer16bit = (short)[searchTextField intValue];
+       long                                            integer32bit = (long)[searchTextField intValue];
+       long long                                       integer64bit = (long long)[searchTextField intValue];
+       float                                           float32bit = (float)[searchTextField floatValue];
+       double                                          float64bit = (double)[searchTextField doubleValue];
+
+       long unsigned                           j, max = [addressList count];
+
+       NSMutableArray                          *newList = [[NSMutableArray alloc] init];
+
+       if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
+       {
+               NSLog( @"task_for_pid returned error: %i", result );
+               return;
+       }
+
+       for ( j = 0; j < max; j++ )
+       {
+               long unsigned           item = [[addressList objectAtIndex:j] unsignedLongValue];
+
+               address = (vm_address_t)item;
+
+               if ( (result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name )) != KERN_SUCCESS )
+               {
+                       if ( result != KERN_INVALID_ADDRESS )
+                       {
+                               NSLog( @"vm_region returned error: %i", result );
+                       }
+
+                       break;
+               }
+
+               //NSLog( @"address: %X, size: %i", address, size );
+
+               if ( (info.protection & VM_PROT_READ) && ((info.protection & VM_PROT_WRITE) >> 1) )
+               {
+                       data = (char unsigned *)malloc( size );
+                       dataCnt = size;
+
+                       if ( (result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt )) != KERN_SUCCESS && result != KERN_PROTECTION_FAILURE )
+                       {
+                               NSLog( @"vm_read_overwrite returned error: %i", result );
+                               free( data );
+                               break;
+                       }
+
+                       if ( result == KERN_SUCCESS )
+                       {
+                               long unsigned   i = item - (long unsigned)address;
+
+                               if ( i < (long unsigned)dataCnt )
+                               {
+                                       //NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
+
+                                       switch ( TYPE_SELECTED )
+                                       {
+                                               case TYPE_STRING:
+                                                       switch ( SIZE_SELECTED )
+                                                       {
+                                                               case SIZE_8_BIT:
+                                                               {
+                                                                       if ( strncmp( string8bit, data+i, stringSize ) == 0 )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+                                                       }
+                                                       break;
+
+                                               case TYPE_INTEGER:
+                                                       switch ( SIZE_SELECTED )
+                                                       {
+                                                               case SIZE_8_BIT:
+                                                               {
+                                                                       if ( integer8bit == *((char *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+
+                                                               case SIZE_16_BIT:
+                                                               {
+                                                                       if ( integer16bit == *((short *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+
+                                                               case SIZE_32_BIT:
+                                                               {
+                                                                       if ( integer32bit == *((long *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+
+                                                               case SIZE_64_BIT:
+                                                               {
+                                                                       if ( integer64bit == *((long long *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+                                                       }
+                                                       break;
+
+                                               case TYPE_FLOAT:
+                                                       switch ( SIZE_SELECTED+2 )
+                                                       {
+                                                               case SIZE_32_BIT:
+                                                               {
+                                                                       if ( float32bit == *((float *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+
+                                                               case SIZE_64_BIT:
+                                                               {
+                                                                       if ( float64bit == *((double *)(data+i)) )
+                                                                       {
+                                                                               [newList addObject:[NSNumber numberWithUnsignedLong:(long unsigned)address + i]];
+                                                                       }
+                                                               }
+                                                                       break;
+                                                       }
+                                                       break;
+                                       }
+                               }
+                       }
+
+                       free( data );
+               }
+       }
+
+       [addressList release];
+       addressList = newList;
+
+       searching = NO;
+
+       // update the interface
+       [statusBar stopAnimation:self];
+       [self updateProcessPopup];
+       [self updateSearchButton];
+       [self updateTypePopup];
+       [self updateSizePopup];
+       [self updateChangeButton];
+       [self updateStatusText];
+       [addressTable reloadData];
+
+       [pool release];
+}
+
+
+- (void)change
+{
+       pid_t                                           pid = (pid_t)PID_SELECTED;
+       vm_map_t                                        task;
+
+       kern_return_t                           result;
+
+       char unsigned                           *string8bit = (char unsigned *)[[changeTextField stringValue] lossyCString];
+       long unsigned                           stringSize = strlen( string8bit );
+       char                                            integer8bit = (char)[changeTextField intValue];
+       short                                           integer16bit = (short)[changeTextField intValue];
+       long                                            integer32bit = (long)[changeTextField intValue];
+       long long                                       integer64bit = (long long)[changeTextField intValue];
+       float                                           float32bit = (float)[changeTextField floatValue];
+       double                                          float64bit = (double)[changeTextField doubleValue];
+
+       NSEnumerator                            *enumerator = [addressTable selectedRowEnumerator];
+       NSNumber                                        *row;
+
+       if ( (result = task_for_pid( current_task(), pid, &task)) != KERN_SUCCESS )
+       {
+               NSLog( @"task_for_pid returned error: %i", result );
+               return;
+       }
+
+       while ( row = [enumerator nextObject] )
+       {
+               long unsigned           item = [[addressList objectAtIndex:[row intValue]] unsignedLongValue];
+
+               //NSLog( @"address: %X", item );
+
+               switch ( TYPE_SELECTED )
+               {
+                       case TYPE_STRING:
+                               switch ( SIZE_SELECTED )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)string8bit, (mach_msg_type_number_t)stringSize );
+                                       }
+                                               break;
+                               }
+                               break;
+
+                       case TYPE_INTEGER:
+                               switch ( SIZE_SELECTED )
+                               {
+                                       case SIZE_8_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer8bit), sizeof(char) );
+                                       }
+                                               break;
+
+                                       case SIZE_16_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer16bit), sizeof(short) );
+                                       }
+                                               break;
+
+                                       case SIZE_32_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer32bit), sizeof(long) );
+                                       }
+                                               break;
+
+                                       case SIZE_64_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&integer64bit), sizeof(long long) );
+                                       }
+                                               break;
+                               }
+                               break;
+
+                       case TYPE_FLOAT:
+                               switch ( SIZE_SELECTED+2 )
+                               {
+                                       case SIZE_32_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&float32bit), sizeof(float) );
+                                       }
+                                               break;
+
+                                       case SIZE_64_BIT:
+                                       {
+                                               result = vm_write( task, (vm_address_t)item, (vm_offset_t)(&float64bit), sizeof(double) );
+                                       }
+                                               break;
+                               }
+                               break;
+               }
+       }
+}
+
+
+- (void)updateProcessPopup
+{
+       if ( searching )
+       {
+               [processPopup setEnabled:NO];
+       }
+       else
+       {
+               [processPopup setEnabled:YES];
+       }
+}
+
+- (void)updateTypePopup
+{
+       if ( cheating || searching )
+       {
+               [typePopup setEnabled:NO];
+       }
+       else
+       {
+               int                     selected = [typePopup indexOfSelectedItem];
+               
+               [typePopup setEnabled:YES];
+               
+               [typePopup removeAllItems];
+
+               [typePopup addItemWithTitle:@"String"];
+               [typePopup addItemWithTitle:@"Integer"];
+               [typePopup addItemWithTitle:@"Float"];
+
+               [typePopup selectItemAtIndex:selected];
+       }
+}
+
+- (void)updateSizePopup
+{
+       if ( cheating || searching )
+       {
+               [sizePopup setEnabled:NO];
+       }
+       else
+       {
+               [sizePopup setEnabled:YES];
+               
+               [sizePopup removeAllItems];
+
+               switch ( TYPE_SELECTED )
+               {
+                       case TYPE_STRING:
+                               [sizePopup addItemWithTitle:@"  8-bit"];
+                               break;
+
+                       case TYPE_INTEGER:
+                               [sizePopup addItemWithTitle:@"  8-bit"];
+                               [sizePopup addItemWithTitle:@"16-bit"];
+                               [sizePopup addItemWithTitle:@"32-bit"];
+                               [sizePopup addItemWithTitle:@"64-bit"];
+                               break;
+
+                       case TYPE_FLOAT:
+                               [sizePopup addItemWithTitle:@"32-bit"];
+                               [sizePopup addItemWithTitle:@"64-bit"];
+                               break;
+               }
+       }
+}
+
+- (void)updateSearchButton
+{
+       if ( searching )
+       {
+               [searchTextField setEnabled:NO];
+               [searchButton setEnabled:NO];
+       }
+       else
+       {
+               [searchTextField setEnabled:YES];
+               [searchButton setEnabled:YES];
+       }
+}
+
+- (void)updateChangeButton
+{
+       if ( [addressTable selectedRow] == -1 || searching )
+       {
+               [changeTextField setEnabled:NO];
+               [changeButton setEnabled:NO];
+       }
+       else
+       {
+               [changeTextField setEnabled:YES];
+               [changeButton setEnabled:YES];
+       }
+}
+
+- (void)updateStatusText
+{
+       if ( searching )
+       {
+               [statusText setStringValue:@"Searching..."];
+       }
+       else if ( !cheating )
+       {
+               [statusText setStringValue:[NSString stringWithFormat:@"PID: %i", PID_SELECTED]];
+       }
+       else // cheating
+       {
+               [statusText setStringValue:[NSString stringWithFormat:@"Found: %i", [addressList count]]];
+       }
+
+       [statusText display];
+}
+
+
+- (void)processListChanged:(NSNotification *)note
+{
+       if ( cheating && [[note name] isEqualToString:@"NSWorkspaceDidTerminateApplicationNotification"] )
+       {
+               int                     pid = PID_SELECTED;
+               int                     other = [[[note userInfo] objectForKey:@"NSApplicationProcessIdentifier"] intValue];
+               
+               // check to make sure the program we were cheating wasn't the one that quit
+               if ( pid == other )
+               {
+                       // it was, so let's take care of it
+                       NSBeginAlertSheet( @"", @"OK", nil, nil, window, nil, nil, nil, 0, @"The application that was being cheated has quit." );
+                       
+                       [self reset];
+               }
+       }
+
+       [self rebuildProcessList];
+       [self updateProcessPopup];
+       [self updateStatusText];
+}
+
+
+- (void)rebuildProcessList
+{
+       NSString                *selected = [[processPopup titleOfSelectedItem] retain];
+       int                             i, max;
+
+       [processList release];
+       processList = [[[NSWorkspace sharedWorkspace] launchedApplications] retain];
+
+       max = [processList count];
+
+       [processPopup setImagePosition:NSImageOverlaps];
+
+       [processPopup removeAllItems];
+
+       for ( i = 0; i < max; i++ )
+       {
+               NSString        *name = [[processList objectAtIndex:i] objectForKey:@"NSApplicationName"];
+               NSString        *path = [[processList objectAtIndex:i] objectForKey:@"NSApplicationPath"];
+
+               NSImage         *image = [[NSWorkspace sharedWorkspace] iconForFile:path];
+
+               [processPopup addItemWithTitle:name];
+
+               [image setScalesWhenResized:YES];
+               [image setSize:NSMakeSize( 16.0, 16.0 )];
+
+               [[processPopup itemAtIndex:i] setImage:image];
+
+               if ( [selected isEqualToString:[processPopup itemTitleAtIndex:i]] )
+               {
+                       [processPopup selectItemAtIndex:i];
+               }
+       }
+
+       [selected release];
+}
+
+
+- (void)dealloc
+{
+       [self reset];
+       
+       [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
+
+       [processList release];
+       
+       [super dealloc];
+}
+
+
+- (IBAction)processPopup:(id)sender
+{
+       [self reset];
+
+       [self updateStatusText];
+}
+
+- (IBAction)typePopup:(id)sender
+{
+       [self updateSizePopup];
+}
+
+- (IBAction)searchButton:(id)sender
+{
+       if ( [[searchTextField stringValue] isEqualToString:@""] )
+       {
+               NSBeep();
+               return;
+       }
+
+       searching = YES;
+
+       // update the interface
+       [statusBar startAnimation:self];
+       [self updateProcessPopup];
+       [self updateSearchButton];
+       [self updateTypePopup];
+       [self updateSizePopup];
+       [self updateChangeButton];
+       [self updateStatusText];
+
+       if ( !cheating )
+       {
+               cheating = YES;
+
+               [NSThread detachNewThreadSelector:@selector(firstSearch:) toTarget:self withObject:nil];
+       }
+       else
+       {
+               [NSThread detachNewThreadSelector:@selector(search:) toTarget:self withObject:nil];
+       }
+/*
+       {
+               pid_t                   pid = (pid_t)PID_SELECTED;
+               vm_map_t                task;
+
+               kern_return_t   result;
+               //int                           waitStatus;
+
+               addressList = [[NSMutableArray alloc] init];
+
+               result = task_for_pid( current_task(), pid, &task );
+
+               if ( result == KERN_SUCCESS )
+                       NSLog( @"KERN_SUCCESS" );
+               else if ( result == KERN_INVALID_ADDRESS )
+                       NSLog( @"KERN_INVALID_ADDRESS" );
+               else if ( result == KERN_INVALID_ARGUMENT )
+                       NSLog( @"KERN_INVALID_ARGUMENT" );
+               else if ( result == KERN_PROTECTION_FAILURE )
+                       NSLog( @"KERN_PROTECTION_FAILURE" );
+               else if ( result == KERN_NO_SPACE )
+                       NSLog( @"KERN_NO_SPACE" );
+
+               if ( ptrace( PT_ATTACH, pid, 0, 0 ) != -1 )
+               {
+                       if ( waitpid( pid, &waitStatus, WUNTRACED ) == pid )
+                       {
+                               if ( WIFSTOPPED(waitStatus) )
+                               {
+                                       NSLog( @"process stopped" );
+                               }
+                               else
+                               {
+                                       NSLog( @"process didn't stop" );
+                               }
+
+                               {
+                                       vm_address_t                            address = 0x1b000;
+                                       vm_size_t                                       size = 0;
+                                       vm_region_basic_info_data_t     info;
+                                       mach_msg_type_number_t          infoCnt = 8;
+                                       mach_port_t                                     object_name = 0;
+
+                                       BOOL                                            canRead, canWrite, canExecute;
+
+                                       char unsigned                           *data;
+                                       vm_size_t                                       dataCnt;
+
+                                       NSLog( @"pid: %i, task: %i", pid, task );
+                                       
+                                       result = vm_region( task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)(&info), &infoCnt, &object_name );
+
+                                       NSLog( @"info count: %i", (int)infoCnt );
+
+                                       if ( result == KERN_SUCCESS )
+                                               NSLog( @"KERN_SUCCESS" );
+                                       else if ( result == KERN_INVALID_ADDRESS )
+                                               NSLog( @"KERN_INVALID_ADDRESS" );
+                                       else if ( result == KERN_INVALID_ARGUMENT )
+                                               NSLog( @"KERN_INVALID_ARGUMENT" );
+                                       else if ( result == KERN_PROTECTION_FAILURE )
+                                               NSLog( @"KERN_PROTECTION_FAILURE" );
+                                       else if ( result == KERN_NO_SPACE )
+                                               NSLog( @"KERN_NO_SPACE" );
+
+                                       NSLog( @"address: %X, size: %i", address, size );
+
+                                       canRead = info.protection & VM_PROT_READ;
+                                       canWrite = (info.protection & VM_PROT_WRITE) >> 1;
+                                       canExecute = (info.protection & VM_PROT_EXECUTE) >> 2;
+
+                                       if ( canRead )
+                                               NSLog( @"can read" );
+                                       if ( canWrite )
+                                               NSLog( @"can write" );
+                                       if ( canExecute )
+                                               NSLog( @"can execute" );
+
+                                       data = (char unsigned *)malloc( size );
+                                       dataCnt = size;
+
+                                       result = vm_read_overwrite( task, address, size, (vm_address_t)data, &dataCnt );
+
+                                       if ( result == KERN_SUCCESS )
+                                               NSLog( @"KERN_SUCCESS" );
+                                       else if ( result == KERN_INVALID_ADDRESS )
+                                               NSLog( @"KERN_INVALID_ADDRESS" );
+                                       else if ( result == KERN_INVALID_ARGUMENT )
+                                               NSLog( @"KERN_INVALID_ARGUMENT" );
+                                       else if ( result == KERN_PROTECTION_FAILURE )
+                                               NSLog( @"KERN_PROTECTION_FAILURE" );
+                                       else if ( result == KERN_NO_SPACE )
+                                               NSLog( @"KERN_NO_SPACE" );
+
+                                       NSLog( @"data: %X, size: %i", (vm_address_t)data, dataCnt );
+
+                                       free( data );
+                               }
+                       }
+                       else
+                       {
+                               NSLog( @"waitpid() failed" );
+                       }
+
+                       ptrace( PT_DETACH, pid, 0, 0 );
+               }
+               else
+               {
+                       NSLog( @"ptrace() failed" );
+               }
+       }*/
+}
+
+- (IBAction)changeButton:(id)sender
+{
+       [self change];
+}
+
+
+- (int)numberOfRowsInTableView:(NSTableView *)table
+{
+       if ( cheating && !searching )
+               return [addressList count];
+
+       return 0;
+}
+
+- (id)tableView:(NSTableView *)table objectValueForTableColumn:(NSTableColumn *)column row:(int)row
+{
+       return [NSString stringWithFormat:@"%X", [[addressList objectAtIndex:row] unsignedLongValue]];
+}
+
+- (void)tableView:(NSTableView *) setObjectValue:(id)object forTableColumn:(NSTableColumn *)column row:(int)row
+{
+       return;
+}
+
+- (void)tableViewSelectionDidChange:(NSNotification *)note
+{
+       [self updateChangeButton];
+}
+
+
+@end
\ No newline at end of file
diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..623ed62
Binary files /dev/null and b/English.lproj/InfoPlist.strings differ
diff --git a/English.lproj/MainMenu.nib/classes.nib b/English.lproj/MainMenu.nib/classes.nib
new file mode 100644 (file)
index 0000000..e08ceca
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {changeButton = id; processPopup = id; searchButton = id; typePopup = id; }; 
+            CLASS = AppController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                addressTable = id; 
+                changeButton = id; 
+                changeTextField = id; 
+                processPopup = id; 
+                searchButton = id; 
+                searchTextField = id; 
+                sizePopup = id; 
+                statusBar = id; 
+                statusText = id; 
+                typePopup = id; 
+                window = id; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib
new file mode 100644 (file)
index 0000000..6ea9806
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBDocumentLocation</key>
+       <string>88 78 356 240 0 0 1280 1002 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>29</key>
+               <string>122 595 201 44 0 0 1280 1002 </string>
+       </dict>
+       <key>IBFramework Version</key>
+       <string>291.0</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>29</integer>
+               <integer>348</integer>
+               <integer>410</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>6L60</string>
+</dict>
+</plist>
diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..3d050c8
Binary files /dev/null and b/English.lproj/MainMenu.nib/keyedobjects.nib differ
diff --git a/English.lproj/MainMenu.nib/objects.nib b/English.lproj/MainMenu.nib/objects.nib
new file mode 100644 (file)
index 0000000..27f331f
Binary files /dev/null and b/English.lproj/MainMenu.nib/objects.nib differ
diff --git a/English.lproj/MainMenu~.nib/classes.nib b/English.lproj/MainMenu~.nib/classes.nib
new file mode 100644 (file)
index 0000000..e08ceca
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    IBClasses = (
+        {
+            ACTIONS = {changeButton = id; processPopup = id; searchButton = id; typePopup = id; }; 
+            CLASS = AppController; 
+            LANGUAGE = ObjC; 
+            OUTLETS = {
+                addressTable = id; 
+                changeButton = id; 
+                changeTextField = id; 
+                processPopup = id; 
+                searchButton = id; 
+                searchTextField = id; 
+                sizePopup = id; 
+                statusBar = id; 
+                statusText = id; 
+                typePopup = id; 
+                window = id; 
+            }; 
+            SUPERCLASS = NSObject; 
+        }, 
+        {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+    ); 
+    IBVersion = 1; 
+}
\ No newline at end of file
diff --git a/English.lproj/MainMenu~.nib/info.nib b/English.lproj/MainMenu~.nib/info.nib
new file mode 100644 (file)
index 0000000..6ea9806
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>IBDocumentLocation</key>
+       <string>88 78 356 240 0 0 1280 1002 </string>
+       <key>IBEditorPositions</key>
+       <dict>
+               <key>29</key>
+               <string>122 595 201 44 0 0 1280 1002 </string>
+       </dict>
+       <key>IBFramework Version</key>
+       <string>291.0</string>
+       <key>IBOpenObjects</key>
+       <array>
+               <integer>29</integer>
+               <integer>348</integer>
+               <integer>410</integer>
+       </array>
+       <key>IBSystem Version</key>
+       <string>6L60</string>
+</dict>
+</plist>
diff --git a/English.lproj/MainMenu~.nib/keyedobjects.nib b/English.lproj/MainMenu~.nib/keyedobjects.nib
new file mode 100644 (file)
index 0000000..026ec00
Binary files /dev/null and b/English.lproj/MainMenu~.nib/keyedobjects.nib differ
diff --git a/English.lproj/MainMenu~.nib/objects.nib b/English.lproj/MainMenu~.nib/objects.nib
new file mode 100644 (file)
index 0000000..5b9086e
Binary files /dev/null and b/English.lproj/MainMenu~.nib/objects.nib differ
diff --git a/Read Me.txt b/Read Me.txt
new file mode 100644 (file)
index 0000000..98588ea
--- /dev/null
@@ -0,0 +1,50 @@
+
+The Cheat 1.0b
+by Chaz McGarvey
+
+
+WHAT THE CHEAT IS:
+
+The Cheat is a small, easy-to-use utility that grants you the ability to ultimately "cheat" another application at runtime.  The most obvious use is for games.  With the help of The Cheat, you can instantly replenish your life, raise your score, give yourself more time, or almost anything else you might need done in a game you are stuck at.
+
+
+HOW DO YOU USE THE CHEAT:
+
+First, select the program you want to cheat from the list of processes.  Then choose the type and size of the variable you want to change using the popup menus.  Since The Cheat will have no idea which variable you want to change or where it is, you're going to have to search for it before you can change it.  Enter the current value of the variable you want to change in the search text field and push "Search."  The Cheat will report what it found.  If there are multiple hits, you should search for the variable again after it has changed in the game.  Ideally, you would keep searching until there was only one possible location for the variable to be, and then you would change it.  If you have searched a million times but there are still more than one results, you can still change the variables one by one or all at the same time if you want (just select the variables from the list on the right).  Be careful when doing this if there are very many hits because of the obvious possibility that you might change something that ought not have been changed.  If you are searching for a variable and it keeps reporting 0 hits, you may have chosen the wrong type of variable of the game might have incorporated some type of anti-cheat features.  Usually even those can be cheated with enough patience, however.
+
+
+HOW DOES THE CHEAT WORK:
+
+The basic ideas of which The Cheat is based on are not new.  There have been many utilities for all of the major platforms that work the same as The Cheat.  But it has been hard to find a good "cheater" for Mac OS X until I wrote The Cheat, though I know of at least one other similar utility which only supports integers.  This little gem uses "undocumented" BSD-level functions to bypass the protected memory system Mac OS X uses in order to mess around with the memory of other programs.  A game's variables (amount of life, time left, strength, special abilities, etc.) are somewhere in its own section of memory.  It's simply a matter of finding where a certain variable is stored and changing it to whatever we want.
+
+
+ANYTHING ELSE YOU SHOULD KNOW:
+
+The Cheat is currently beta software.  It is _not_ optimized (it's not running as fast as it could), and I can't even guarantee that it works.  I would like The Cheat to be the best it can be, though, so if you have any suggestions or bug fixes or success stories or funny jokes, please send them to me.  That's the only way The Cheat will be able to improve.  As for the future, The Cheat will be optimized by 1.0, and I hope to have as many bugs squashed as possible.  I think I'll even include a decent Read Me and hopefully I'll have an icon.
+
+
+VERSION HISTORY:
+
+1.0b1 (9/4/03) - First public version.
+
+
+CONTACT ME:
+
+Chaz McGarvey
+
+Email: chaz@brokenzipper.com
+iChat: ChazMP
+
+http://www.brokenzipper.com/
+
+
+IF YOU ARE FEELING CHARITABLE:
+
+I will probably take donations if you feel I'm worth it.  Rest assured, it will be put to good use on a programming book or something.  School is keeping me busy, but a little light reading on the side never killed anyone.
+
+Also, I need an icon if any of you happen to be Photoshop gurus.  I have no idea what it should look like, so good luck if you want to help me in that area.  I would also be ecstatic if any of you could translate The Cheat (and I suppose the final Read Me) into additional languages, as I quite am languistically challenged.
+
+
+LEGAL STUFF:
+
+Basically, don't sue me if you think my software broke something of yours because I need to finish school and that would just not be cool.  Oh yeah, and The Cheat is copyrighted material, which means I own it and you can't steal it.  But it's free, so I don't know why anybody would do that.  Anyway, have a nice day.
diff --git a/The Cheat.pbproj/chaz.pbxuser b/The Cheat.pbproj/chaz.pbxuser
new file mode 100644 (file)
index 0000000..60ee588
--- /dev/null
@@ -0,0 +1,480 @@
+// !$*UTF8*$!
+{
+       29B97313FDCFA39411CA2CEA = {
+               activeBuildStyle = 4A9504CCFFE6A4B311CA0CBA;
+               activeExecutable = 6E31BC0D04EB164300A80003;
+               activeTarget = 29B97326FDCFA39411CA2CEA;
+               addToTargets = (
+                       29B97326FDCFA39411CA2CEA,
+               );
+               codeSenseManager = 6EAFEFEF05D0CAEA00C357EF;
+               executables = (
+                       6E31BC0D04EB164300A80003,
+               );
+               perUserDictionary = {
+                       PBXPerProjectTemplateStateSaveDate = 97569444;
+                       PBXPrepackagedSmartGroups_v2 = (
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       activationKey = OldTargetSmartGroup;
+                                       clz = PBXTargetSmartGroup;
+                                       description = "Displays all targets of the project.";
+                                       globalID = 1C37FABC04509CD000000102;
+                                       name = Targets;
+                                       preferences = {
+                                               image = Targets;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXTargetSmartGroup2;
+                                       description = "Displays all targets of the project as well as nested build phases.";
+                                       globalID = 1C37FBAC04509CD000000102;
+                                       name = Targets;
+                                       preferences = {
+                                               image = Targets;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXExecutablesSmartGroup;
+                                       description = "Displays all executables of the project.";
+                                       globalID = 1C37FAAC04509CD000000102;
+                                       name = Executables;
+                                       preferences = {
+                                               image = Executable;
+                                       };
+                               },
+                               {
+                                       " PBXTransientLocationAtTop " = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXErrorsWarningsSmartGroup;
+                                       description = "Displays files with errors or warnings.";
+                                       globalID = 1C08E77C0454961000C914BD;
+                                       name = "Errors and Warnings";
+                                       preferences = {
+                                               fnmatch = "";
+                                               image = WarningsErrors;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = 1CC0EA4004350EF90044410B;
+                                       name = "Implementation Files";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "?*\\.[mcMC]";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "This group displays Interface Builder NIB Files.";
+                                       globalID = 1CC0EA4004350EF90041110B;
+                                       name = "NIB Files";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "*.nib";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = no;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFindSmartGroup;
+                                       description = "Displays Find Results.";
+                                       globalID = 1C37FABC05509CD000000102;
+                                       name = "Find Results";
+                                       preferences = {
+                                               image = spyglass;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = no;
+                                       absolutePathToBundle = "";
+                                       clz = PBXBookmarksSmartGroup;
+                                       description = "Displays Project Bookmarks.";
+                                       globalID = 1C37FABC05539CD112110102;
+                                       name = Bookmarks;
+                                       preferences = {
+                                               image = Bookmarks;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = XCSCMSmartGroup;
+                                       description = "Displays files with interesting SCM status.";
+                                       globalID = E2644B35053B69B200211256;
+                                       name = SCM;
+                                       preferences = {
+                                               image = PBXRepository;
+                                               isLeaf = 0;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXSymbolsSmartGroup;
+                                       description = "Displays all symbols for the project.";
+                                       globalID = 1C37FABC04509CD000100104;
+                                       name = "Project Symbols";
+                                       preferences = {
+                                               image = ProjectSymbols;
+                                               isLeaf = 1;
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = PBXTemplateMarker;
+                                       name = "Simple Filter SmartGroup";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "*.nib";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                               {
+                                       PBXTransientLocationAtTop = bottom;
+                                       absolutePathToBundle = "";
+                                       clz = PBXFilenameSmartGroup;
+                                       description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter.";
+                                       globalID = PBXTemplateMarker;
+                                       name = "Simple Regular Expression SmartGroup";
+                                       preferences = {
+                                               canSave = 1;
+                                               fnmatch = "";
+                                               image = SmartFolder;
+                                               isLeaf = 0;
+                                               recursive = 1;
+                                               regex = "?*\\.[mcMC]";
+                                               root = "<PROJECT>";
+                                       };
+                               },
+                       );
+                       "PBXTemplateGeometry-F5F68CF101725D4C0D7A8F4C" = {
+                               Frame = "{{0, 0}, {1280, 873}}";
+                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                               };
+                               RubberWindowFrame = "0 87 1280 915 0 0 1280 1002 ";
+                       };
+                       PBXWorkspaceContents = (
+                               {
+                                       PBXProjectWorkspaceModule_StateKey_Rev39 = {
+                                               PBXProjectWorkspaceModule_DEGV_Geometry = {
+                                                       _collapsingFrameDimension = 0;
+                                                       _indexOfCollapsedView = 0;
+                                                       _percentageOfCollapsedView = 0;
+                                                       isCollapsed = yes;
+                                                       sizes = (
+                                                               "{{0, 0}, {1280, 127}}",
+                                                               "{{0, 127}, {1280, 746}}",
+                                                       );
+                                               };
+                                               PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
+                                                       BoundsStr = "{{0, 0}, {1265, 110}}";
+                                                       Rows = (
+                                                               0,
+                                                       );
+                                                       VisibleRectStr = "{{0, 0}, {1265, 110}}";
+                                               };
+                                               PBXProjectWorkspaceModule_EditorOpen = true;
+                                               PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+                                                       PBXSplitModuleInNavigatorKey = {
+                                                               Split0 = {
+                                                                       bookmark = 6EAFF00605D0D29D00C357EF;
+                                                                       history = (
+                                                                               6EAFEFFD05D0CB9B00C357EF,
+                                                                       );
+                                                               };
+                                                               SplitCount = 1;
+                                                       };
+                                               };
+                                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                                       GroupTreeCollapsed = yes;
+                                                       PBXProjectWorkspaceModule_SGTM_Geometry = {
+                                                               _collapsingFrameDimension = 182;
+                                                               _indexOfCollapsedView = 0;
+                                                               _percentageOfCollapsedView = 0.1421875;
+                                                               sizes = (
+                                                                       "{{0, 0}, {1280, 873}}",
+                                                               );
+                                                       };
+                                               };
+                                               PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1280, 127}}";
+                                               PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 127}, {1280, 746}}";
+                                               PBXProjectWorkspaceModule_OldSuperviewFrame = "{{0, 0}, {1280, 873}}";
+                                               PBXProjectWorkspaceModule_SGTM = {
+                                                       PBXBottomSmartGroupGIDs = (
+                                                               1C37FBAC04509CD000000102,
+                                                               1C37FAAC04509CD000000102,
+                                                               1C08E77C0454961000C914BD,
+                                                               1CC0EA4004350EF90044410B,
+                                                               1CC0EA4004350EF90041110B,
+                                                               1C37FABC05509CD000000102,
+                                                               1C37FABC05539CD112110102,
+                                                               E2644B35053B69B200211256,
+                                                               1C37FABC04509CD000100104,
+                                                       );
+                                                       PBXSmartGroupTreeModuleColumnData = {
+                                                               PBXSmartGroupTreeModuleColumnWidthsKey = (
+                                                                       165,
+                                                               );
+                                                               PBXSmartGroupTreeModuleColumnsKey_v4 = (
+                                                                       MainColumn,
+                                                               );
+                                                       };
+                                                       PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
+                                                               PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
+                                                                       29B97314FDCFA39411CA2CEA,
+                                                                       080E96DDFE201D6D7F000001,
+                                                                       29B97315FDCFA39411CA2CEA,
+                                                               );
+                                                               PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
+                                                                       (
+                                                                               3,
+                                                                               1,
+                                                                               0,
+                                                                       ),
+                                                               );
+                                                               PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {165, 855}}";
+                                                       };
+                                                       PBXTopSmartGroupGIDs = (
+                                                       );
+                                               };
+                                       };
+                               },
+                       );
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXClassBrowserModule" = {
+                               OptionsSetName = "Hierarchy, all classes";
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
+                       };
+                       "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+                               PBXProjectWorkspaceModule_StateKey_Rev39 = {
+                                       PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = {
+                                               BoundsStr = "{{0, 0}, {1083, 856}}";
+                                               Rows = (
+                                                       0,
+                                               );
+                                               VisibleRectStr = "{{0, 0}, {1083, 856}}";
+                                       };
+                                       PBXProjectWorkspaceModule_EditorOpen = false;
+                                       PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+                                               PBXSplitModuleInNavigatorKey = {
+                                                       SplitCount = 1;
+                                               };
+                                       };
+                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                               PBXProjectWorkspaceModule_SGTM_Geometry = {
+                                                       _collapsingFrameDimension = 0;
+                                                       _indexOfCollapsedView = 0;
+                                                       _percentageOfCollapsedView = 0;
+                                                       sizes = (
+                                                               "{{0, 0}, {182, 873}}",
+                                                               "{{182, 0}, {1098, 873}}",
+                                                       );
+                                               };
+                                       };
+                                       PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {1098, 873}}";
+                                       PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {750, 480}}";
+                                       PBXProjectWorkspaceModule_OldSuperviewFrame = "{{182, 0}, {1098, 873}}";
+                                       PBXProjectWorkspaceModule_SGTM = {
+                                               PBXBottomSmartGroupGIDs = (
+                                                       1C37FBAC04509CD000000102,
+                                                       1C37FAAC04509CD000000102,
+                                                       1C08E77C0454961000C914BD,
+                                                       1CC0EA4004350EF90044410B,
+                                                       1CC0EA4004350EF90041110B,
+                                                       1C37FABC05509CD000000102,
+                                                       1C37FABC05539CD112110102,
+                                                       E2644B35053B69B200211256,
+                                                       1C37FABC04509CD000100104,
+                                               );
+                                               PBXSmartGroupTreeModuleColumnData = {
+                                                       PBXSmartGroupTreeModuleColumnWidthsKey = (
+                                                               165,
+                                                       );
+                                                       PBXSmartGroupTreeModuleColumnsKey_v4 = (
+                                                               MainColumn,
+                                                       );
+                                               };
+                                               PBXSmartGroupTreeModuleOutlineStateKey_v7 = {
+                                                       PBXSmartGroupTreeModuleOutlineStateExpansionKey = (
+                                                       );
+                                                       PBXSmartGroupTreeModuleOutlineStateSelectionKey = (
+                                                               (
+                                                                       0,
+                                                               ),
+                                                       );
+                                                       PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {165, 855}}";
+                                               };
+                                               PBXTopSmartGroupGIDs = (
+                                               );
+                                       };
+                               };
+                       };
+                       PBXWorkspaceGeometries = (
+                               {
+                                       Frame = "{{0, 0}, {1280, 873}}";
+                                       PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                                       };
+                                       RubberWindowFrame = "0 87 1280 915 0 0 1280 1002 ";
+                               },
+                       );
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+                               Frame = "{{0, 0}, {480, 217}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "400 592 480 238 0 0 1280 1002 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXClassBrowserModule" = {
+                               ClassesFrame = "{{0, 0}, {408, 96}}";
+                               ClassesTreeTableConfiguration = (
+                                       PBXClassNameColumnIdentifier,
+                                       208,
+                                       PBXClassBookColumnIdentifier,
+                                       22,
+                               );
+                               Frame = "{{0, 0}, {655, 476}}";
+                               MembersFrame = "{{0, 96}, {408, 404}}";
+                               MembersTreeTableConfiguration = (
+                                       PBXMemberTypeIconColumnIdentifier,
+                                       22,
+                                       PBXMemberNameColumnIdentifier,
+                                       216,
+                                       PBXMemberTypeColumnIdentifier,
+                                       133,
+                                       PBXMemberBookColumnIdentifier,
+                                       22,
+                               );
+                               RubberWindowFrame = "312 452 655 518 0 0 1280 1002 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+                               Frame = "{{0, 0}, {400, 201}}";
+                               PBXModuleWindowStatusBarHidden = YES;
+                               RubberWindowFrame = "50 974 400 222 0 0 1280 1002 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectFindModule" = {
+                               Frame = "{{0, 0}, {614, 100}}";
+                               RubberWindowFrame = "333 720 614 142 0 0 1280 1002 ";
+                       };
+                       "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+                               Frame = "{{0, 0}, {1280, 873}}";
+                               PBXProjectWorkspaceModule_GeometryKey_Rev15 = {
+                               };
+                               RubberWindowFrame = "0 87 1280 915 0 0 1280 1002 ";
+                       };
+                       PBXWorkspaceStateSaveDate = 97569444;
+               };
+               perUserProjectItems = {
+                       6EAFEFFD05D0CB9B00C357EF = 6EAFEFFD05D0CB9B00C357EF;
+                       6EAFF00605D0D29D00C357EF = 6EAFF00605D0D29D00C357EF;
+               };
+               sourceControlManager = 6EAFEFEE05D0CAEA00C357EF;
+               userBuildSettings = {
+               };
+       };
+       29B97326FDCFA39411CA2CEA = {
+               activeExec = 0;
+               executables = (
+                       6E31BC0D04EB164300A80003,
+               );
+       };
+       6E31BC0D04EB164300A80003 = {
+               activeArgIndex = 2147483647;
+               activeArgIndices = (
+               );
+               argumentStrings = (
+               );
+               configStateDict = {
+               };
+               debuggerPlugin = GDBDebugging;
+               dylibVariantSuffix = "";
+               enableDebugStr = 1;
+               environmentEntries = (
+               );
+               isa = PBXExecutable;
+               name = "The Cheat";
+               shlibInfoDictList = (
+               );
+               sourceDirectories = (
+               );
+       };
+       6E31BC0F04EB1BEF00A80003 = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {1235, 14592}}";
+                       sepNavSelRange = "{18650, 0}";
+                       sepNavVisRect = "{{0, 12541}, {1235, 714}}";
+               };
+       };
+       6EAFEFEE05D0CAEA00C357EF = {
+               isa = PBXSourceControlManager;
+               scmConfiguration = {
+               };
+               scmType = scm.cvs;
+       };
+       6EAFEFEF05D0CAEA00C357EF = {
+               indexTemplatePath = "";
+               isa = PBXCodeSenseManager;
+               usesDefaults = 1;
+               wantsCodeCompletion = 1;
+               wantsCodeCompletionAutoPopup = 0;
+               wantsCodeCompletionAutoSuggestions = 0;
+               wantsCodeCompletionCaseSensitivity = 1;
+               wantsCodeCompletionOnlyMatchingItems = 1;
+               wantsCodeCompletionParametersIncluded = 1;
+               wantsCodeCompletionPlaceholdersInserted = 1;
+               wantsCodeCompletionTabCompletes = 1;
+               wantsIndex = 1;
+       };
+       6EAFEFFD05D0CB9B00C357EF = {
+               fRef = 6E31BC0F04EB1BEF00A80003;
+               isa = PBXTextBookmark;
+               name = "AppController.m: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1022;
+               vrLoc = 0;
+       };
+       6EAFF00605D0D29D00C357EF = {
+               fRef = 6E31BC0F04EB1BEF00A80003;
+               isa = PBXTextBookmark;
+               name = "AppController.m: 804";
+               rLen = 0;
+               rLoc = 18650;
+               rType = 0;
+               vrLen = 1350;
+               vrLoc = 18122;
+       };
+}
diff --git a/The Cheat.pbproj/project.pbxproj b/The Cheat.pbproj/project.pbxproj
new file mode 100644 (file)
index 0000000..bd26a92
--- /dev/null
@@ -0,0 +1,450 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 39;
+       objects = {
+               080E96DCFE201CFB7F000001 = {
+                       fileRef = 29B97318FDCFA39411CA2CEA;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               080E96DDFE201D6D7F000001 = {
+                       children = (
+                               6E31BC0E04EB1BEF00A80003,
+                               6E31BC0F04EB1BEF00A80003,
+                       );
+                       isa = PBXGroup;
+                       name = Classes;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C165CFE840E0CC02AAC07 = {
+                       children = (
+                               089C165DFE840E0CC02AAC07,
+                       );
+                       isa = PBXVariantGroup;
+                       name = InfoPlist.strings;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C165DFE840E0CC02AAC07 = {
+                       fileEncoding = 10;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist.strings;
+                       name = English;
+                       path = English.lproj/InfoPlist.strings;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               089C165EFE840E0CC02AAC07 = {
+                       fileRef = 089C165CFE840E0CC02AAC07;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+//080
+//081
+//082
+//083
+//084
+//100
+//101
+//102
+//103
+//104
+               1058C7A0FEA54F0111CA2CBB = {
+                       children = (
+                               1058C7A1FEA54F0111CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = "Linked Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               1058C7A1FEA54F0111CA2CBB = {
+                       fallbackIsa = PBXFileReference;
+                       isa = PBXFrameworkReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Cocoa.framework;
+                       path = /System/Library/Frameworks/Cocoa.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               1058C7A2FEA54F0111CA2CBB = {
+                       children = (
+                               29B97325FDCFA39411CA2CEA,
+                               29B97324FDCFA39411CA2CEA,
+                       );
+                       isa = PBXGroup;
+                       name = "Other Frameworks";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               1058C7A3FEA54F0111CA2CBB = {
+                       fileRef = 1058C7A1FEA54F0111CA2CBB;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+//100
+//101
+//102
+//103
+//104
+//170
+//171
+//172
+//173
+//174
+               17587328FF379C6511CA2CBB = {
+                       explicitFileType = wrapper.application;
+                       fallbackIsa = PBXFileReference;
+                       isa = PBXApplicationReference;
+                       path = "The Cheat.app";
+                       refType = 3;
+                       sourceTree = BUILT_PRODUCTS_DIR;
+               };
+//170
+//171
+//172
+//173
+//174
+//190
+//191
+//192
+//193
+//194
+               19C28FACFE9D520D11CA2CBB = {
+                       children = (
+                               17587328FF379C6511CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+//190
+//191
+//192
+//193
+//194
+//290
+//291
+//292
+//293
+//294
+               29B97313FDCFA39411CA2CEA = {
+                       buildSettings = {
+                       };
+                       buildStyles = (
+                               4A9504CCFFE6A4B311CA0CBA,
+                               4A9504CDFFE6A4B311CA0CBA,
+                       );
+                       hasScannedForEncodings = 1;
+                       isa = PBXProject;
+                       mainGroup = 29B97314FDCFA39411CA2CEA;
+                       projectDirPath = "";
+                       targets = (
+                               29B97326FDCFA39411CA2CEA,
+                       );
+               };
+               29B97314FDCFA39411CA2CEA = {
+                       children = (
+                               080E96DDFE201D6D7F000001,
+                               29B97315FDCFA39411CA2CEA,
+                               29B97317FDCFA39411CA2CEA,
+                               29B97323FDCFA39411CA2CEA,
+                               19C28FACFE9D520D11CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = "The Cheat";
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97315FDCFA39411CA2CEA = {
+                       children = (
+                               32CA4F630368D1EE00C91783,
+                               29B97316FDCFA39411CA2CEA,
+                       );
+                       isa = PBXGroup;
+                       name = "Other Sources";
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97316FDCFA39411CA2CEA = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = main.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97317FDCFA39411CA2CEA = {
+                       children = (
+                               29B97318FDCFA39411CA2CEA,
+                               089C165CFE840E0CC02AAC07,
+                       );
+                       isa = PBXGroup;
+                       name = Resources;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97318FDCFA39411CA2CEA = {
+                       children = (
+                               29B97319FDCFA39411CA2CEA,
+                       );
+                       isa = PBXVariantGroup;
+                       name = MainMenu.nib;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97319FDCFA39411CA2CEA = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.nib;
+                       name = English;
+                       path = English.lproj/MainMenu.nib;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97323FDCFA39411CA2CEA = {
+                       children = (
+                               1058C7A0FEA54F0111CA2CBB,
+                               1058C7A2FEA54F0111CA2CBB,
+                       );
+                       isa = PBXGroup;
+                       name = Frameworks;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               29B97324FDCFA39411CA2CEA = {
+                       fallbackIsa = PBXFileReference;
+                       isa = PBXFrameworkReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = AppKit.framework;
+                       path = /System/Library/Frameworks/AppKit.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               29B97325FDCFA39411CA2CEA = {
+                       fallbackIsa = PBXFileReference;
+                       isa = PBXFrameworkReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Foundation.framework;
+                       path = /System/Library/Frameworks/Foundation.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               29B97326FDCFA39411CA2CEA = {
+                       buildPhases = (
+                               29B97327FDCFA39411CA2CEA,
+                               29B97328FDCFA39411CA2CEA,
+                               29B9732BFDCFA39411CA2CEA,
+                               29B9732DFDCFA39411CA2CEA,
+                       );
+                       buildSettings = {
+                               FRAMEWORK_SEARCH_PATHS = "";
+                               HEADER_SEARCH_PATHS = "";
+                               INSTALL_PATH = "$(HOME)/Applications";
+                               LIBRARY_SEARCH_PATHS = "";
+                               OTHER_CFLAGS = "-std=c99";
+                               OTHER_LDFLAGS = "";
+                               PRECOMPILE_PREFIX_HEADER = YES;
+                               PREFIX_HEADER = The_Cheat_Prefix.h;
+                               PRODUCT_NAME = "The Cheat";
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                               WRAPPER_EXTENSION = app;
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXApplicationTarget;
+                       name = "The Cheat";
+                       productInstallPath = "$(HOME)/Applications";
+                       productName = "The Cheat";
+                       productReference = 17587328FF379C6511CA2CBB;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>The Cheat</string>
+       <key>CFBundleGetInfoString</key>
+       <string>The Cheat 1.0b1</string>
+       <key>CFBundleIconFile</key>
+       <string>icon.icns</string>
+       <key>CFBundleIdentifier</key>
+       <string>com.brokenzipper.TheCheat</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>The Cheat</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0b1</string>
+       <key>CFBundleSignature</key>
+       <string>ThCh</string>
+       <key>CFBundleVersion</key>
+       <string>1.0b1</string>
+       <key>NSMainNibFile</key>
+       <string>MainMenu</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+";
+               };
+               29B97327FDCFA39411CA2CEA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               32CA4F650368D2AA00C91783,
+                               6E31BC1004EB1BEF00A80003,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               29B97328FDCFA39411CA2CEA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               080E96DCFE201CFB7F000001,
+                               089C165EFE840E0CC02AAC07,
+                       );
+                       isa = PBXResourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               29B9732BFDCFA39411CA2CEA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               29B9732CFDCFA39411CA2CEA,
+                               6E31BC1104EB1BEF00A80003,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               29B9732CFDCFA39411CA2CEA = {
+                       fileRef = 29B97316FDCFA39411CA2CEA;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                               );
+                       };
+               };
+               29B9732DFDCFA39411CA2CEA = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               1058C7A3FEA54F0111CA2CBB,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+//290
+//291
+//292
+//293
+//294
+//320
+//321
+//322
+//323
+//324
+               32CA4F630368D1EE00C91783 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = The_Cheat_Prefix.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               32CA4F650368D2AA00C91783 = {
+                       fileRef = 32CA4F630368D1EE00C91783;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+//320
+//321
+//322
+//323
+//324
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+               4A9504CCFFE6A4B311CA0CBA = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OPTIMIZATION_CFLAGS = "-O0";
+                               ZERO_LINK = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               4A9504CDFFE6A4B311CA0CBA = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               ZERO_LINK = NO;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+//6E0
+//6E1
+//6E2
+//6E3
+//6E4
+               6E31BC0E04EB1BEF00A80003 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       path = AppController.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31BC0F04EB1BEF00A80003 = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = AppController.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               6E31BC1004EB1BEF00A80003 = {
+                       fileRef = 6E31BC0E04EB1BEF00A80003;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               6E31BC1104EB1BEF00A80003 = {
+                       fileRef = 6E31BC0F04EB1BEF00A80003;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+       };
+       rootObject = 29B97313FDCFA39411CA2CEA;
+}
diff --git a/The_Cheat_Prefix.h b/The_Cheat_Prefix.h
new file mode 100644 (file)
index 0000000..0d0c539
--- /dev/null
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'The Cheat' target in the 'The Cheat' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif
diff --git a/main.m b/main.m
new file mode 100644 (file)
index 0000000..0fcbed4
--- /dev/null
+++ b/main.m
@@ -0,0 +1,17 @@
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Project:   «PROJECTNAME»
+//
+// File:      «FILENAME»
+// Created:   «DATE»
+//
+// Copyright: «YEAR» «FULLUSERNAME».  All rights reserved.
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#import <Cocoa/Cocoa.h>
+
+
+int main( int argc, const char *argv[] )
+{
+       return NSApplicationMain(argc, argv);
+}
\ No newline at end of file
This page took 0.068069 seconds and 4 git commands to generate.