--- /dev/null
+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
#import "CheatServer.h"
+
@class AboutBoxController;
@class HelpController;
@class PreferenceController;
- (IBAction)checkForUpdate:(id)sender;
-// Privilage elevation stuff
-AuthorizationRef _authRef;
-AuthorizationItem _authItem;
-AuthorizationRights _authRights;
-- (int) preAuthorize;
-- (int) launchAuthPrgm;
-
// Server Stuff
- (CheatServer *)cheatServer;
- (BOOL)startCheatServer;
#import "HelpController.h"
#import "PreferenceController.h"
-// Privilage elevation libs
-#include <security/authorization.h>
-#include <security/authorizationdb.h>
-#include <security/authorizationtags.h>
-#include <sys/types.h>
-#include <unistd.h>
-
@implementation AppController
- (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
{
[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
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
// Static Globals
-BOOL static _gLogEnabled = NO;
+BOOL static _gLogEnabled = YES;
FILE static *_gLogFile = stdout;
FILE static *_gDebugFile = NULL;
// 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;
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>IBClasses</key>
- <array>
- <dict>
- <key>ACTIONS</key>
- <dict>
- <key>ibEmailButton</key>
- <string>id</string>
- <key>ibWebsiteButton</key>
- <string>id</string>
- </dict>
- <key>CLASS</key>
- <string>AboutBoxController</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>OUTLETS</key>
- <dict>
- <key>ibDateText</key>
- <string>NSTextField</string>
- <key>ibEmailButton</key>
- <string>NSButton</string>
- <key>ibNameVersionText</key>
- <string>NSTextField</string>
- <key>ibWebsiteButton</key>
- <string>NSButton</string>
- </dict>
- <key>SUPERCLASS</key>
- <string>NSWindowController</string>
- </dict>
- <dict>
- <key>CLASS</key>
- <string>NSMenu</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- <dict>
- <key>CLASS</key>
- <string>FirstResponder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- <dict>
- <key>CLASS</key>
- <string>NSObject</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- </dict>
- </array>
- <key>IBVersion</key>
- <string>1</string>
-</dict>
-</plist>
+{
+ 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
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!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>124 93 356 241 0 0 1280 938 </string>
<key>IBFramework Version</key>
- <string>677</string>
- <key>IBLastKnownRelativeProjectPath</key>
- <string>../The Cheat.xcodeproj</string>
- <key>IBOldestOS</key>
- <integer>5</integer>
+ <string>364.0</string>
+ <key>IBGroupedObjects</key>
+ <dict>
+ <key>3</key>
+ <array>
+ <string>93</string>
+ <string>91</string>
+ </array>
+ <key>7</key>
+ <array>
+ <string>77</string>
+ <string>80</string>
+ <string>87</string>
+ </array>
+ <key>8</key>
+ <array>
+ <string>89</string>
+ <string>81</string>
+ </array>
+ </dict>
+ <key>IBLastGroupID</key>
+ <string>9</string>
<key>IBOpenObjects</key>
<array>
- <integer>78</integer>
+ <integer>85</integer>
</array>
<key>IBSystem Version</key>
- <string>9C7010</string>
- <key>targetFramework</key>
- <string>IBCocoaFramework</string>
+ <string>7U16</string>
</dict>
</plist>
<key>CFBundleExecutable</key>
<string>The Cheat</string>
<key>CFBundleGetInfoString</key>
- <string>The Cheat 1.2.2</string>
+ <string>The Cheat 1.2.3</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
<key>CFBundleIdentifier</key>
<string>com.brokenzipper.TheCheat</string>
+ <key>SecTaskAccess</key>
+ <string>allowed</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>1.2.2</string>
+ <string>1.2.3</string>
<key>CFBundleSignature</key>
<string>chœt</string>
<key>CFBundleURLTypes</key>
</dict>
</array>
<key>CFBundleVersion</key>
- <string>1.2.2</string>
+ <string>1.2.3</string>
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>NSMainNibFile</key>
return SearchIterationLastValue;
}
}
+
return NULL;
}
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 ) {
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;
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;
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;
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;
#include <mach/mach_traps.h> // for task_for_pid(3)
#include <signal.h> // for stop(2)
-
static __inline__ vm_map_t _VMTaskFromPID( pid_t process )
{
vm_map_t task;
- (void)reloadData
-{
+{
if ( _dontUpdate ) {
_updatePending = YES;
return;
//
#import <Cocoa/Cocoa.h>
+#import <Foundation/foundation.h>
+#import <SecurityFoundation/SFAuthorization.h>
+#import <Security/AuthorizationTags.h>
#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];
[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