/* * DCPatcher.c * DualityCore * * Created by IT on 10/4/06. * Copyright 2006 __MyCompanyName__. All rights reserved. * */ #include "DCPatcher.h" #include "DCLog.h" #include "DCProcessInfo.h" static EventTypeSpec launchEvents[2] = { {kEventClassApplication, kEventAppLaunched}, {kEventClassApplication, kEventAppTerminated} }; int DCPatchProcess(ProcessSerialNumber *processPSN) { mach_port_t machPortForProcess; mach_port_t portOfOurProcess; int err; struct DCProcessInfo infoForProcessToPatch = DCCreateProcessInfoForPSN(processPSN); // Make sure we do not patch ourself // GetProcessPID(processPSN, &pid); DCLogMessage("pid is %d\n",infoForProcessToPatch.pid); if (infoForProcessToPatch.pid == getpid()) return 1; // -------- char bundleName[255]; CFStringGetCString(infoForProcessToPatch.bundleIdentifier,bundleName, 255,kCFStringEncodingASCII); if (bundleName!=nil) DCLogMessage("%s\n", bundleName); else DCLogMessage("No bundle identifer could be found\n"); portOfOurProcess = mach_task_self(); err = task_for_pid(portOfOurProcess, infoForProcessToPatch.pid, &machPortForProcess); if (err) { DCLogCriticalMessage("task_for_pid err: %d\n", err); return 1; } thread_act_t *threads; int threadCount; err = task_threads(machPortForProcess, &threads, &threadCount); if (err) { DCLogCriticalMessage("task_threads err: %d\n", err); return 1; } err = thread_suspend(threads[0]); if (err) DCLogCriticalMessage("thread_suspend err: %d\n", err); err = thread_abort(threads[0]); if (err) DCLogCriticalMessage("thread_abort err: %d\n", err); return 0; } pascal OSStatus DCInjectNotification(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { int result; ProcessSerialNumber programPSN; UInt32 actualParamSize; EventParamType actualParamType; // Ignore events if they are application termination events if(GetEventKind(theEvent) == kEventAppLaunched) { DCLogMessage("New Application has been launched...\n"); } if(GetEventKind(theEvent) == kEventAppTerminated) { DCLogMessage("The application terminated...\n"); return noErr; } result = GetEventParameter(theEvent, kEventParamProcessID, typeProcessSerialNumber, &actualParamType, sizeof(programPSN), &actualParamSize, &programPSN); // This has been triggered by the launching of an application. We want to get the process // serial number so that we can patch the application as needed. GetEventParameter // will extract this number from the incoming EventRef if (result != noErr) { DCLogCriticalMessage("GetEventParameter() == %d\n", result); return result; } if (actualParamSize == 0 || actualParamType != typeProcessSerialNumber) { DCLogCriticalMessage("GetEventParameter() actual parameters do not match\n"); return -1; } // Install the patches for the application if(!DCPatchProcess(&programPSN)) { DCLogCriticalMessage("Error: Process could not be patched...\n"); } // Call the next event handler on the event return CallNextEventHandler(nextHandler, theEvent); } void DCRegisterForLaunchNotifications() { // Set up and install the event handler for the launch notification EventHandlerUPP launchCallback = NewEventHandlerUPP(DCInjectNotification); //EventHandlerRef handlerRemovalHandler = NULL; OSStatus err = noErr; // Install the application event handler err = InstallApplicationEventHandler(launchCallback, 2, launchEvents, 0, NULL); //err = InstallEventHandler(GetApplicationEventTarget(),launchCallback,2,launchEvents,NULL,NULL); // Test to ensure this worked if(err != noErr) { DCLogCriticalMessage("Error: Could not install event handler.\n"); exit(1); } // Dispose of the event handler UPP DisposeEventHandlerUPP(launchCallback); }