From 368c6acbcfb90dbb5726cbc517e1800ed0f28965 Mon Sep 17 00:00:00 2001 From: Zhang <403799106@qq.com> Date: Tue, 28 Mar 2017 11:23:49 +0100 Subject: [PATCH] Discard InspectiveC as it breaks Building on Xcode 8.3 --- DOCS/CODEOWNERS.md | 32 +- ThirdPartyTools/InspectiveC/ARM64Types.h | 126 ---- ThirdPartyTools/InspectiveC/InspCWrapper.m | 174 ----- ThirdPartyTools/InspectiveC/InspectiveC.h | 51 -- ThirdPartyTools/InspectiveC/InspectiveC.mm | 584 --------------- .../InspectiveC/InspectiveCarm32.mm | 53 -- .../InspectiveC/InspectiveCarm64.mm | 100 --- ThirdPartyTools/InspectiveC/LICENSE.txt | 674 ------------------ ThirdPartyTools/InspectiveC/Makefile | 14 - ThirdPartyTools/InspectiveC/README.md | 208 ------ ThirdPartyTools/InspectiveC/blocks.h | 29 - ThirdPartyTools/InspectiveC/blocks.mm | 41 -- ThirdPartyTools/InspectiveC/control | 10 - ThirdPartyTools/InspectiveC/hashmap.h | 73 -- ThirdPartyTools/InspectiveC/hashmap.mm | 295 -------- ThirdPartyTools/InspectiveC/logging.h | 35 - ThirdPartyTools/InspectiveC/logging.mm | 201 ------ ThirdPartyTools/InspectiveC/obj | 1 - ThirdPartyTools/README.md | 6 +- capstone | 2 +- 20 files changed, 18 insertions(+), 2691 deletions(-) delete mode 100644 ThirdPartyTools/InspectiveC/ARM64Types.h delete mode 100644 ThirdPartyTools/InspectiveC/InspCWrapper.m delete mode 100644 ThirdPartyTools/InspectiveC/InspectiveC.h delete mode 100644 ThirdPartyTools/InspectiveC/InspectiveC.mm delete mode 100644 ThirdPartyTools/InspectiveC/InspectiveCarm32.mm delete mode 100644 ThirdPartyTools/InspectiveC/InspectiveCarm64.mm delete mode 100644 ThirdPartyTools/InspectiveC/LICENSE.txt delete mode 100644 ThirdPartyTools/InspectiveC/Makefile delete mode 100644 ThirdPartyTools/InspectiveC/README.md delete mode 100644 ThirdPartyTools/InspectiveC/blocks.h delete mode 100644 ThirdPartyTools/InspectiveC/blocks.mm delete mode 100644 ThirdPartyTools/InspectiveC/control delete mode 100644 ThirdPartyTools/InspectiveC/hashmap.h delete mode 100644 ThirdPartyTools/InspectiveC/hashmap.mm delete mode 100644 ThirdPartyTools/InspectiveC/logging.h delete mode 100644 ThirdPartyTools/InspectiveC/logging.mm delete mode 120000 ThirdPartyTools/InspectiveC/obj diff --git a/DOCS/CODEOWNERS.md b/DOCS/CODEOWNERS.md index a0aa2ec..7f2b383 100644 --- a/DOCS/CODEOWNERS.md +++ b/DOCS/CODEOWNERS.md @@ -1,5 +1,5 @@ -#Alban Diquet@iSEC Partners -##Hooks/APIHooks/ +# Alban Diquet@iSEC Partners +## Hooks/APIHooks/ - SSLKillSwitch.xm - CommonCryptor.xm @@ -19,28 +19,24 @@ - libC.xm - NSData.xm - NSURLCredential.xm -- NSFileHandle.xm +- NSFileHandle.xm -##/Hooks/Utils/ +## /Hooks/Utils/ Most. But Heavily Modified -#HanSheng Zhang(Naville) +# HanSheng Zhang(Naville) Everything Left. Unless Otherwise Specified -#Zheng Wu(i_82) +# Zheng Wu(i_82) - NSURLSession.xm -- NSKeyedArchiver.xm -- NSKeyedUnarchiver.xm +- NSKeyedArchiver.xm +- NSKeyedUnarchiver.xm -##DavidGoldman -#ThirdPartyTools/InspectiveC +## Elias Limneos +# ThirdPartyTools/classdumpdyld -##Elias Limneos -#ThirdPartyTools/classdumpdyld - -##Carina -#ThirdPartyTools/dumpdecrypted - -##Submodules -#All Submodules Belong To Their Respective Owner +## Carina +# ThirdPartyTools/dumpdecrypted +## Submodules +# All Submodules Belong To Their Respective Owner diff --git a/ThirdPartyTools/InspectiveC/ARM64Types.h b/ThirdPartyTools/InspectiveC/ARM64Types.h deleted file mode 100644 index 29592b2..0000000 --- a/ThirdPartyTools/InspectiveC/ARM64Types.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef ARM64_TYPES_H -#define ARM64_TYPES_H - -// ARM64 defines. -#define alignof(t) __alignof__(t) - -// TODO(DavidGoldman): Treat the regs as a pointer directly to avoid casting? i.e.: -// (*(t *)(&args.regs->general.arr[args.ngrn++])) -#define pa_arg(args, t) \ - ( (args.ngrn < 8) ? ((t)(args.regs->general.arr[args.ngrn++])) : \ - pa_stack_arg(args, t) \ - ) - -#define pa_float(args) \ - ( (args.nsrn < 8) ? args.regs->floating.arr[args.nsrn++].f.f1 : \ - pa_stack_arg(args, float) \ - ) - -#define pa_double(args) \ - ( (args.nsrn < 8) ? args.regs->floating.arr[args.nsrn++].d.d1 : \ - pa_stack_arg(args, double) \ - ) - -// We need to align the sp - we do so via sp = ((sp + alignment - 1) & -alignment). -// Then we increment the sp by the size of the argument and return the argument. -#define pa_stack_arg(args, t) \ - (*(t *)( (args.stack = (unsigned char *)( ((uintptr_t)args.stack + (alignof(t) - 1)) & -alignof(t)) + sizeof(t)) - sizeof(t) )) - -#define pa_two_ints(args, varType, varName, intType) \ - varType varName; \ - if (args.ngrn < 7) { \ - intType a = (intType)args.regs->general.arr[args.ngrn++]; \ - intType b = (intType)args.regs->general.arr[args.ngrn++]; \ - varName = (varType) { a, b }; \ - } else { \ - args.ngrn = 8; \ - intType a = pa_stack_arg(args, intType); \ - intType b = pa_stack_arg(args, intType); \ - varName = (varType) { a, b }; \ - } \ - -#define pa_two_doubles(args, t, varName) \ - t varName; \ - if (args.nsrn < 7) { \ - double a = args.regs->floating.arr[args.nsrn++].d.d1; \ - double b = args.regs->floating.arr[args.nsrn++].d.d1; \ - varName = (t) { a, b }; \ - } else { \ - args.nsrn = 8; \ - double a = pa_stack_arg(args, double); \ - double b = pa_stack_arg(args, double); \ - varName = (t) { a, b }; \ - } \ - -#define pa_four_doubles(args, t, varName) \ - t varName; \ - if (args.nsrn < 5) { \ - double a = args.regs->floating.arr[args.nsrn++].d.d1; \ - double b = args.regs->floating.arr[args.nsrn++].d.d1; \ - double c = args.regs->floating.arr[args.nsrn++].d.d1; \ - double d = args.regs->floating.arr[args.nsrn++].d.d1; \ - varName = (t) { a, b, c, d }; \ - } else { \ - args.nsrn = 8; \ - double a = pa_stack_arg(args, double); \ - double b = pa_stack_arg(args, double); \ - double c = pa_stack_arg(args, double); \ - double d = pa_stack_arg(args, double); \ - varName = (t) { a, b, c, d }; \ - } \ - -typedef union FPReg_ { - __int128_t q; - struct { - double d1; // Holds the double (LSB). - double d2; - } d; - struct { - float f1; // Holds the float (LSB). - float f2; - float f3; - float f4; - } f; -} FPReg; - -struct RegState_ { - union { - uint64_t arr[10]; - struct { - uint64_t x0; - uint64_t x1; - uint64_t x2; - uint64_t x3; - uint64_t x4; - uint64_t x5; - uint64_t x6; - uint64_t x7; - uint64_t x8; - uint64_t lr; - } regs; - } general; - - union { - FPReg arr[8]; - struct { - FPReg q0; - FPReg q1; - FPReg q2; - FPReg q3; - FPReg q4; - FPReg q5; - FPReg q6; - FPReg q7; - } regs; - } floating; -}; - -typedef struct pa_list_ { - struct RegState_ *regs; // Registers saved when function is called. - unsigned char *stack; // Address of current argument. - int ngrn; // The Next General-purpose Register Number. - int nsrn; // The Next SIMD and Floating-point Register Number. -} pa_list; - -#endif - diff --git a/ThirdPartyTools/InspectiveC/InspCWrapper.m b/ThirdPartyTools/InspectiveC/InspCWrapper.m deleted file mode 100644 index 79beda7..0000000 --- a/ThirdPartyTools/InspectiveC/InspCWrapper.m +++ /dev/null @@ -1,174 +0,0 @@ -/* - If you link directly with libinspectivec, it will automatically load the dylib into any process - that you hook into (which is bad if you only want to hook into a single process). You can try - using this method instead. - */ -#include - -typedef void (*inspectiveC_IntFuncT)(int depth); -typedef void (*inspectiveC_ObjectFuncT)(id obj); -typedef void (*inspectiveC_ClassFuncT)(Class clazz); -typedef void (*inspectiveC_SelFuncT)(SEL _cmd); -typedef void (*inspectiveC_voidFuncT)(void); -typedef void (*inspectiveC_ObjectSelFuncT)(id obj, SEL _cmd); -typedef void (*inspectiveC_ClassSelFuncT)(Class clazz, SEL _cmd); - -static void *inspectiveC_Handle = NULL; - -static inspectiveC_IntFuncT $setMaximumRelativeLoggingDepth; - -static inspectiveC_ObjectFuncT $watchObject; -static inspectiveC_ObjectFuncT $unwatchObject; -static inspectiveC_ObjectSelFuncT $watchSelectorOnObject; -static inspectiveC_ObjectSelFuncT $unwatchSelectorOnObject; - -static inspectiveC_ClassFuncT $watchClass; -static inspectiveC_ClassFuncT $unwatchClass; -static inspectiveC_ClassSelFuncT $watchSelectorOnClass; -static inspectiveC_ClassSelFuncT $unwatchSelectorOnClass; - -static inspectiveC_SelFuncT $watchSelector; -static inspectiveC_SelFuncT $unwatchSelector; - -static inspectiveC_voidFuncT $enableLogging; -static inspectiveC_voidFuncT $disableLogging; - -static inspectiveC_voidFuncT $enableCompleteLogging; -static inspectiveC_voidFuncT $disableCompleteLogging; - -static void * inspectiveC_loadFunctionNamed(const char *name) { - void *func = dlsym(inspectiveC_Handle, name); - if (!func) { - NSLog(@"[InspectiveC Wrapper] Unable to load function %s! Error: %s", name, dlerror()); - } - return func; -} - -static void inspectiveC_init() { - static dispatch_once_t predicate; - dispatch_once(&predicate, ^{ - inspectiveC_Handle = dlopen("/usr/lib/libinspectivec.dylib", RTLD_NOW); - - if (inspectiveC_Handle) { - $setMaximumRelativeLoggingDepth = (inspectiveC_IntFuncT)inspectiveC_loadFunctionNamed("InspectiveC_setMaximumRelativeLoggingDepth"); - - $watchObject = (inspectiveC_ObjectFuncT)inspectiveC_loadFunctionNamed("InspectiveC_watchObject"); - $unwatchObject = (inspectiveC_ObjectFuncT)inspectiveC_loadFunctionNamed("InspectiveC_unwatchObject"); - $watchSelectorOnObject = (inspectiveC_ObjectSelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_watchSelectorOnObject"); - $unwatchSelectorOnObject = (inspectiveC_ObjectSelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_unwatchSelectorOnObject"); - - $watchClass = (inspectiveC_ClassFuncT)inspectiveC_loadFunctionNamed("InspectiveC_watchInstancesOfClass"); - $unwatchClass = (inspectiveC_ClassFuncT)inspectiveC_loadFunctionNamed("InspectiveC_unwatchInstancesOfClass"); - $watchSelectorOnClass = (inspectiveC_ClassSelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_watchSelectorOnInstancesOfClass"); - $unwatchSelectorOnClass = (inspectiveC_ClassSelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_unwatchSelectorOnInstancesOfClass"); - - $watchSelector = (inspectiveC_SelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_watchSelector"); - $unwatchSelector = (inspectiveC_SelFuncT)inspectiveC_loadFunctionNamed("InspectiveC_unwatchSelector"); - - $enableLogging = (inspectiveC_voidFuncT)inspectiveC_loadFunctionNamed("InspectiveC_enableLogging"); - $disableLogging = (inspectiveC_voidFuncT)inspectiveC_loadFunctionNamed("InspectiveC_disableLogging"); - - $enableCompleteLogging = (inspectiveC_voidFuncT)inspectiveC_loadFunctionNamed("InspectiveC_enableCompleteLogging"); - $disableCompleteLogging = (inspectiveC_voidFuncT)inspectiveC_loadFunctionNamed("InspectiveC_disableCompleteLogging"); - } else { - NSLog(@"[InspectiveC Wrapper] Unable to load libinspectivec! Error: %s", dlerror()); - } - }); -} - -void setMaximumRelativeLoggingDepth(int depth) { - inspectiveC_init(); - if($setMaximumRelativeLoggingDepth) { - $setMaximumRelativeLoggingDepth(depth); - } -} - -void watchObject(id obj) { - inspectiveC_init(); - if ($watchObject) { - $watchObject(obj); - } -} -void unwatchObject(id obj) { - inspectiveC_init(); - if ($unwatchObject) { - $unwatchObject(obj); - } -} -void watchSelectorOnObject(id obj, SEL _cmd) { - inspectiveC_init(); - if ($watchSelectorOnObject) { - $watchSelectorOnObject(obj, _cmd); - } -} -void unwatchSelectorOnObject(id obj, SEL _cmd) { - inspectiveC_init(); - if ($unwatchSelectorOnObject) { - $unwatchSelectorOnObject(obj, _cmd); - } -} - -void watchClass(Class clazz) { - inspectiveC_init(); - if ($watchClass) { - $watchClass(clazz); - } -} -void unwatchClass(Class clazz) { - inspectiveC_init(); - if ($unwatchClass) { - $unwatchClass(clazz); - } -} -void watchSelectorOnClass(Class clazz, SEL _cmd) { - inspectiveC_init(); - if ($watchSelectorOnClass) { - $watchSelectorOnClass(clazz, _cmd); - } -} -void unwatchSelectorOnClass(Class clazz, SEL _cmd) { - inspectiveC_init(); - if ($unwatchSelectorOnClass) { - $unwatchSelectorOnClass(clazz, _cmd); - } -} - -void watchSelector(SEL _cmd) { - inspectiveC_init(); - if ($watchSelector) { - $watchSelector(_cmd); - } -} -void unwatchSelector(SEL _cmd) { - inspectiveC_init(); - if ($unwatchSelector) { - $unwatchSelector(_cmd); - } -} - -void enableLogging() { - inspectiveC_init(); - if ($enableLogging) { - $enableLogging(); - } -} -void disableLogging() { - inspectiveC_init(); - if ($disableLogging) { - $disableLogging(); - } -} - -void enableCompleteLogging() { - inspectiveC_init(); - if ($enableCompleteLogging) { - $enableCompleteLogging(); - } -} - -void disableCompleteLogging() { - inspectiveC_init(); - if ($disableCompleteLogging) { - $disableCompleteLogging(); - } -} diff --git a/ThirdPartyTools/InspectiveC/InspectiveC.h b/ThirdPartyTools/InspectiveC/InspectiveC.h deleted file mode 100644 index 7240e16..0000000 --- a/ThirdPartyTools/InspectiveC/InspectiveC.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef INSPECTIVE_C_H -#define INSPECTIVE_C_H - -#include - -#if __cplusplus -extern "C" { -#endif - -// Set the maximum logging depth after a hit. -void InspectiveC_setMaximumRelativeLoggingDepth(int depth); - - -// Watches/unwatches the specified object (all selectors). -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void InspectiveC_watchObject(id obj); -void InspectiveC_unwatchObject(id obj); - -// Watches/unwatches the specified selector on the object. -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void InspectiveC_watchSelectorOnObject(id obj, SEL _cmd); -void InspectiveC_unwatchSelectorOnObject(id obj, SEL _cmd); - - -// Watches/unwatches instances of the specified class ONLY - will not watch subclass instances. -void InspectiveC_watchInstancesOfClass(Class clazz); -void InspectiveC_unwatchInstancesOfClass(Class clazz); - -// Watches/unwatches the specified selector on instances of the specified class ONLY - will not -// watch subclass instances. -void InspectiveC_watchSelectorOnInstancesOfClass(Class clazz, SEL _cmd); -void InspectiveC_unwatchSelectorOnInstancesOfClass(Class clazz, SEL _cmd); - - -// Watches/unwatches the specified selector. -void InspectiveC_watchSelector(SEL _cmd); -void InspectiveC_unwatchSelector(SEL _cmd); - -// Enables/disables logging for the current thread. -void InspectiveC_enableLogging(); -void InspectiveC_disableLogging(); - -// Enables/disables logging every message for the current thread. -void InspectiveC_enableCompleteLogging(); -void InspectiveC_disableCompleteLogging(); - -#if __cplusplus -} -#endif - -#endif diff --git a/ThirdPartyTools/InspectiveC/InspectiveC.mm b/ThirdPartyTools/InspectiveC/InspectiveC.mm deleted file mode 100644 index 5ac6847..0000000 --- a/ThirdPartyTools/InspectiveC/InspectiveC.mm +++ /dev/null @@ -1,584 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include - -#include "hashmap.h" -#include "logging.h" - -// Optional - comment this out if you want to log on ALL threads (laggy due to rw-locks). -#define MAIN_THREAD_ONLY - -#define MAX_PATH_LENGTH 1024 - -#define DEFAULT_CALLSTACK_DEPTH 128 -#define CALLSTACK_DEPTH_INCREMENT 64 - -#define DEFAULT_MAX_RELATIVE_RECURSIVE_DESCENT_DEPTH 64 - -#ifdef MAIN_THREAD_ONLY -#define RLOCK -#define WLOCK -#define UNLOCK -#else -static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; - -#define RLOCK pthread_rwlock_rdlock(&lock) -#define WLOCK pthread_rwlock_wrlock(&lock) -#define UNLOCK pthread_rwlock_unlock(&lock) -#endif - -#define WATCH_ALL_SELECTORS_SELECTOR NULL - -#if __arm64__ -#define arg_list pa_list -#else -#define arg_list va_list -#endif - -#ifdef MAIN_THREAD_ONLY -static void performBlockOnProperThread(void (^block)(void)) { - if (pthread_main_np()) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); - } -} -#else -static void performBlockOnProperThread(void (^block)(void)) { - WLOCK; - block(); - UNLOCK; -} -#endif - -// The original objc_msgSend. -static id (*orig_objc_msgSend)(id, SEL, ...); - -// These classes support handling of void *s using callback functions, yet their methods -// accept (fake) ids. =/ i.e. objectForKey: and setObject:forKey: are dangerous for us because what -// looks like an id can be a regular old int and crash our program... -static Class NSMapTable_Class; -static Class NSHashTable_Class; - -// We have to call [ class] when logging to make sure that the class is initialized. -static SEL class_SEL = @selector(class); - -static HashMapRef objectsMap; -static HashMapRef classMap; -static HashMapRef selsSet; -static pthread_key_t threadKey; -static const char *directory; - -// Max callstack depth to log after the last hit. -static int maxRelativeRecursiveDepth = DEFAULT_MAX_RELATIVE_RECURSIVE_DESCENT_DEPTH; - -// HashMap functions. -static int pointerEquality(void *a, void *b) { - uintptr_t ia = reinterpret_cast(a); - uintptr_t ib = reinterpret_cast(b); - return ia == ib; -} - -#ifdef __arm64__ -// 64 bit hash from https://gist.github.com/badboy/6267743. -static inline NSUInteger pointerHash(void *v) { - uintptr_t key = reinterpret_cast(v); - key = (~key) + (key << 21); // key = (key << 21) - key - 1; - key = key ^ (key >> 24); - key = (key + (key << 3)) + (key << 8); // key * 265 - key = key ^ (key >> 14); - key = (key + (key << 2)) + (key << 4); // key * 21 - key = key ^ (key >> 28); - key = key + (key << 31); - return key; -} -#else -// Robert Jenkin's 32 bit int hash. -static inline NSUInteger pointerHash(void *v) { - uintptr_t a = reinterpret_cast(v); - a = (a + 0x7ed55d16) + (a << 12); - a = (a ^ 0xc761c23c) ^ (a >> 19); - a = (a + 0x165667b1) + (a << 5); - a = (a + 0xd3a2646c) ^ (a << 9); - a = (a + 0xfd7046c5) + (a << 3); - a = (a ^ 0xb55a4f09) ^ (a >> 16); - return (NSUInteger)a; -} -#endif - -// Shared structures. -typedef struct CallRecord_ { - id obj; - SEL _cmd; - uintptr_t lr; - int prevHitIndex; // Only used if isWatchHit is set. - char isWatchHit; -} CallRecord; - -typedef struct ThreadCallStack_ { - FILE *file; - char *spacesStr; - CallRecord *stack; - int allocatedLength; - int index; - int numWatchHits; - int lastPrintedIndex; - int lastHitIndex; - char isLoggingEnabled; - char isCompleteLoggingEnabled; -} ThreadCallStack; - -static inline void mapAddSelector(HashMapRef map, id obj_or_class, SEL _cmd) { - HashMapRef selectorSet = (HashMapRef)HMGet(map, (void *)obj_or_class); - if (selectorSet == NULL) { - selectorSet = HMCreate(&pointerEquality, &pointerHash); - HMPut(map, (void *)obj_or_class, selectorSet); - } - - HMPut(selectorSet, _cmd, (void *)YES); -} - -static inline void mapDestroySelectorSet(HashMapRef map, id obj_or_class) { - HashMapRef selectorSet = (HashMapRef)HMRemove(map, (void *)obj_or_class); - if (selectorSet != NULL) { - HMFree(selectorSet); - } -} - -static inline void selectorSetRemoveSelector(HashMapRef selectorSet, SEL _cmd) { - if (selectorSet != NULL) { - HMRemove(selectorSet, _cmd); - } -} - -// Inspective C Public API. - -extern "C" void InspectiveC_setMaximumRelativeLoggingDepth(int depth) { - if (depth >= 0) { - maxRelativeRecursiveDepth = depth; - } -} - -extern "C" void InspectiveC_watchObject(id obj) { - if (obj == nil) { - return; - } - performBlockOnProperThread(^(){ - mapAddSelector(objectsMap, obj, WATCH_ALL_SELECTORS_SELECTOR); - }); -} -extern "C" void InspectiveC_unwatchObject(id obj) { - if (obj == nil) { - return; - } - performBlockOnProperThread(^(){ - mapDestroySelectorSet(objectsMap, obj); - }); -} - -extern "C" void InspectiveC_watchSelectorOnObject(id obj, SEL _cmd) { - if (obj == nil || _cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - mapAddSelector(objectsMap, obj, _cmd); - }); -} -extern "C" void InspectiveC_unwatchSelectorOnObject(id obj, SEL _cmd) { - if (obj == nil || _cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - selectorSetRemoveSelector((HashMapRef)HMGet(objectsMap, obj), _cmd); - }); -} - -extern "C" void InspectiveC_watchInstancesOfClass(Class clazz) { - if (clazz == nil) { - return; - } - performBlockOnProperThread(^(){ - mapAddSelector(classMap, clazz, WATCH_ALL_SELECTORS_SELECTOR); - }); -} -extern "C" void InspectiveC_unwatchInstancesOfClass(Class clazz) { - if (clazz == nil) { - return; - } - performBlockOnProperThread(^(){ - mapDestroySelectorSet(classMap, clazz); - }); -} - -extern "C" void InspectiveC_watchSelectorOnInstancesOfClass(Class clazz, SEL _cmd) { - if (clazz == nil || _cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - mapAddSelector(classMap, clazz, _cmd); - }); -} -extern "C" void InspectiveC_unwatchSelectorOnInstancesOfClass(Class clazz, SEL _cmd) { - if (clazz == nil || _cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - selectorSetRemoveSelector((HashMapRef)HMGet(classMap, clazz), _cmd); - }); -} - -extern "C" void InspectiveC_watchSelector(SEL _cmd) { - if (_cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - HMPut(selsSet, (void *)_cmd, (void *)_cmd); - }); -} -extern "C" void InspectiveC_unwatchSelector(SEL _cmd) { - if (_cmd == NULL) { - return; - } - performBlockOnProperThread(^(){ - HMRemove(selsSet, (void *)_cmd); - }); -} - -static inline ThreadCallStack * getThreadCallStack(); - -// Enables/disables logging every message. -extern "C" void InspectiveC_enableCompleteLogging() { - ThreadCallStack *cs = getThreadCallStack(); - cs->isCompleteLoggingEnabled = 1; -} - -extern "C" void InspectiveC_disableCompleteLogging() { - ThreadCallStack *cs = getThreadCallStack(); - cs->isCompleteLoggingEnabled = 0; -} - -// Semi Public API - used to temporarily disable logging. - -extern "C" void InspectiveC_enableLogging() { - ThreadCallStack *cs = getThreadCallStack(); - cs->isLoggingEnabled = 1; -} - -extern "C" void InspectiveC_disableLogging() { - ThreadCallStack *cs = getThreadCallStack(); - cs->isLoggingEnabled = 0; -} - -extern "C" int InspectiveC_isLoggingEnabled() { - ThreadCallStack *cs = getThreadCallStack(); - return (int)cs->isLoggingEnabled; -} - -// Shared functions. -extern "C" char ***_NSGetArgv(void); - -static FILE * newFileForThread() { - const char *exeName = **_NSGetArgv(); - if (exeName == NULL) { - exeName = "(NULL)"; - } else if (const char *slash = strrchr(exeName, '/')) { - exeName = slash + 1; - } - - pid_t pid = getpid(); - char path[MAX_PATH_LENGTH]; - - sprintf(path, "%s/InspectiveC", directory); - mkdir(path, 0755); - sprintf(path, "%s/InspectiveC/%s", directory, exeName); - mkdir(path, 0755); - - if (pthread_main_np()) { - sprintf(path, "%s/InspectiveC/%s/%d_main.log", directory, exeName, pid); - } else { - mach_port_t tid = pthread_mach_thread_np(pthread_self()); - sprintf(path, "%s/InspectiveC/%s/%d_t%u.log", directory, exeName, pid, tid); - } - return fopen(path, "a"); -} - -static inline ThreadCallStack * getThreadCallStack() { - ThreadCallStack *cs = (ThreadCallStack *)pthread_getspecific(threadKey); - if (cs == NULL) { - cs = (ThreadCallStack *)malloc(sizeof(ThreadCallStack)); -#ifdef MAIN_THREAD_ONLY - cs->file = (pthread_main_np()) ? newFileForThread() : NULL; -#else - cs->file = newFileForThread(); -#endif - cs->isLoggingEnabled = (cs->file != NULL); - cs->isCompleteLoggingEnabled = 0; - cs->spacesStr = (char *)malloc(DEFAULT_CALLSTACK_DEPTH + 1); - memset(cs->spacesStr, ' ', DEFAULT_CALLSTACK_DEPTH); - cs->spacesStr[DEFAULT_CALLSTACK_DEPTH] = '\0'; - cs->stack = (CallRecord *)calloc(DEFAULT_CALLSTACK_DEPTH, sizeof(CallRecord)); - cs->allocatedLength = DEFAULT_CALLSTACK_DEPTH; - cs->index = cs->lastPrintedIndex = cs->lastHitIndex = -1; - cs->numWatchHits = 0; - pthread_setspecific(threadKey, cs); - } - return cs; -} - -static void destroyThreadCallStack(void *ptr) { - ThreadCallStack *cs = (ThreadCallStack *)ptr; - if (cs->file) { - fclose(cs->file); - } - free(cs->spacesStr); - free(cs->stack); - free(cs); -} - -static inline void pushCallRecord(id obj, uintptr_t lr, SEL _cmd, ThreadCallStack *cs) { - int nextIndex = (++cs->index); - if (nextIndex >= cs->allocatedLength) { - cs->allocatedLength += CALLSTACK_DEPTH_INCREMENT; - cs->stack = (CallRecord *)realloc(cs->stack, cs->allocatedLength * sizeof(CallRecord)); - cs->spacesStr = (char *)realloc(cs->spacesStr, cs->allocatedLength + 1); - memset(cs->spacesStr, ' ', cs->allocatedLength); - cs->spacesStr[cs->allocatedLength] = '\0'; - } - CallRecord *newRecord = &cs->stack[nextIndex]; - newRecord->obj = obj; - newRecord->_cmd = _cmd; - newRecord->lr = lr; - newRecord->isWatchHit = 0; -} - -static inline CallRecord * popCallRecord(ThreadCallStack *cs) { - return &cs->stack[cs->index--]; -} - -static inline BOOL isKindOfClass(Class selfClass, Class clazz) { - for (Class candidate = selfClass; candidate; candidate = class_getSuperclass(candidate)) { - if (candidate == clazz) { - return YES; - } - } - return NO; -} - -static inline BOOL classSupportsArbitraryPointerTypes(Class clazz) { - return isKindOfClass(clazz, NSMapTable_Class) || isKindOfClass(clazz, NSHashTable_Class); -} - -static inline void log(FILE *file, id obj, SEL _cmd, char *spaces) { - Class kind = object_getClass(obj); - bool isMetaClass = class_isMetaClass(kind); - if (isMetaClass) { - fprintf(file, "%s%s+|%s %s|\n", spaces, spaces, class_getName(kind), sel_getName(_cmd)); - } else { - fprintf(file, "%s%s-|%s %s| @<%p>\n", spaces, spaces, class_getName(kind), sel_getName(_cmd), (void *)obj); - } -} - -static inline void logWithArgs(ThreadCallStack *cs, FILE *file, id obj, SEL _cmd, char *spaces, - arg_list &args, Class kind, BOOL isMetaClass, BOOL isWatchHit) { - Method method = (isMetaClass) ? class_getClassMethod(kind, _cmd) : class_getInstanceMethod(kind, _cmd); - if (method) { - const char *normalFormatStr; - const char *metaClassFormatStr; - - if (isWatchHit) { - normalFormatStr = "%s%s***-|%s@<%p> %s|"; - metaClassFormatStr = "%s%s***+|%s %s|"; - } else { - normalFormatStr = "%s%s-|%s@<%p> %s|"; - metaClassFormatStr = "%s%s+|%s %s|"; - } - - if (isMetaClass) { - fprintf(file, metaClassFormatStr, spaces, spaces, class_getName(kind), sel_getName(_cmd)); - } else { - fprintf(file, normalFormatStr, spaces, spaces, class_getName(kind), (void *)obj, sel_getName(_cmd)); - } - const char *typeEncoding = method_getTypeEncoding(method); - if (!typeEncoding || classSupportsArbitraryPointerTypes(kind)) { - fprintf(file, (isWatchHit) ? " ~NO ENCODING~***\n" : " ~NO ENCODING~\n"); - return; - } - - cs->isLoggingEnabled = 0; - @try { - NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:typeEncoding]; - const NSUInteger numberOfArguments = [signature numberOfArguments]; - for (NSUInteger index = 2; index < numberOfArguments; ++index) { - const char *type = [signature getArgumentTypeAtIndex:index]; - fprintf(file, " "); - if (!logArgument(file, type, args)) { // Can't understand arg - probably a struct. - fprintf(file, "~BAIL on \"%s\"~", type); - break; - } - } - } @catch(NSException *e) { - fprintf(file, "~BAD ENCODING~"); - } - fprintf(file, (isWatchHit) ? "***\n" : "\n"); - cs->isLoggingEnabled = 1; - } -} - -// Returns orig_objc_msgSend in r0. Sadly I couldn't figure out a way to "blx orig_objc_msgSend" -// and moving this directly inside the replacementObjc_msgSend method generates assembly that -// overrides r0 before can we push it... without this you're gonna have a bad time. -uintptr_t getOrigObjc_msgSend() { - return reinterpret_cast(orig_objc_msgSend); -} - -static inline void logWatchedHit(ThreadCallStack *cs, FILE *file, id obj, SEL _cmd, char *spaces, arg_list &args) { - Class kind = object_getClass(obj); - BOOL isMetaClass = class_isMetaClass(kind); - - logWithArgs(cs, file, obj, _cmd, spaces, args, kind, isMetaClass, YES); -} - -static inline void logObjectAndArgs(ThreadCallStack *cs, FILE *file, id obj, SEL _cmd, char *spaces, arg_list &args) { - - // Call [ class] to make sure the class is initialized. - Class kind = ((Class (*)(id, SEL))orig_objc_msgSend)(obj, class_SEL); - BOOL isMetaClass = (kind == obj); - - logWithArgs(cs, file, obj, _cmd, spaces, args, kind, isMetaClass, NO); -} - -static inline void onWatchHit(ThreadCallStack *cs, arg_list &args) { - const int hitIndex = cs->index; - CallRecord *hitRecord = &cs->stack[hitIndex]; - hitRecord->isWatchHit = 1; - hitRecord->prevHitIndex = cs->lastHitIndex; - cs->lastHitIndex = hitIndex; - ++cs->numWatchHits; - - FILE *logFile = cs->file; - if (logFile) { - - // Log previous calls if necessary. - for (int i = cs->lastPrintedIndex + 1; i < hitIndex; ++i) { - CallRecord record = cs->stack[i]; - - // Modify spacesStr. - char *spaces = cs->spacesStr; - spaces[i] = '\0'; - log(logFile, record.obj, record._cmd, spaces); - - // Clean up spacesStr. - spaces[i] = ' '; - } - - // Log the hit call. - char *spaces = cs->spacesStr; - spaces[hitIndex] = '\0'; - logWatchedHit(cs, logFile, hitRecord->obj, hitRecord->_cmd, spaces, args); - - // Clean up spacesStr. - spaces[hitIndex] = ' '; - - // Lastly, set the lastPrintedIndex. - cs->lastPrintedIndex = hitIndex; - } -} - -static inline void onNestedCall(ThreadCallStack *cs, arg_list &args) { - const int curIndex = cs->index; - FILE *logFile = cs->file; - if (logFile && - (cs->isCompleteLoggingEnabled || (curIndex - cs->lastHitIndex) <= maxRelativeRecursiveDepth)) { - - // Log the current call. - char *spaces = cs->spacesStr; - spaces[curIndex] = '\0'; - CallRecord curRecord = cs->stack[curIndex]; - logObjectAndArgs(cs, logFile, curRecord.obj, curRecord._cmd, spaces, args); - spaces[curIndex] = ' '; - - // Lastly, set the lastPrintedIndex. - cs->lastPrintedIndex = curIndex; - } -} - -static inline BOOL selectorSetContainsSelector(HashMapRef selectorSet, SEL _cmd) { - if (selectorSet == NULL) { - return NO; - } - return HMGet(selectorSet, WATCH_ALL_SELECTORS_SELECTOR) != NULL || - HMGet(selectorSet, _cmd) != NULL; -} - -static inline void preObjc_msgSend_common(id self, uintptr_t lr, SEL _cmd, ThreadCallStack *cs, arg_list &args) { -#ifdef MAIN_THREAD_ONLY - if (self && pthread_main_np() && cs->isLoggingEnabled) { -#else - if (self && cs->isLoggingEnabled) { -#endif - Class clazz = object_getClass(self); - RLOCK; - // Critical section - check for hits. - BOOL isWatchedObject = selectorSetContainsSelector((HashMapRef)HMGet(objectsMap, (void *)self), _cmd); - BOOL isWatchedClass = selectorSetContainsSelector((HashMapRef)HMGet(classMap, (void *)clazz), _cmd); - BOOL isWatchedSel = (HMGet(selsSet, (void *)_cmd) != NULL); - UNLOCK; - if (isWatchedObject && _cmd == @selector(dealloc)) { - WLOCK; - mapDestroySelectorSet(objectsMap, self); - UNLOCK; - } - if (isWatchedObject || isWatchedClass || isWatchedSel) { - onWatchHit(cs, args); - } else if (cs->numWatchHits > 0 || cs->isCompleteLoggingEnabled) { - onNestedCall(cs, args); - } - } -} - -// Called in our replacementObjc_msgSend after calling the original objc_msgSend. -// This returns the lr in r0/x0. -uintptr_t postObjc_msgSend() { - ThreadCallStack *cs = (ThreadCallStack *)pthread_getspecific(threadKey); - CallRecord *record = popCallRecord(cs); - if (record->isWatchHit) { - --cs->numWatchHits; - cs->lastHitIndex = record->prevHitIndex; - } - if (cs->lastPrintedIndex > cs->index) { - cs->lastPrintedIndex = cs->index; - } - return record->lr; -} - -// 32-bit vs 64-bit stuff. -#ifdef __arm64__ -#include "InspectiveCarm64.mm" -#else -#include "InspectiveCarm32.mm" -#endif - -MSInitialize { - pthread_key_create(&threadKey, &destroyThreadCallStack); - - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *path = [paths firstObject]; - directory = [path UTF8String]; - NSLog(@"[InspectiveC] Loading - Directory is \"%s\"", directory); - - NSMapTable_Class = [objc_getClass("NSMapTable") class]; - NSHashTable_Class = [objc_getClass("NSHashTable") class]; - - objectsMap = HMCreate(&pointerEquality, &pointerHash); - classMap = HMCreate(&pointerEquality, &pointerHash); - selsSet = HMCreate(&pointerEquality, &pointerHash); - - MSHookFunction(&objc_msgSend, (id (*)(id, SEL, ...))&replacementObjc_msgSend, &orig_objc_msgSend); -} diff --git a/ThirdPartyTools/InspectiveC/InspectiveCarm32.mm b/ThirdPartyTools/InspectiveC/InspectiveCarm32.mm deleted file mode 100644 index fec5eea..0000000 --- a/ThirdPartyTools/InspectiveC/InspectiveCarm32.mm +++ /dev/null @@ -1,53 +0,0 @@ - -// arm32 hooking magic. - -// Called in our replacementObjc_msgSend before calling the original objc_msgSend. -// This pushes a CallRecord to our stack, most importantly saving the lr. -// Returns orig_objc_msgSend. -uintptr_t preObjc_msgSend(id self, uintptr_t lr, SEL _cmd, va_list args) { - ThreadCallStack *cs = getThreadCallStack(); - pushCallRecord(self, lr, _cmd, cs); - - preObjc_msgSend_common(self, lr, _cmd, cs, args); - - return reinterpret_cast(orig_objc_msgSend); -} - -// Our replacement objc_msgSeng for arm32. -__attribute__((__naked__)) -static void replacementObjc_msgSend() { - __asm__ volatile ( - // Make sure it's enabled. - "push {r0-r3, lr}\n" - "blx _InspectiveC_isLoggingEnabled\n" - "mov r12, r0\n" - "pop {r0-r3, lr}\n" - "ands r12, r12\n" - "beq Lpassthrough\n" - // Call our preObjc_msgSend hook - returns orig_objc_msgSend. - // Swap the args around for our call to preObjc_msgSend. - "push {r0, r1, r2, r3}\n" - "mov r2, r1\n" - "mov r1, lr\n" - "add r3, sp, #8\n" - "blx __Z15preObjc_msgSendP11objc_objectmP13objc_selectorPv\n" - "mov r12, r0\n" - "pop {r0, r1, r2, r3}\n" - // Call through to the original objc_msgSend. - "blx r12\n" - // Call our postObjc_msgSend hook. - "push {r0-r3}\n" - "blx __Z16postObjc_msgSendv\n" - "mov lr, r0\n" - "pop {r0-r3}\n" - "bx lr\n" - // Pass through to original objc_msgSend. - "Lpassthrough:\n" - "push {r0, lr}\n" - "blx __Z19getOrigObjc_msgSendv\n" - "mov r12, r0\n" - "pop {r0, lr}\n" - "bx r12" - ); -} - diff --git a/ThirdPartyTools/InspectiveC/InspectiveCarm64.mm b/ThirdPartyTools/InspectiveC/InspectiveCarm64.mm deleted file mode 100644 index da6912e..0000000 --- a/ThirdPartyTools/InspectiveC/InspectiveCarm64.mm +++ /dev/null @@ -1,100 +0,0 @@ - -struct PointerAndInt_ { - uintptr_t ptr; - int i; -}; - -// arm64 hooking magic. - -// Called in our replacementObjc_msgSend before calling the original objc_msgSend. -// This pushes a CallRecord to our stack, most importantly saving the lr. -// Returns orig_objc_msgSend in x0 and isLoggingEnabled in x1. -struct PointerAndInt_ preObjc_msgSend(id self, uintptr_t lr, SEL _cmd, struct RegState_ *rs) { - ThreadCallStack *cs = getThreadCallStack(); - if (!cs->isLoggingEnabled) { // Not enabled, just return. - return (struct PointerAndInt_) {reinterpret_cast(orig_objc_msgSend), 0}; - } - pushCallRecord(self, lr, _cmd, cs); - pa_list args = (pa_list){ rs, ((unsigned char *)rs) + 208, 2, 0 }; // 208 is the offset of rs from the top of the stack. - - preObjc_msgSend_common(self, lr, _cmd, cs, args); - - return (struct PointerAndInt_) {reinterpret_cast(orig_objc_msgSend), 1}; -} - -// Our replacement objc_msgSend (arm64). -// -// See: -// https://blog.nelhage.com/2010/10/amd64-and-pa_arg/ -// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf -// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html -__attribute__((__naked__)) -static volatile void replacementObjc_msgSend() { - __asm__ volatile ( - // push {q0-q7} - "stp q6, q7, [sp, #-32]!\n" - "stp q4, q5, [sp, #-32]!\n" - "stp q2, q3, [sp, #-32]!\n" - "stp q0, q1, [sp, #-32]!\n" - // push {x0-x8, lr} - "stp x8, lr, [sp, #-16]!\n" - "stp x6, x7, [sp, #-16]!\n" - "stp x4, x5, [sp, #-16]!\n" - "stp x2, x3, [sp, #-16]!\n" - "stp x0, x1, [sp, #-16]!\n" - // Swap args around for call. - "mov x2, x1\n" - "mov x1, lr\n" - "mov x3, sp\n" - // Call preObjc_msgSend which puts orig_objc_msgSend into x0 and isLoggingEnabled into x1. - "bl __Z15preObjc_msgSendP11objc_objectmP13objc_selectorP9RegState_\n" - "mov x9, x0\n" - "mov x10, x1\n" - "tst x10, x10\n" // Set condition code for later branch. - // pop {x0-x8, lr} - "ldp x0, x1, [sp], #16\n" - "ldp x2, x3, [sp], #16\n" - "ldp x4, x5, [sp], #16\n" - "ldp x6, x7, [sp], #16\n" - "ldp x8, lr, [sp], #16\n" - // pop {q0-q7} - "ldp q0, q1, [sp], #32\n" - "ldp q2, q3, [sp], #32\n" - "ldp q4, q5, [sp], #32\n" - "ldp q6, q7, [sp], #32\n" - // Make sure it's enabled. - "b.eq Lpassthrough\n" - // Call through to the original objc_msgSend. - "blr x9\n" - // push {x0-x9} - "stp x0, x1, [sp, #-16]!\n" - "stp x2, x3, [sp, #-16]!\n" - "stp x4, x5, [sp, #-16]!\n" - "stp x6, x7, [sp, #-16]!\n" - "stp x8, x9, [sp, #-16]!\n" // Not sure if needed - push for alignment. - // push {q0-q7} - "stp q0, q1, [sp, #-32]!\n" - "stp q2, q3, [sp, #-32]!\n" - "stp q4, q5, [sp, #-32]!\n" - "stp q6, q7, [sp, #-32]!\n" - // Call our postObjc_msgSend hook. - "bl __Z16postObjc_msgSendv\n" - "mov lr, x0\n" - // pop {q0-q7} - "ldp q6, q7, [sp], #32\n" - "ldp q4, q5, [sp], #32\n" - "ldp q2, q3, [sp], #32\n" - "ldp q0, q1, [sp], #32\n" - // pop {x0-x9} - "ldp x8, x9, [sp], #16\n" - "ldp x6, x7, [sp], #16\n" - "ldp x4, x5, [sp], #16\n" - "ldp x2, x3, [sp], #16\n" - "ldp x0, x1, [sp], #16\n" - "ret\n" - - // Pass through to original objc_msgSend. - "Lpassthrough:\n" - "br x9" - ); -} diff --git a/ThirdPartyTools/InspectiveC/LICENSE.txt b/ThirdPartyTools/InspectiveC/LICENSE.txt deleted file mode 100644 index 9cecc1d..0000000 --- a/ThirdPartyTools/InspectiveC/LICENSE.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - {project} Copyright (C) {year} {fullname} - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/ThirdPartyTools/InspectiveC/Makefile b/ThirdPartyTools/InspectiveC/Makefile deleted file mode 100644 index f65c9fb..0000000 --- a/ThirdPartyTools/InspectiveC/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -ADDITIONAL_LDFLAGS = -Wl,-segalign,4000 -# ADDITIONAL_OBJCFLAGS += -S - -TWEAK_NAME = InspectiveC -InspectiveC_FILES = hashmap.mm logging.mm blocks.mm InspectiveC.mm -InspectiveC_LIBRARIES = substrate -InspectiveC_FRAMEWORKS = Foundation UIKit - -include $(THEOS)/makefiles/common.mk -include $(THEOS_MAKE_PATH)/tweak.mk -include $(THEOS_MAKE_PATH)/library.mk - -after-install:: - install.exec "killall -9 SpringBoard" diff --git a/ThirdPartyTools/InspectiveC/README.md b/ThirdPartyTools/InspectiveC/README.md deleted file mode 100644 index fbd7709..0000000 --- a/ThirdPartyTools/InspectiveC/README.md +++ /dev/null @@ -1,208 +0,0 @@ -[InspectiveC](https://github.com/DavidGoldman/InspectiveC) -====== - -*MobileSubstrate based objc_msgSend hook for debugging/inspection purposes.* - -Based on [itrace by emeau](https://github.com/emeau/itrace), [AspectiveC by saurik](http://svn.saurik.com/repos/menes/trunk/aspectivec/AspectiveC.mm), and [Subjective-C by kennytm](http://networkpx.blogspot.com/2009/09/introducing-subjective-c.html). - -Logs output to **/var/mobile/Documents/InspectiveC** or **/var/mobile/Containers/Data/Application/\/Documents/InspectiveC** (sandbox). Inside the InspectiveC folder, you'll find **\/\_\.log**. - -**You can download the deb from the stable_debs folder or from my [repo](http://apt.golddavid.com/).** - -**Description:** - -This is an inspection tool that you can use to log Objective-C message hierarchies. It can currently -watch specific objects, all objects of a given class, and specific selectors. It is indeed -compatible with arm64 - in fact, it is more full-featured on arm64 as arm32 has obj_msgSend[st|fp]ret -which are currently not hooked. - -**Features:** -* arm64 support (and arm32) -* Watch specific objects -* Watch instances of a specific class -* Watch specific selectors -* Prints arguments - -**Hopeful Features (in no particular order):** -* Support logging blocks/replaced C functions -* Print retvals -* Optimizations - * Nicer hooking (i.e. remove getOrigObjc_msgSend) - * Better multithreading performance - -**Example Output:** - -``` -***-|SpringBoard@<0x15455d320> _run|*** - +|NSAutoreleasePool alloc| - +|NSAutoreleasePool allocWithZone:| NULL - -|NSAutoreleasePool@<0x170442a00> init| - -|SpringBoard@<0x15455d320> _accessibilityInit| - -|SpringBoard@<0x15455d320> performSelector:withObject:afterDelay:| @selector(_accessibilitySetUpQuickSpeak) nil 1.5 - +|NSArray arrayWithObject:| @"kCFRunLoopDefaultMode" - -|SpringBoard@<0x15455d320> performSelector:withObject:afterDelay:inModes:| @selector(_accessibilitySetUpQuickSpeak) nil 1.5 <__NSArrayI@0x174233560> - -|SpringBoard@<0x15455d320> _updateAccessibilitySettingsLoader| - +|NSBundle mainBundle| - -|NSBundle@<0x17009f310> bundleIdentifier| - -|__NSCFString@<0x1740557b0> isEqualToString:| @"com.apple.PreBoard" - -|__NSStackBlock__@<0x16fdb7608> copy| - +|CFPrefsSearchListSource withSearchListForIdentifier:container:perform:| 0x19819f3b0 NULL <__NSStackBlock__@0x16fdb7570> - +|NSNumber class| - -|__NSCFBoolean@<0x194d4ab70> isKindOfClass:| [NSNumber class] - -|__NSCFBoolean@<0x194d4ab70> boolValue| - -|__NSCFBoolean@<0x194d4ab70> release| - -|SpringBoard@<0x15455d320> _updateApplicationAccessibility| - +|NSBundle mainBundle| - -|NSBundle@<0x17009f310> bundleIdentifier| - -|__NSCFString@<0x1740557b0> isEqualToString:| @"com.apple.PreBoard" - -|__NSStackBlock__@<0x16fdb75f8> copy| - +|CFPrefsSearchListSource withSearchListForIdentifier:container:perform:| 0x19819f3b0 NULL <__NSStackBlock__@0x16fdb7560> - +|NSNumber class| - -|__NSCFNumber@<0xb000000000000003> isKindOfClass:| [NSNumber class] - -|__NSCFNumber@<0xb000000000000003> boolValue| - -|__NSCFNumber@<0xb000000000000003> release| - -|SpringBoard@<0x15455d320> _updateLargeTextNotification|... -``` - -**Usage:** - -Properly [install theos](http://iphonedevwiki.net/index.php/Theos/Setup) and grab yourself a copy -of the iOS SDK. You may have to modify the Makefile (i.e. ARCHS or TARGET) and/or InspectiveC.mm. I -compile this on my Mac with Clang - if you use anything different you may have some issues with the -assembly code. - -When you install the deb, you will find **libinspectivec.dylib** in /usr/lib. Copy this dylib into -$THEOS/lib and then copy **InspectiveC.h** into $THEOS/include. - -**Option 0: Use InspectiveC with Cycript for maximum efficiency** - -Use Cycript to inject into a process, then paste a single line to load InspectiveC. The command is a -compiled version of the InspectiveC.cy file - found in this repo in cycript/InspectiveC.compiled.cy. - -Be sure to install **Cycript on Cydia** and replace "SpringBoard" in the first command with the name -of the process that you want to inject into. Also, don't forget to **respring/kill the app** when -you no longer want InspectiveC loaded. - -```c -// You can replace SpringBoard with whatever process name you want. -root# cycript -p SpringBoard - -cy# intFunc=new Type("v").functionWith(int);objFunc=new Type("v").functionWith(id);classFunc=new Type("v").functionWith(Class);selFunc=new Type("v").functionWith(SEL);voidFunc=new Type("v").functionWith(new Type("v"));objSelFunc=new Type("v").functionWith(id,SEL);classSelFunc=new Type("v").functionWith(Class,SEL);handle=dlopen("/usr/lib/libinspectivec.dylib",RTLD_NOW);setMaximumRelativeLoggingDepth=intFunc(dlsym(handle,"InspectiveC_setMaximumRelativeLoggingDepth"));watchObject=objFunc(dlsym(handle,"InspectiveC_watchObject"));unwatchObject=objFunc(dlsym(handle,"InspectiveC_unwatchObject"));watchSelectorOnObject=objSelFunc(dlsym(handle,"InspectiveC_watchSelectorOnObject"));unwatchSelectorOnObject=objSelFunc(dlsym(handle,"InspectiveC_unwatchSelectorOnObject"));watchClass=classFunc(dlsym(handle,"InspectiveC_watchInstancesOfClass"));unwatchClass=classFunc(dlsym(handle,"InspectiveC_unwatchInstancesOfClass"));watchSelectorOnClass=classSelFunc(dlsym(handle,"InspectiveC_watchSelectorOnInstancesOfClass"));unwatchSelectorOnClass=classSelFunc(dlsym(handle,"InspectiveC_unwatchSelectorOnInstancesOfClass"));watchSelector=selFunc(dlsym(handle,"InspectiveC_watchSelector"));unwatchSelector=selFunc(dlsym(handle,"InspectiveC_unwatchSelector"));enableLogging=voidFunc(dlsym(handle,"InspectiveC_enableLogging"));disableLogging=voidFunc(dlsym(handle,"InspectiveC_disableLogging"));enableCompleteLogging=voidFunc(dlsym(handle,"InspectiveC_enableCompleteLogging"));disableCompleteLogging=voidFunc(dlsym(handle,"InspectiveC_disableCompleteLogging")) - -// Now use your InspectiveC commands as if they were the ones in InspCWrapper. - -// Use this command to limit the recursion when logging. -cy# setMaximumRelativeLoggingDepth(5) - -cy# watchObject(choose(SBUIController)[0]) - -cy# unwatchObject(choose(SBUIController)[0]) - -cy# watchSelector(@selector(anySelectorYouWant)) - -cy# watchClass([AnyClassYouWant class]) -``` - -**Option 1: Use the InspectiveC Wrapper** - -Include **InspCWrapper.m** in your Tweak file. You should probably use a DEBUG guard. - -```c -#if INSPECTIVEC_DEBUG -#include "InspCWrapper.m" -#endif -``` - -Then use the following API: - -```c -// Set the maximum logging depth after a hit. -void setMaximumRelativeLoggingDepth(int depth); - - -// Watches/unwatches the specified object (all selectors). -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void watchObject(id obj); -void unwatchObject(id obj); - -// Watches/unwatches the specified selector on the object. -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void watchSelectorOnObject(id obj, SEL _cmd); -void unwatchSelectorOnObject(id obj, SEL _cmd); - - -// Watches/unwatches instances of the specified class ONLY - will not watch subclass instances. -void watchClass(Class clazz); -void unwatchClass(Class clazz); - -// Watches/unwatches the specified selector on instances of the specified class ONLY - will not -// watch subclass instances. -void watchSelectorOnClass(Class clazz, SEL _cmd); -void unwatchSelectorOnClass(Class clazz, SEL _cmd); - - -// Watches/unwatches the specified selector. -void watchSelector(SEL _cmd); -void unwatchSelector(SEL _cmd); - -// Enables/disables logging for the current thread. -void enableLogging(); -void disableLogging(); - -// Enables/disables logging every message for the current thread. -void enableCompleteLogging(); -void disableCompleteLogging(); -``` - - -**Option 2: Link directly against InspectiveC** - -Add the following line to your makefile: - -``` -_LIBRARIES = inspectivec -``` - -This will automatically load InspectiveC in your tweak (whatever process your tweak injects into). -Then include InspectiveC.h in your tweak and use those functions. - - -InspectiveC.h headlines the following API: -```c -// Set the maximum logging depth after a hit. -void InspectiveC_setMaximumRelativeLoggingDepth(int depth); - - -// Watches/unwatches the specified object (all selectors). -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void InspectiveC_watchObject(id obj); -void InspectiveC_unwatchObject(id obj); - -// Watches/unwatches the specified selector on the object. -// Objects will be automatically unwatched when they receive a -|dealloc| message. -void InspectiveC_watchSelectorOnObject(id obj, SEL _cmd); -void InspectiveC_unwatchSelectorOnObject(id obj, SEL _cmd); - - -// Watches/unwatches instances of the specified class ONLY - will not watch subclass instances. -void InspectiveC_watchInstancesOfClass(Class clazz); -void InspectiveC_unwatchInstancesOfClass(Class clazz); - -// Watches/unwatches the specified selector on instances of the specified class ONLY - will not -// watch subclass instances. -void InspectiveC_watchSelectorOnInstancesOfClass(Class clazz, SEL _cmd); -void InspectiveC_unwatchSelectorOnInstancesOfClass(Class clazz, SEL _cmd); - - -// Watches/unwatches the specified selector. -void InspectiveC_watchSelector(SEL _cmd); -void InspectiveC_unwatchSelector(SEL _cmd); - -// Enables/disables logging for the current thread. -void InspectiveC_enableLogging(); -void InspectiveC_disableLogging(); - -// Enables/disables logging every message for the current thread. -void InspectiveC_enableCompleteLogging(); -void InspectiveC_disableCompleteLogging(); -``` diff --git a/ThirdPartyTools/InspectiveC/blocks.h b/ThirdPartyTools/InspectiveC/blocks.h deleted file mode 100644 index fd1e25b..0000000 --- a/ThirdPartyTools/InspectiveC/blocks.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef BLOCKS_H -#define BLOCKS_H - -enum { - BLOCK_HAS_COPY_DISPOSE = (1 << 25), - BLOCK_HAS_CTOR = (1 << 26), // Helpers have C++ code. - BLOCK_IS_GLOBAL = (1 << 28), - BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE. - BLOCK_HAS_SIGNATURE = (1 << 30), -}; - -struct BlockLiteral_ { - void *isa; // Should be initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock. - int flags; - int reserved; - void (*invoke)(void *, ...); - struct BlockDescriptor_ { - unsigned long int reserved; // NULL. - unsigned long int size; // sizeof(struct BlockLiteral_). - // Optional helper functions. - void (*copy_helper)(void *dst, void *src); // IFF (1 << 25). - void (*dispose_helper)(void *src); // IFF (1 << 25). - const char *signature; // IFF (1 << 30). - } *descriptor; -}; - -void logBlock(FILE *file, id block); - -#endif diff --git a/ThirdPartyTools/InspectiveC/blocks.mm b/ThirdPartyTools/InspectiveC/blocks.mm deleted file mode 100644 index 6f030ad..0000000 --- a/ThirdPartyTools/InspectiveC/blocks.mm +++ /dev/null @@ -1,41 +0,0 @@ -#include "blocks.h" - -#include - -// Thanks to CTObjectiveCRuntimeAdditions (https://github.com/ebf/CTObjectiveCRuntimeAdditions). -// See http://clang.llvm.org/docs/Block-ABI-Apple.html. -void logBlock(FILE *file, id block) { - struct BlockLiteral_ *blockRef = (__bridge struct BlockLiteral_ *)block; - int flags = blockRef->flags; - - const char *signature = NULL; - - if (flags & BLOCK_HAS_SIGNATURE) { - unsigned char *signatureLocation = (unsigned char *)blockRef->descriptor; - signatureLocation += sizeof(unsigned long int); - signatureLocation += sizeof(unsigned long int); - - if (flags & BLOCK_HAS_COPY_DISPOSE) { - signatureLocation += sizeof(void (*)(void *, void *)); - signatureLocation += sizeof(void (*)(void *)); - } - - signature = (*(const char **)signatureLocation); - } - - if (signature) { - NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:signature]; - Class kind = object_getClass(block); - fprintf(file, "<%s@%p signature=\"%s ; retType=%s", class_getName(kind), (void *)block, signature, methodSignature.methodReturnType); - - // Skip the first argument (self). - NSUInteger numOfArgs = methodSignature.numberOfArguments; - for (NSUInteger i = 1; i < numOfArgs; ++i) { - fprintf(file, " %u=%s", (unsigned)i, [methodSignature getArgumentTypeAtIndex:i]); - } - fprintf(file, "\">"); - } else { - Class kind = object_getClass(block); - fprintf(file, "<%s@%p>", class_getName(kind), (void *)block); - } -} diff --git a/ThirdPartyTools/InspectiveC/control b/ThirdPartyTools/InspectiveC/control deleted file mode 100644 index 6f51b53..0000000 --- a/ThirdPartyTools/InspectiveC/control +++ /dev/null @@ -1,10 +0,0 @@ -Package: com.golddavid.inspectivec -Name: InspectiveC -Depends: mobilesubstrate (>= 0.9.5.000) -Version: 1.0.8 -Architecture: iphoneos-arm -Description: objc_msgSend hook for debugging/inspection purposes. -Depiction: http://apt.golddavid.com/depictions/InspectiveC.html -Maintainer: David Goldman -Author: David Goldman -Section: Development diff --git a/ThirdPartyTools/InspectiveC/hashmap.h b/ThirdPartyTools/InspectiveC/hashmap.h deleted file mode 100644 index 85342b2..0000000 --- a/ThirdPartyTools/InspectiveC/hashmap.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HASHMAP_H -#define HASHMAP_H - -#include -#import - -// Equality function used in hashmap to test for equality - returns nonzero if equal. -typedef int (*EqualityFuncT)(void *, void *); - -// Hashing function used to position items inside the HashMap. -typedef NSUInteger (*HashFuncT)(void *); - -// Destruction function used to release {key, value} entries inside the HashMap. -typedef void (*EntryDestructFuncT)(void *, void *); - -// HashBucket structure, used in the HashMap's table. -typedef struct HashBucket_ { - void *key; - void *value; - struct HashBucket_ *next; -} HashBucket; - -// HashMap structure, containing a table of HashBuckets, and the required functions. -typedef struct HashMap_ { - HashBucket **table; - size_t tableSize; - size_t size; - EqualityFuncT equalityFunction; - HashFuncT hashFunction; -} HashMap; -typedef HashMap * HashMapRef; - -// Creates a new int HashMap. -HashMapRef HMCreateIntHashMap(); - -// Creates a new string HashMap. -HashMapRef HMCreateStringHashMap(); - -// Creates a new HashMap. -HashMapRef HMCreate(EqualityFuncT ef, HashFuncT hf); - -// Creates a copy of the given HashMap. -HashMapRef HMCopy(HashMapRef ref); - -// Frees a HashMap without touching the keys and values. -void HMFree(HashMapRef hashMap); - -// Frees a HashMap after calling the EntryDestructFuncT on all entries in the HashMap. -void HMFreeWithEntryDestruct(HashMapRef hashMap, EntryDestructFuncT edf); - -// Inserts the given value into the HashMap, using key. Note that if key already exists in the -// HashMap, it will be updated to reference value instead. -// -// This function returns 1 if it succeeds; 0 otherwise. -int HMPut(HashMapRef hashMap, void *key, void *value); - -// Returns the object referenced by key, if any. -void * HMGet(HashMapRef hashMap, void *key); - -// Removes a key from the HashMap, returning the value removed, if any. Note that this may be called -// when iterating through buckets if and only if you only remove the current key being iterated. -void * HMRemove(HashMapRef hashMap, void *key); - -// Calls the function on all entries in the HashMap, in an arbitrary order. -void HMIterate(HashMapRef hashMap, void (*function)(void *, void *)); - -// Calls the function on all entries in the HashMap, in an arbitrary order. -void HMIterateWithArg(HashMapRef hashMap, void *arg, void (*functionWithExtraArg)(void *, void *, void *extraArg)); - -// Prints some HashMap stats. -void HMPrintStats(HashMapRef hashMap); - -#endif diff --git a/ThirdPartyTools/InspectiveC/hashmap.mm b/ThirdPartyTools/InspectiveC/hashmap.mm deleted file mode 100644 index 55515e7..0000000 --- a/ThirdPartyTools/InspectiveC/hashmap.mm +++ /dev/null @@ -1,295 +0,0 @@ -#include "hashmap.h" - -#include -#include -#include - -#define INITIAL_SIZE 16 -#define LOAD_FACTOR 0.75 - -#define TRUE 1 -#define FALSE 0 - -// Dummy destruct function used for freeing the map with a call to HMFree. -static void hm_dummy_entry_destruct(void *key, void *value) { } - -// Returns the given table index for a given key. -static inline NSUInteger hm_index_for_key(HashMapRef hashMap, void *key) { - return hashMap->hashFunction(key) % hashMap->tableSize; -} - -// Inserts the given bucket into the HashMap in constant time. -static inline void hm_insert(HashMapRef hashMap, HashBucket *bucket) { - NSUInteger index = hm_index_for_key(hashMap, bucket->key); - bucket->next = hashMap->table[index]; - hashMap->table[index] = bucket; -} - -// Returns the bucket (or NULL) for the given key. Expected constant time behavior, but has a worst -// case of O(n). -static inline HashBucket * hm_get_bucket(HashMapRef hashMap, void *key) { - HashBucket *bucket = hashMap->table[hm_index_for_key(hashMap, key)]; - while (bucket) { - if (hashMap->equalityFunction(key, bucket->key)) { - return bucket; - } - bucket = bucket->next; - } - return NULL; -} - -// Removes the bucket for the given key if it exists. Expected constant time behavior, but has a -// worst case of O(n). -static inline HashBucket * hm_remove_bucket(HashMapRef hashMap, void *key) { - NSUInteger index = hm_index_for_key(hashMap, key); - HashBucket *prev = NULL; - HashBucket *cur = hashMap->table[index]; - - while (cur) { - if (hashMap->equalityFunction(key, cur->key)) { - if (prev == NULL) { - hashMap->table[index] = cur->next; - } else { - prev->next = cur->next; - } - return cur; - } - prev = cur; - cur = cur->next; - } - return NULL; -} - -// Resizes the given HashMap by a factor of 2. Returns 1 if it succeeds. -static inline int hm_resize(HashMapRef hashMap) { - size_t oldTableSize = hashMap->tableSize; - size_t newTableSize = 2 * oldTableSize; - HashBucket **oldTable = hashMap->table; - HashBucket **newTable = (HashBucket **)calloc(newTableSize, sizeof(HashBucket *)); - if (!newTable) { - return FALSE; - } - hashMap->tableSize = newTableSize; - hashMap->table = newTable; - - for (size_t index = 0; index < oldTableSize; ++index) { - HashBucket *bucket = oldTable[index]; - - while (bucket) { - HashBucket *nextBucket = bucket->next; - hm_insert(hashMap, bucket); - bucket = nextBucket; - } - } - free(oldTable); - return TRUE; -} - -// Resizes the given HashMap if necessary (judged by the size of the HashMap and LOAD_FACTOR). -// Returns 1 if the HashMap does not need to be resized after adding 1 more item. -static inline int hm_resize_check(HashMapRef hashMap) { - if (hashMap->size + 1 > hashMap->tableSize * LOAD_FACTOR) { - return hm_resize(hashMap); - } - return TRUE; -} - -// V is actually a signed int *. -// Robert Jenkins' 32 bit integer hash function. -static NSUInteger intHash(void *v) { - unsigned a = *(unsigned *)v; - a = (a + 0x7ed55d16) + (a<<12); - a = (a ^ 0xc761c23c) ^ (a>>19); - a = (a + 0x165667b1) + (a<<5); - a = (a + 0xd3a2646c) ^ (a<<9); - a = (a + 0xfd7046c5) + (a<<3); - a = (a ^ 0xb55a4f09) ^ (a>>16); - return a; -} - -// Tests int pointers for equality. -static int intEquality(void *va, void *vb) { - int a = *(int *)va; - int b = *(int *)vb; - return a == b; -} - -// Creates a new int HashMap. -HashMapRef HMCreateIntHashMap() { - return HMCreate(&intEquality, &intHash); -} - -// Tests two strings for equality. -static int strEquality(void *va, void *vb) { - return strcmp((char *)va, (char *)vb) == 0; -} - -// Jenkins's one-at-a-time string hash function, as used in Perl. -// See http://en.wikipedia.org/wiki/Jenkins_hash_function -static NSUInteger strHash(void *voidStr) { - char *str = (char *)voidStr; - size_t len = strlen(str); - NSUInteger hash, i; - for(hash = i = 0; i < len; ++i) { - hash += str[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; -} - -// Creates a new string HashMap. -HashMapRef HMCreateStringHashMap() { - return HMCreate(&strEquality, &strHash); -} - -// Creates a new HashMap. -HashMapRef HMCreate(EqualityFuncT ef, HashFuncT hf) { - HashMapRef hashMap = (HashMapRef)malloc(sizeof(HashMap)); - if (hashMap) { // Make sure malloc worked - HashBucket **table = (HashBucket **)calloc(INITIAL_SIZE, sizeof(HashBucket *)); - if (!table) { // Check for alloc failure. - free(hashMap); - return NULL; - } - hashMap->tableSize = INITIAL_SIZE; - hashMap->size = 0; - hashMap->table = table; - hashMap->equalityFunction = ef; - hashMap->hashFunction = hf; - } - return hashMap; -} - -static void hm_insert_entry(void *key, void *val, void *map) { - HashMapRef hashMap = (HashMapRef)map; - HMPut(hashMap, key, val); -} - -// Creates a copy of the given HashMap. -HashMapRef HMCopy(HashMapRef ref) { - HashMapRef hashMap = HMCreate(ref->equalityFunction, ref->hashFunction); - if (hashMap) { - HMIterateWithArg(ref, hashMap, &hm_insert_entry); - } - return hashMap; -} - -// Inserts the given value into the HashMap, using key. Note that if key already exists in the -// HashMap, it will be updated to reference value instead. -// -// This function returns 1 if it succeeds; 0 otherwise. -int HMPut(HashMapRef hashMap, void *key, void *value) { - HashBucket *bucket = hm_get_bucket(hashMap, key); - if (bucket) { // Already exists in map. - bucket->value = value; - return TRUE; - } else { // Add into map. - HashBucket *bucket = (HashBucket *)malloc(sizeof(HashBucket)); - if (hm_resize_check(hashMap) && bucket) { - bucket->key = key; - bucket->value = value; - hm_insert(hashMap, bucket); - ++hashMap->size; - return TRUE; - } else { - free(bucket); - return FALSE; - } - } -} - -// Returns the object referenced by key, if any. -void * HMGet(HashMapRef hashMap, void *key) { - HashBucket *bucket = hm_get_bucket(hashMap, key); - return (bucket) ? bucket->value : NULL; -} - -// Removes a key from the HashMap, returning the value removed, if any. Note that this may be called -// when iterating through buckets if and only if you only remove the current key being iterated. -void * HMRemove(HashMapRef hashMap, void *key) { - HashBucket *bucket = hm_remove_bucket(hashMap, key); - if (bucket) { - void *retVal = bucket->value; - --hashMap->size; - free(bucket); - return retVal; - } else { - return NULL; - } -} - -// Calls the function on all entries in the HashMap, in an arbitrary order. -void HMIterate(HashMapRef hashMap, void (*function)(void *, void *)) { - for (size_t index = 0; index < hashMap->tableSize; ++index) { - HashBucket *bucket = hashMap->table[index]; - while (bucket) { - HashBucket *nextBucket = bucket->next; - function(bucket->key, bucket->value); - bucket = nextBucket; - } - } -} - -// Calls the function on all entries in the HashMap, in an arbitrary order. -void HMIterateWithArg(HashMapRef hashMap, void *arg, void (*functionWithExtraArg)(void *, void *, void *extraArg)) { - for (size_t index = 0; index < hashMap->tableSize; ++index) { - HashBucket *bucket = hashMap->table[index]; - while (bucket) { - HashBucket *nextBucket = bucket->next; - functionWithExtraArg(bucket->key, bucket->value, arg); - bucket = nextBucket; - } - } -} - -// Frees a HashMap after calling the EntryDestructFuncT on all entries in the HashMap. -void HMFreeWithEntryDestruct(HashMapRef hashMap, EntryDestructFuncT entryDestruct) { - for (size_t index = 0; index < hashMap->tableSize; ++index) { - HashBucket *bucket = hashMap->table[index]; - while (bucket) { - HashBucket *nextBucket = bucket->next; - entryDestruct(bucket->key, bucket->value); - free(bucket); - bucket = nextBucket; - } - } - free(hashMap->table); - free(hashMap); -} - -// Frees a HashMap without touching the keys and values. -void HMFree(HashMapRef hashMap) { - HMFreeWithEntryDestruct(hashMap, &hm_dummy_entry_destruct); -} - -// Prints some HashMap stats. -void HMPrintStats(HashMapRef hashMap) { - printf("HashMap <%p>, size=%u\n", (void *)hashMap, (unsigned)hashMap->size); - printf("\tTableSize: %u\n", (unsigned)hashMap->tableSize); - - unsigned sumBucketLengths = 0; - unsigned numNonZeroBuckets = 0; - - for (size_t index = 0; index < hashMap->tableSize; ++index) { - unsigned bucketLength = 0; - - HashBucket *bucket = hashMap->table[index]; - while (bucket) { - HashBucket *nextBucket = bucket->next; - ++bucketLength; - bucket = nextBucket; - } - - if (bucketLength) { - sumBucketLengths += bucketLength; - ++numNonZeroBuckets; - } - } - - printf("\tNon Zero Buckets: %u\n", numNonZeroBuckets); - printf("\tAverage Non Zero Size: %u\n", (sumBucketLengths / numNonZeroBuckets)); -} diff --git a/ThirdPartyTools/InspectiveC/logging.h b/ThirdPartyTools/InspectiveC/logging.h deleted file mode 100644 index 2273029..0000000 --- a/ThirdPartyTools/InspectiveC/logging.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef LOGGING_H -#define LOGGING_H - -#import -#include - -#ifdef __arm64__ -#define arg_list pa_list -#define int_up_cast(t) t -#define uint_up_cast(t) t -#include "ARM64Types.h" -#else -#define arg_list va_list -#define int_up_cast(t) int -#define uint_up_cast(t) unsigned int -#define pa_arg(args, type) va_arg(args, type) -#define pa_float(args) float_from_va_list(args) -#define pa_double(args) va_arg(args, double) - -#define pa_two_ints(args, varType, varName, intType) \ - varType varName = va_arg(args, varType); \ - -#define pa_two_doubles(args, t, varName) \ - t varName = va_arg(args, t); \ - -#define pa_four_doubles(args, t, varName) \ - t varName = va_arg(args, t); \ - -#endif - -void logObject(FILE *file, id obj); - -bool logArgument(FILE *file, const char *type, arg_list &args); - -#endif diff --git a/ThirdPartyTools/InspectiveC/logging.mm b/ThirdPartyTools/InspectiveC/logging.mm deleted file mode 100644 index 8237e8c..0000000 --- a/ThirdPartyTools/InspectiveC/logging.mm +++ /dev/null @@ -1,201 +0,0 @@ -#include "logging.h" - -#include - -#include "blocks.h" - -static Class NSString_Class = objc_getClass("NSString"); -static Class NSBlock_Class = objc_getClass("NSBlock"); - -static inline void logNSStringForStruct(FILE *file, NSString *str) { - fprintf(file, "%s", [str UTF8String]); -} - -static inline void logNSString(FILE *file, NSString *str) { - fprintf(file, "@\"%s\"", [str UTF8String]); -} - -static inline BOOL isKindOfClass(Class selfClass, Class clazz) { - for (Class candidate = selfClass; candidate; candidate = class_getSuperclass(candidate)) { - if (candidate == clazz) { - return YES; - } - } - return NO; -} - -void logObject(FILE *file, id obj) { - if (obj == nil) { - fprintf(file, "nil"); - return; - } - Class kind = object_getClass(obj); - if (class_isMetaClass(kind)) { - fprintf(file, "[%s class]", class_getName(obj)); - return; - } - if (isKindOfClass(kind, NSString_Class)) { - logNSString(file, obj); - return; - } - if (isKindOfClass(kind, NSBlock_Class)) { - logBlock(file, obj); - return; - } - fprintf(file, "<%s@%p>", class_getName(kind), reinterpret_cast(obj)); -} - -#ifndef __arm64__ -static float float_from_va_list(va_list &args) { - union { - uint32_t i; - float f; - } value = {va_arg(args, uint32_t)}; - return value.f; -} -#endif - -// Heavily based/taken from AspectiveC by saurik. -// @see http://svn.saurik.com/repos/menes/trunk/aspectivec/AspectiveC.mm -// @see https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html -bool logArgument(FILE *file, const char *type, arg_list &args) { - loop: - switch(*type) { - case '#': // A class object (Class). - case '@': { // An object (whether statically typed or typed id). - id value = pa_arg(args, id); - logObject(file, value); - } break; - case ':': { // A method selector (SEL). - SEL value = pa_arg(args, SEL); - if (value == NULL) { - fprintf(file, "NULL"); - } else { - fprintf(file, "@selector(%s)", sel_getName(value)); - } - } break; - case '*': { // A character string (char *). - const char *value = pa_arg(args, const char *); - fprintf(file, "\"%s\"", value); - } break; - case '^': { // A pointer to type (^type). - void *value = pa_arg(args, void *); - if (value == NULL) { - fprintf(file, "NULL"); - } else { - fprintf(file, "%p", value); - } - } break; - case 'B': { // A C++ bool or a C99 _Bool. - bool value = pa_arg(args, int_up_cast(bool)); - fprintf(file, "%s", value ? "true" : "false"); - } break; - case 'c': { // A char. - signed char value = pa_arg(args, int_up_cast(char)); - fprintf(file, "%d", value); - } break; - case 'C': { // An unsigned char. - unsigned char value = pa_arg(args, uint_up_cast(unsigned char)); - fprintf(file, "%d", value); - } break; - case 's': { // A short. - short value = pa_arg(args, int_up_cast(short)); - fprintf(file, "%d", value); - } break; - case 'S': { // An unsigned short. - unsigned short value = pa_arg(args, uint_up_cast(unsigned short)); - fprintf(file, "%u", value); - } break; - case 'i': { // An int. - int value = pa_arg(args, int); - if (value == INT_MAX) { - fprintf(file, "INT_MAX"); - } else { - fprintf(file, "%d", value); - } - } break; - case 'I': { // An unsigned int. - unsigned int value = pa_arg(args, unsigned int); - fprintf(file, "%u", value); - } break; -#ifdef __arm64__ - case 'l': { // A long - treated as a 32-bit quantity on 64-bit programs. - int value = pa_arg(args, int); - fprintf(file, "%d", value); - } break; - case 'L': { // An unsigned long - treated as a 32-bit quantity on 64-bit programs. - unsigned int value = pa_arg(args, unsigned int); - fprintf(file, "%u", value); - } break; -#else - case 'l': { // A long. - long value = pa_arg(args, long); - fprintf(file, "%ld", value); - } break; - case 'L': { // An unsigned long. - unsigned long value = pa_arg(args, unsigned long); - fprintf(file, "%lu", value); - } break; -#endif - case 'q': { // A long long. - long long value = pa_arg(args, long long); - fprintf(file, "%lld", value); - } break; - case 'Q': { // An unsigned long long. - unsigned long long value = pa_arg(args, unsigned long long); - fprintf(file, "%llu", value); - } break; - case 'f': { // A float. - float value = pa_float(args); - fprintf(file, "%g", value); - } break; - case 'd': { // A double. - double value = pa_double(args); - fprintf(file, "%g", value); - } break; - case '{': { // A struct. We check for some common structs. - if (strncmp(type, "{CGAffineTransform=", 19) == 0) { -#ifdef __arm64__ - CGAffineTransform *ptr = (CGAffineTransform *)pa_arg(args, void *); - logNSStringForStruct(file, NSStringFromCGAffineTransform(*ptr)); -#else - CGAffineTransform at = va_arg(args, CGAffineTransform); - logNSStringForStruct(file, NSStringFromCGAffineTransform(at)); -#endif - } else if (strncmp(type, "{CGPoint=", 9) == 0) { - pa_two_doubles(args, CGPoint, point) - logNSStringForStruct(file, NSStringFromCGPoint(point)); - } else if (strncmp(type, "{CGRect=", 8) == 0) { - pa_four_doubles(args, UIEdgeInsets, insets) - CGRect rect = CGRectMake(insets.top, insets.left, insets.bottom, insets.right); - logNSStringForStruct(file, NSStringFromCGRect(rect)); - } else if (strncmp(type, "{CGSize=", 8) == 0) { - pa_two_doubles(args, CGSize, size) - logNSStringForStruct(file, NSStringFromCGSize(size)); - } else if (strncmp(type, "{UIEdgeInsets=", 14) == 0) { - pa_four_doubles(args, UIEdgeInsets, insets) - logNSStringForStruct(file, NSStringFromUIEdgeInsets(insets)); - } else if (strncmp(type, "{UIOffset=", 10) == 0) { - pa_two_doubles(args, UIOffset, offset) - logNSStringForStruct(file, NSStringFromUIOffset(offset)); - } else if (strncmp(type, "{_NSRange=", 10) == 0) { - pa_two_ints(args, NSRange, range, unsigned long); - logNSStringForStruct(file, NSStringFromRange(range)); - } else { // Nope. - return false; - } - } break; - case 'N': // inout. - case 'n': // in. - case 'O': // bycopy. - case 'o': // out. - case 'R': // byref. - case 'r': // const. - case 'V': // oneway. - ++type; - goto loop; - default: - return false; - } - return true; -} diff --git a/ThirdPartyTools/InspectiveC/obj b/ThirdPartyTools/InspectiveC/obj deleted file mode 120000 index 27c3ca0..0000000 --- a/ThirdPartyTools/InspectiveC/obj +++ /dev/null @@ -1 +0,0 @@ -.theos/obj \ No newline at end of file diff --git a/ThirdPartyTools/README.md b/ThirdPartyTools/README.md index 525d4fa..18b2a3b 100644 --- a/ThirdPartyTools/README.md +++ b/ThirdPartyTools/README.md @@ -1,4 +1,4 @@ -#ThirdParty Tools. +# ThirdParty Tools. >As the saying goes. "Don't fix shit that ain't broken" This folder contains third party tools that will be automatically compiled and binded inside the result Mach-O. @@ -7,10 +7,10 @@ This folder contains third party tools that will be automatically compiled and b Folder Name Is The Universal Identifier (This Also Works For Other Modules).So please make sure >>FolderName==ProjectNameInMakeFile==Suffix Of Build dylib(That's the ProjectName in MakeFile) -##Warn +## Warn **ALL PROJECT NAMES MUST HAVE LENGTH SMALLER THAN 16** >This is only for stuff that are nearly impossible to transfer into a pass of main project. >For example. InspectiveC contains hacks within objc_msgSend that the main project heavily depends on. >Therefor, it comes as a seperate Tool -#DON'T CALL MAIN PROJECT STUFF WITHIN PROJECTS HERE +# DON'T CALL MAIN PROJECT STUFF WITHIN PROJECTS HERE diff --git a/capstone b/capstone index e22577e..85f4b8f 160000 --- a/capstone +++ b/capstone @@ -1 +1 @@ -Subproject commit e22577e42dd956b40897b7d1ebe77979ef70160c +Subproject commit 85f4b8f7d9314bb73c06367ff83c3b46c3ea9433