From: Charles McGarvey Date: Fri, 28 Nov 2008 19:00:00 +0000 (-0700) Subject: The Cheat 1.2.3 X-Git-Tag: v1.2.3 X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fthecheat;a=commitdiff_plain;h=ad02580588e2ca41f15ba8f9bd084561d8d485c2 The Cheat 1.2.3 Bug Fixes: - Issues with getting The Cheat to start up on certain machines. Contributed by nil. --- diff --git a/A few notes.txt b/A few notes.txt new file mode 100644 index 0000000..830c07a --- /dev/null +++ b/A few notes.txt @@ -0,0 +1,7 @@ +The authorization code is taken from iHaxGamez source. + +Memory reading and writing will not work as you would expect if you compile and run The Cheat natively on an intel machine. This is because there are byte ordering (endian) issues that need to be fixed that I haven't been able to (or too lazy to figure out how to get it to work correctly). + +The Xcode project provided is not guaranteed to work for Xcode versions below 3.1 + +-nil \ No newline at end of file diff --git a/AppController.h b/AppController.h index 7eb651f..e4a9765 100644 --- a/AppController.h +++ b/AppController.h @@ -26,6 +26,7 @@ #import "CheatServer.h" + @class AboutBoxController; @class HelpController; @class PreferenceController; @@ -53,13 +54,6 @@ - (IBAction)checkForUpdate:(id)sender; -// Privilage elevation stuff -AuthorizationRef _authRef; -AuthorizationItem _authItem; -AuthorizationRights _authRights; -- (int) preAuthorize; -- (int) launchAuthPrgm; - // Server Stuff - (CheatServer *)cheatServer; - (BOOL)startCheatServer; diff --git a/AppController.m b/AppController.m index 303b1eb..1adfbaf 100644 --- a/AppController.m +++ b/AppController.m @@ -25,13 +25,6 @@ #import "HelpController.h" #import "PreferenceController.h" -// Privilage elevation libs -#include -#include -#include -#include -#include - @implementation AppController @@ -71,90 +64,13 @@ - (id)init { - if ( self = [super init] ) - { - if( geteuid() != 0 ) - { - [self launchAuthPrgm]; - [self setDelegate:self]; - } + if ( self = [super init] ) { + [self setDelegate:self]; } - if( geteuid() != 0 ) - { - NSRunAlertPanel(@"The Cheat must be run as root,", - @"Due to a limitation of Leopard, the application needs elevated privileges to run.", - @"Exit", nil, nil ); - [self terminate: 0]; - } - return self; } -- (int) preAuthorize -{ - int err; - AuthorizationFlags authFlags; - - - NSLog (@"MyWindowController: preAuthorize"); - - if (_authRef) - return errAuthorizationSuccess; - - NSLog (@"MyWindowController: preAuthorize: ** calling AuthorizationCreate...**\n"); - - authFlags = kAuthorizationFlagDefaults; - err = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment, authFlags, &_authRef); - if (err != errAuthorizationSuccess) - return err; - - NSLog (@"MyWindowController: preAuthorize: ** calling AuthorizationCopyRights...**\n"); - - _authItem.name = kAuthorizationRightExecute; - _authItem.valueLength = 0; - _authItem.value = NULL; - _authItem.flags = 0; - _authRights.count = 1; - _authRights.items = (AuthorizationItem*) malloc (sizeof (_authItem)); - memcpy (&_authRights.items[0], &_authItem, sizeof (_authItem)); - authFlags = kAuthorizationFlagDefaults - | kAuthorizationFlagExtendRights - | kAuthorizationFlagInteractionAllowed - | kAuthorizationFlagPreAuthorize; - err = AuthorizationCopyRights (_authRef, &_authRights, kAuthorizationEmptyEnvironment, authFlags, NULL); - - return err; -} - -- (int) launchAuthPrgm -{ - AuthorizationFlags authFlags; - int err; - - // path - NSString * path = [[NSBundle mainBundle] executablePath]; - if (![[NSFileManager defaultManager] isExecutableFileAtPath: path]) - return -1; - - // auth - - if (!_authRef) - { - err = [self preAuthorize]; - if (err != errAuthorizationSuccess) - return err; - } - - // launch - - NSLog (@"MyWindowController: launchWithPath: ** calling AuthorizationExecuteWithPrivileges...**\n"); - authFlags = kAuthorizationFlagDefaults; - err = AuthorizationExecuteWithPrivileges (_authRef, [path cString], authFlags, NULL, NULL); - if(err==0) [NSApp terminate:self]; - - return err; -} - (void)dealloc { @@ -163,14 +79,35 @@ [super dealloc]; } +// http://vgable.com/blog/2008/10/05/restarting-your-cocoa-application/ +- (void)restartOurselves +{ + NSString *killArg1AndOpenArg2Script = @"kill -9 $1 \n open \"$2\""; + NSString *ourPID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]]; + NSString *pathToUs = [[NSBundle mainBundle] bundlePath]; + + NSArray *shArgs = [NSArray arrayWithObjects:@"-c", killArg1AndOpenArg2Script, @"", ourPID, pathToUs, nil]; + NSTask *restartTask = [NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:shArgs]; + [restartTask waitUntilExit]; + NSLog(@"*** ERROR: %@ should have been terminated, but we are still running", pathToUs); + assert(!"We should not be running!"); +} + +- (BOOL) checkExecutablePermissions { + NSDictionary *applicationAttributes = [[NSFileManager defaultManager] fileAttributesAtPath:[[NSBundle mainBundle] executablePath] traverseLink: YES]; + + // We expect 2755 as octal (1517 as decimal, -rwxr-sr-x as extended notation) + return ([applicationAttributes filePosixPermissions] == 1517 && [[applicationAttributes fileGroupOwnerAccountName] isEqualToString: @"procmod"]); +} /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #pragma mark NSApplication Delegate /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + [NSApp activateIgnoringOtherApps:YES]; + // check if this is the first launch if ( ![[NSUserDefaults standardUserDefaults] boolForKey:TCFirstLaunchPref] ) { // FIRST LAUNCH @@ -183,7 +120,7 @@ ChazCheckForUpdate( TCUpdateCheckURL, NO ); } - // automaticall start the cheat server if the pref is set + // automatically start the cheat server if the pref is set if ( [[NSUserDefaults standardUserDefaults] boolForKey:TCRunServerPref] ) { if ( ![self startCheatServer] ) { // inform the user that the server won't start diff --git a/ChazLog.m b/ChazLog.m index e78125b..bee3160 100644 --- a/ChazLog.m +++ b/ChazLog.m @@ -30,7 +30,7 @@ void static _ChazPrint( FILE *output, NSString *format, va_list args ); // Static Globals -BOOL static _gLogEnabled = NO; +BOOL static _gLogEnabled = YES; FILE static *_gLogFile = stdout; FILE static *_gDebugFile = NULL; diff --git a/CheatDocument.m b/CheatDocument.m index b058d74..1810c77 100644 --- a/CheatDocument.m +++ b/CheatDocument.m @@ -1154,8 +1154,8 @@ Process static *_tc_target = nil; // clear the search [_searchData clearResults]; - [ibSearchVariableTable reloadData]; + //[ibSearchVariableTable reloadData]; // this can cause a crash, so commenting it out for now. // clear the selected process [_process release]; _process = nil; diff --git a/English.lproj/AboutBox.nib/classes.nib b/English.lproj/AboutBox.nib/classes.nib index c132e54..f9f3920 100644 --- a/English.lproj/AboutBox.nib/classes.nib +++ b/English.lproj/AboutBox.nib/classes.nib @@ -1,59 +1,18 @@ - - - - - IBClasses - - - ACTIONS - - ibEmailButton - id - ibWebsiteButton - id - - CLASS - AboutBoxController - LANGUAGE - ObjC - OUTLETS - - ibDateText - NSTextField - ibEmailButton - NSButton - ibNameVersionText - NSTextField - ibWebsiteButton - NSButton - - SUPERCLASS - NSWindowController - - - CLASS - NSMenu - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - FirstResponder - LANGUAGE - ObjC - SUPERCLASS - NSObject - - - CLASS - NSObject - LANGUAGE - ObjC - - - IBVersion - 1 - - +{ + IBClasses = ( + { + ACTIONS = {ibEmailButton = id; ibWebsiteButton = id; }; + CLASS = AboutBoxController; + LANGUAGE = ObjC; + OUTLETS = { + ibDateText = NSTextField; + ibEmailButton = NSButton; + ibNameVersionText = NSTextField; + ibWebsiteButton = NSButton; + }; + SUPERCLASS = NSWindowController; + }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/English.lproj/AboutBox.nib/info.nib b/English.lproj/AboutBox.nib/info.nib index 99d506a..4c7b4ef 100644 --- a/English.lproj/AboutBox.nib/info.nib +++ b/English.lproj/AboutBox.nib/info.nib @@ -1,20 +1,37 @@ - + + IBDocumentLocation + 124 93 356 241 0 0 1280 938 IBFramework Version - 677 - IBLastKnownRelativeProjectPath - ../The Cheat.xcodeproj - IBOldestOS - 5 + 364.0 + IBGroupedObjects + + 3 + + 93 + 91 + + 7 + + 77 + 80 + 87 + + 8 + + 89 + 81 + + + IBLastGroupID + 9 IBOpenObjects - 78 + 85 IBSystem Version - 9C7010 - targetFramework - IBCocoaFramework + 7U16 diff --git a/English.lproj/AboutBox.nib/keyedobjects.nib b/English.lproj/AboutBox.nib/keyedobjects.nib index c71d319..7ef2eec 100644 Binary files a/English.lproj/AboutBox.nib/keyedobjects.nib and b/English.lproj/AboutBox.nib/keyedobjects.nib differ diff --git a/Info.plist b/Info.plist index 440bc13..e46e7c6 100644 --- a/Info.plist +++ b/Info.plist @@ -30,11 +30,13 @@ CFBundleExecutable The Cheat CFBundleGetInfoString - The Cheat 1.2.2 + The Cheat 1.2.3 CFBundleIconFile icon.icns CFBundleIdentifier com.brokenzipper.TheCheat + SecTaskAccess + allowed CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -42,7 +44,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.2.2 + 1.2.3 CFBundleSignature chœt CFBundleURLTypes @@ -57,7 +59,7 @@ CFBundleVersion - 1.2.2 + 1.2.3 NSAppleScriptEnabled YES NSMainNibFile diff --git a/SearchContext.m b/SearchContext.m index 82a3939..68495e4 100644 --- a/SearchContext.m +++ b/SearchContext.m @@ -301,6 +301,7 @@ return SearchIterationLastValue; } } + return NULL; } diff --git a/Searching.m b/Searching.m index 2814a32..80ad0d6 100644 --- a/Searching.m +++ b/Searching.m @@ -164,7 +164,6 @@ int SearchIterationAgain( ThreadedTask *task, unsigned iteration ) context->lastRegion = VMMakeRegion( context->process, *(context->lastRegionPtr), 0 ); region = VMNextRegionWithAttributes( context->process, context->lastRegion, VMREGION_READABLE | VMREGION_WRITABLE ); if ( VMRegionIsNotNull( region ) ) { - if ( context->bufferSize < VMRegionSize( region ) ) { char *buf = realloc( context->buffer, VMRegionSize( region ) ); if ( buf ) { @@ -183,9 +182,9 @@ int SearchIterationAgain( ThreadedTask *task, unsigned iteration ) top = *context->lastPerRegionPtr; for ( i = 0; i < top; i++ ) { - ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region); - if ( context->compareFunc(ptr,context->value->_value) ) { + + if (ptr >= context->buffer && context->compareFunc(ptr,context->value->_value)) { if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) { TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) ); context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults; @@ -276,7 +275,7 @@ int SearchIterationLastValue( ThreadedTask *task, unsigned iteration ) for ( i = 0; i < top; i++ ) { ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region); - if ( context->compareFunc(ptr,context->lastValuePtr) ) { + if ( ptr >= context->buffer && context->compareFunc(ptr,context->lastValuePtr) ) { if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) { TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) ); context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults; @@ -453,7 +452,8 @@ int SearchStringIterationAgain( ThreadedTask *task, unsigned iteration ) for ( i = 0; i < top; i++ ) { ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region); - if ( memcmp( ptr, context->value->_value, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) { + + if ( ptr >= context->buffer && memcmp( ptr, context->value->_value, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) { if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) { TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) ); context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults; @@ -542,7 +542,7 @@ int SearchStringIterationLastValue( ThreadedTask *task, unsigned iteration ) for ( i = 0; i < top; i++ ) { ptr = context->buffer + *context->lastAddressPtr - VMRegionAddress(region); - if ( memcmp( ptr, context->lastValuePtr, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) { + if ( ptr >= context->buffer && memcmp( ptr, context->lastValuePtr, MIN(TCArrayElementSize(context->values),context->buffer+VMRegionAddress(region)-ptr) ) == 0 ) { if ( context->numberOfResults >= TCArrayElementCount(context->addresses) ) { TCArrayResize( context->addresses, TCArrayElementCount(context->addresses) + TC_BUFFER_SIZE / sizeof(TCAddress) ); context->addressPtr = (TCAddress *)TCArrayBytes(context->addresses) + context->numberOfResults; diff --git a/VMRegion.m b/VMRegion.m index 612327a..c24d342 100644 --- a/VMRegion.m +++ b/VMRegion.m @@ -40,7 +40,6 @@ #include // for task_for_pid(3) #include // for stop(2) - static __inline__ vm_map_t _VMTaskFromPID( pid_t process ) { vm_map_t task; diff --git a/VariableTable.m b/VariableTable.m index 5d47e11..07ba3ca 100644 --- a/VariableTable.m +++ b/VariableTable.m @@ -70,7 +70,7 @@ - (void)reloadData -{ +{ if ( _dontUpdate ) { _updatePending = YES; return; diff --git a/main.m b/main.m index 68dd64f..7075d5d 100644 --- a/main.m +++ b/main.m @@ -19,9 +19,71 @@ // #import +#import +#import +#import #include "ChazLog.h" -int main( int argc, const char *argv[] ) +void authMe(char * FullPathToMe) +{ + // get authorization as root + + OSStatus myStatus; + + // set up Authorization Item + AuthorizationItem myItems[1]; + myItems[0].name = kAuthorizationRightExecute; + myItems[0].valueLength = 0; + myItems[0].value = NULL; + myItems[0].flags = 0; + + // Set up Authorization Rights + AuthorizationRights myRights; + myRights.count = sizeof (myItems) / sizeof (myItems[0]); + myRights.items = myItems; + + // set up Authorization Flags + AuthorizationFlags myFlags; + myFlags = + kAuthorizationFlagDefaults | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagExtendRights; + + // Create an Authorization Ref using Objects above. NOTE: Login bod comes up with this call. + AuthorizationRef myAuthorizationRef; + myStatus = AuthorizationCreate (&myRights, kAuthorizationEmptyEnvironment, myFlags, &myAuthorizationRef); + + if (myStatus == errAuthorizationSuccess) + { + // prepare communication path - used to signal that process is loaded + FILE *myCommunicationsPipe = NULL; + char myReadBuffer[] = " "; + + // run this app in GOD mode by passing authorization ref and comm pipe (asynchoronous call to external application) + myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef,FullPathToMe,kAuthorizationFlagDefaults,nil,&myCommunicationsPipe); + + // external app is running asynchronously - it will send to stdout when loaded + if (myStatus == errAuthorizationSuccess) + { + read (fileno (myCommunicationsPipe), myReadBuffer, sizeof (myReadBuffer)); + fclose(myCommunicationsPipe); + } + + // release authorization reference + myStatus = AuthorizationFree (myAuthorizationRef, kAuthorizationFlagDestroyRights); + } +} + +bool amIWorthy(void) +{ + // running as root? + AuthorizationRef myAuthRef; + OSStatus stat = AuthorizationCopyPrivilegedReference(&myAuthRef,kAuthorizationFlagDefaults); + + return stat == errAuthorizationSuccess; +} + +int main( int argc, char *argv[] ) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -32,7 +94,18 @@ int main( int argc, const char *argv[] ) [pool release]; - return NSApplicationMain( argc, (const char **) argv ); + if (amIWorthy()) + { + printf("Don't forget to flush! ;-) "); // signal back to close caller + fflush(stdout); + + return NSApplicationMain(argc, (const char **) argv); + } + else + { + authMe(argv[0]); + return 0; + } ChazDebugCleanup(); } \ No newline at end of file