--- /dev/null
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 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
--- /dev/null
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 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
--- /dev/null
+{
+ 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
--- /dev/null
+<?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>
--- /dev/null
+{
+ 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
--- /dev/null
+<?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>
--- /dev/null
+
+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.
--- /dev/null
+// !$*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;
+ };
+}
--- /dev/null
+// !$*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;
+}
--- /dev/null
+//
+// Prefix header for all source files of the 'The Cheat' target in the 'The Cheat' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
--- /dev/null
+
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 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