From 286806b3ca5653a3c628cad32577de8cfd5add75 Mon Sep 17 00:00:00 2001 From: Naville <403799106@qq.com> Date: Sat, 12 Mar 2016 11:56:40 +0000 Subject: [PATCH] ObjCRuntime --- Hooks/API/ObjCRuntime.xm | 64 +++++++++++++++++++++++ Hooks/API/dlfcn.xm | 6 --- Hooks/ThirdPartyTools/DeviceIDFake.xm | 47 +++++++++++++++++ Hooks/ThirdPartyTools/InspectiveC.xm | 47 +++++++++++++++++ Hooks/ThirdPartyTools/RuntimeClassDump.xm | 47 +++++++++++++++++ Hooks/ThirdPartyTools/dumpdecrypted.xm | 47 +++++++++++++++++ Hooks/Utils/WebShell.m | 22 ++++++++ ThirdPartyTools/DeviceIDFake/obj | 1 + ThirdPartyTools/InspectiveC/obj | 1 + ThirdPartyTools/RuntimeClassDump/obj | 1 + ThirdPartyTools/dumpdecrypted/obj | 1 + VERSION | 2 +- build.py | 56 ++++++++++++-------- 13 files changed, 313 insertions(+), 29 deletions(-) create mode 100644 Hooks/API/ObjCRuntime.xm create mode 100644 Hooks/ThirdPartyTools/DeviceIDFake.xm create mode 100644 Hooks/ThirdPartyTools/InspectiveC.xm create mode 100644 Hooks/ThirdPartyTools/RuntimeClassDump.xm create mode 100644 Hooks/ThirdPartyTools/dumpdecrypted.xm create mode 120000 ThirdPartyTools/DeviceIDFake/obj create mode 120000 ThirdPartyTools/InspectiveC/obj create mode 120000 ThirdPartyTools/RuntimeClassDump/obj create mode 120000 ThirdPartyTools/dumpdecrypted/obj diff --git a/Hooks/API/ObjCRuntime.xm b/Hooks/API/ObjCRuntime.xm new file mode 100644 index 0000000..eddc536 --- /dev/null +++ b/Hooks/API/ObjCRuntime.xm @@ -0,0 +1,64 @@ +#import "../SharedDefine.pch" +#import +#import + +/* +FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector); +FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName); +*/ +//Old Func Pointers +Class (*old_NSClassFromString)(NSString *aClassName); +NSString* (*old_NSStringFromClass)(Class aClass); +NSString* (*old_NSStringFromProtocol)(Protocol* proto); +Protocol* (*old_NSProtocolFromString)(NSString* namestr); + + +//New Func +Class new_NSClassFromString(NSString* aClassName){ + if(WTShouldLog){ + WTInit(@"ObjCRuntime",@"NSClassFromString"); + WTAdd(aClassName,@"ClassName"); + WTSave; + WTRelease; + } + return old_NSClassFromString(aClassName); +} +NSString* new_NSStringFromClass(Class aClass){ + NSString* orig=old_NSStringFromClass(aClass); + if(WTShouldLog){ + WTInit(@"ObjCRuntime",@"NSStringFromClass"); + WTAdd(orig,@"ClassName"); + WTSave; + WTRelease; + } + return orig; +} + +NSString* new_NSStringFromProtocol(Protocol* proto){ + NSString* orig=old_NSStringFromProtocol(proto); + if(WTShouldLog){ + WTInit(@"ObjCRuntime",@"NSStringFromProtocol"); + WTAdd(orig,@"ProtocalName"); + WTSave; + WTRelease; + } + return orig; +} + +Protocol* new_NSProtocolFromString(NSString* namestr){ + if(WTShouldLog){ + WTInit(@"ObjCRuntime",@"NSProtocolFromString"); + WTAdd(namestr,@"ProtocalName"); + WTSave; + WTRelease; + } + return old_NSProtocolFromString(namestr); +} + +extern void init_ObjCRuntime_hook() { + MSHookFunction((void*)NSClassFromString,(void*)new_NSClassFromString, (void**)&old_NSClassFromString); + MSHookFunction((void*)NSStringFromClass,(void*)new_NSStringFromClass, (void**)&old_NSStringFromClass); + MSHookFunction((void*)NSStringFromProtocol,(void*)new_NSStringFromProtocol, (void**)&old_NSStringFromProtocol); + MSHookFunction((void*)NSProtocolFromString,(void*)new_NSProtocolFromString, (void**)&old_NSProtocolFromString); + +} diff --git a/Hooks/API/dlfcn.xm b/Hooks/API/dlfcn.xm index 15ad4cd..26ed80b 100644 --- a/Hooks/API/dlfcn.xm +++ b/Hooks/API/dlfcn.xm @@ -1,8 +1,5 @@ #import "../SharedDefine.pch" #import - -#ifdef PROTOTYPE -//Pointless. Rarely Used By Apps And Called Too Much By System.Producing Tons Of Useless Message int (*old_dladdr)(const void *, Dl_info *); int new_dladdr(const void * addr, Dl_info * info){ int ret = old_dladdr(addr, info); @@ -15,7 +12,6 @@ int new_dladdr(const void * addr, Dl_info * info){ } return ret; } -#endif void * (*old_dlopen)(const char * __path, int __mode); @@ -45,9 +41,7 @@ void * new_dlopen(const char * __path, int __mode) { extern void init_dlfcn_hook() { -#ifdef PROTOTYPE MSHookFunction((void*)dladdr,(void*)new_dladdr, (void**)&old_dladdr); -#endif MSHookFunction((void*)dlsym,(void*)new_dlsym, (void**)&old_dlsym); MSHookFunction((void*)dlopen,(void*)new_dlopen, (void**)&old_dlopen); } diff --git a/Hooks/ThirdPartyTools/DeviceIDFake.xm b/Hooks/ThirdPartyTools/DeviceIDFake.xm new file mode 100644 index 0000000..5af3081 --- /dev/null +++ b/Hooks/ThirdPartyTools/DeviceIDFake.xm @@ -0,0 +1,47 @@ +//Shall We Use Marcos instead of this shit? +#import "../SharedDefine.pch" +#import +#import +extern NSString* RandomString(); +extern void init_DeviceIDFake_hook(){ +#ifdef PROTOTYPE +//Because We Ain't Ready Yet. No Test + for(int i=0;i<_dyld_image_count();i++){ + const char * Nam=_dyld_get_image_name(i); + NSString* curName=[[NSString stringWithUTF8String:Nam] autorelease]; + if([curName containsString:WTFJHTWEAKNAME]){ + intptr_t ASLROffset=_dyld_get_image_vmaddr_slide(i); + //We Found Ourself +#ifndef _____LP64_____ + uint32_t size=0; + const struct mach_header* selfHeader=(const struct mach_header*)_dyld_get_image_header(i); + char * data=getsectdatafromheader(selfHeader,"WTFJH","DeviceIDFake",&size); + +#elif + uint64_t size=0; + const struct mach_header_64* selfHeader=(const struct mach_header_64*)_dyld_get_image_header(i); + char * data=getsectdatafromheader_64(selfHeader,"WTFJH","DeviceIDFake",&size); +#endif + data=ASLROffset+data;//Add ASLR Offset To Pointer And Fix Address + NSData* SDData=[NSData dataWithBytes:data length:size]; + NSString* randomPath=[NSString stringWithFormat:@"%@/Documents/%@",NSHomeDirectory(),RandomString()]; + [SDData writeToFile:randomPath atomically:YES]; + dlopen(randomPath.UTF8String,RTLD_NOW); + //Inform Our Logger + CallTracer *tracer = [[CallTracer alloc] initWithClass:@"WTFJH" andMethod:@"LoadThirdPartyTools"]; + [tracer addArgFromPlistObject:@"dlopen" withKey:@"Type"]; + [tracer addArgFromPlistObject:randomPath withKey:@"Path"]; + [tracer addArgFromPlistObject:@"DeviceIDFake" withKey:@"ModuleName"]; + [traceStorage saveTracedCall: tracer]; + [tracer release]; + //End + + [SDData release]; + break; + } + + + + } +#endif +} diff --git a/Hooks/ThirdPartyTools/InspectiveC.xm b/Hooks/ThirdPartyTools/InspectiveC.xm new file mode 100644 index 0000000..4cc1c3f --- /dev/null +++ b/Hooks/ThirdPartyTools/InspectiveC.xm @@ -0,0 +1,47 @@ +//Shall We Use Marcos instead of this shit? +#import "../SharedDefine.pch" +#import +#import +extern NSString* RandomString(); +extern void init_InspectiveC_hook(){ +#ifdef PROTOTYPE +//Because We Ain't Ready Yet. No Test + for(int i=0;i<_dyld_image_count();i++){ + const char * Nam=_dyld_get_image_name(i); + NSString* curName=[[NSString stringWithUTF8String:Nam] autorelease]; + if([curName containsString:WTFJHTWEAKNAME]){ + intptr_t ASLROffset=_dyld_get_image_vmaddr_slide(i); + //We Found Ourself +#ifndef _____LP64_____ + uint32_t size=0; + const struct mach_header* selfHeader=(const struct mach_header*)_dyld_get_image_header(i); + char * data=getsectdatafromheader(selfHeader,"WTFJH","InspectiveC",&size); + +#elif + uint64_t size=0; + const struct mach_header_64* selfHeader=(const struct mach_header_64*)_dyld_get_image_header(i); + char * data=getsectdatafromheader_64(selfHeader,"WTFJH","InspectiveC",&size); +#endif + data=ASLROffset+data;//Add ASLR Offset To Pointer And Fix Address + NSData* SDData=[NSData dataWithBytes:data length:size]; + NSString* randomPath=[NSString stringWithFormat:@"%@/Documents/%@",NSHomeDirectory(),RandomString()]; + [SDData writeToFile:randomPath atomically:YES]; + dlopen(randomPath.UTF8String,RTLD_NOW); + //Inform Our Logger + CallTracer *tracer = [[CallTracer alloc] initWithClass:@"WTFJH" andMethod:@"LoadThirdPartyTools"]; + [tracer addArgFromPlistObject:@"dlopen" withKey:@"Type"]; + [tracer addArgFromPlistObject:randomPath withKey:@"Path"]; + [tracer addArgFromPlistObject:@"InspectiveC" withKey:@"ModuleName"]; + [traceStorage saveTracedCall: tracer]; + [tracer release]; + //End + + [SDData release]; + break; + } + + + + } +#endif +} diff --git a/Hooks/ThirdPartyTools/RuntimeClassDump.xm b/Hooks/ThirdPartyTools/RuntimeClassDump.xm new file mode 100644 index 0000000..72a1b65 --- /dev/null +++ b/Hooks/ThirdPartyTools/RuntimeClassDump.xm @@ -0,0 +1,47 @@ +//Shall We Use Marcos instead of this shit? +#import "../SharedDefine.pch" +#import +#import +extern NSString* RandomString(); +extern void init_RuntimeClassDump_hook(){ +#ifdef PROTOTYPE +//Because We Ain't Ready Yet. No Test + for(int i=0;i<_dyld_image_count();i++){ + const char * Nam=_dyld_get_image_name(i); + NSString* curName=[[NSString stringWithUTF8String:Nam] autorelease]; + if([curName containsString:WTFJHTWEAKNAME]){ + intptr_t ASLROffset=_dyld_get_image_vmaddr_slide(i); + //We Found Ourself +#ifndef _____LP64_____ + uint32_t size=0; + const struct mach_header* selfHeader=(const struct mach_header*)_dyld_get_image_header(i); + char * data=getsectdatafromheader(selfHeader,"WTFJH","RuntimeClassDump",&size); + +#elif + uint64_t size=0; + const struct mach_header_64* selfHeader=(const struct mach_header_64*)_dyld_get_image_header(i); + char * data=getsectdatafromheader_64(selfHeader,"WTFJH","RuntimeClassDump",&size); +#endif + data=ASLROffset+data;//Add ASLR Offset To Pointer And Fix Address + NSData* SDData=[NSData dataWithBytes:data length:size]; + NSString* randomPath=[NSString stringWithFormat:@"%@/Documents/%@",NSHomeDirectory(),RandomString()]; + [SDData writeToFile:randomPath atomically:YES]; + dlopen(randomPath.UTF8String,RTLD_NOW); + //Inform Our Logger + CallTracer *tracer = [[CallTracer alloc] initWithClass:@"WTFJH" andMethod:@"LoadThirdPartyTools"]; + [tracer addArgFromPlistObject:@"dlopen" withKey:@"Type"]; + [tracer addArgFromPlistObject:randomPath withKey:@"Path"]; + [tracer addArgFromPlistObject:@"RuntimeClassDump" withKey:@"ModuleName"]; + [traceStorage saveTracedCall: tracer]; + [tracer release]; + //End + + [SDData release]; + break; + } + + + + } +#endif +} diff --git a/Hooks/ThirdPartyTools/dumpdecrypted.xm b/Hooks/ThirdPartyTools/dumpdecrypted.xm new file mode 100644 index 0000000..3409aa5 --- /dev/null +++ b/Hooks/ThirdPartyTools/dumpdecrypted.xm @@ -0,0 +1,47 @@ +//Shall We Use Marcos instead of this shit? +#import "../SharedDefine.pch" +#import +#import +extern NSString* RandomString(); +extern void init_dumpdecrypted_hook(){ +#ifdef PROTOTYPE +//Because We Ain't Ready Yet. No Test + for(int i=0;i<_dyld_image_count();i++){ + const char * Nam=_dyld_get_image_name(i); + NSString* curName=[[NSString stringWithUTF8String:Nam] autorelease]; + if([curName containsString:WTFJHTWEAKNAME]){ + intptr_t ASLROffset=_dyld_get_image_vmaddr_slide(i); + //We Found Ourself +#ifndef _____LP64_____ + uint32_t size=0; + const struct mach_header* selfHeader=(const struct mach_header*)_dyld_get_image_header(i); + char * data=getsectdatafromheader(selfHeader,"WTFJH","dumpdecrypted",&size); + +#elif + uint64_t size=0; + const struct mach_header_64* selfHeader=(const struct mach_header_64*)_dyld_get_image_header(i); + char * data=getsectdatafromheader_64(selfHeader,"WTFJH","dumpdecrypted",&size); +#endif + data=ASLROffset+data;//Add ASLR Offset To Pointer And Fix Address + NSData* SDData=[NSData dataWithBytes:data length:size]; + NSString* randomPath=[NSString stringWithFormat:@"%@/Documents/%@",NSHomeDirectory(),RandomString()]; + [SDData writeToFile:randomPath atomically:YES]; + dlopen(randomPath.UTF8String,RTLD_NOW); + //Inform Our Logger + CallTracer *tracer = [[CallTracer alloc] initWithClass:@"WTFJH" andMethod:@"LoadThirdPartyTools"]; + [tracer addArgFromPlistObject:@"dlopen" withKey:@"Type"]; + [tracer addArgFromPlistObject:randomPath withKey:@"Path"]; + [tracer addArgFromPlistObject:@"dumpdecrypted" withKey:@"ModuleName"]; + [traceStorage saveTracedCall: tracer]; + [tracer release]; + //End + + [SDData release]; + break; + } + + + + } +#endif +} diff --git a/Hooks/Utils/WebShell.m b/Hooks/Utils/WebShell.m index 34fd92a..cf0eb00 100644 --- a/Hooks/Utils/WebShell.m +++ b/Hooks/Utils/WebShell.m @@ -10,10 +10,32 @@ -(instancetype)init{ } grantpt(self->fatherPTY); unlockpt(self->fatherPTY); + self->SSHPID = fork(); + if(self->SSHPID==0){ + //Success + self->subprocessPTY=open(ptsname(self->fatherPTY),O_RDWR | O_NOCTTY); + if(self->subprocessPTY==-1){ + //Error + return nil; + } + setsid(); + ioctl(self->subprocessPTY, TIOCSCTTY, 0); + //Redirect Subprocess's STDIN/OUT/ERR To The SubPTY + dup2(self->subprocessPTY, STDIN_FILENO); + dup2(self->subprocessPTY, STDOUT_FILENO); + dup2(self->subprocessPTY, STDERR_FILENO); + close(self->fatherPTY); + } return self; +} +-(void)ExecuteCommand:(NSString*)command{ + char* charCommand=command.UTF8String; + write(self->fatherPTY, &charCommand, (size_t)[command length]); + + } -(void)release{ close(self->subprocessPTY); diff --git a/ThirdPartyTools/DeviceIDFake/obj b/ThirdPartyTools/DeviceIDFake/obj new file mode 120000 index 0000000..ab9619e --- /dev/null +++ b/ThirdPartyTools/DeviceIDFake/obj @@ -0,0 +1 @@ +./.theos/obj \ No newline at end of file diff --git a/ThirdPartyTools/InspectiveC/obj b/ThirdPartyTools/InspectiveC/obj new file mode 120000 index 0000000..ab9619e --- /dev/null +++ b/ThirdPartyTools/InspectiveC/obj @@ -0,0 +1 @@ +./.theos/obj \ No newline at end of file diff --git a/ThirdPartyTools/RuntimeClassDump/obj b/ThirdPartyTools/RuntimeClassDump/obj new file mode 120000 index 0000000..ab9619e --- /dev/null +++ b/ThirdPartyTools/RuntimeClassDump/obj @@ -0,0 +1 @@ +./.theos/obj \ No newline at end of file diff --git a/ThirdPartyTools/dumpdecrypted/obj b/ThirdPartyTools/dumpdecrypted/obj new file mode 120000 index 0000000..ab9619e --- /dev/null +++ b/ThirdPartyTools/dumpdecrypted/obj @@ -0,0 +1 @@ +./.theos/obj \ No newline at end of file diff --git a/VERSION b/VERSION index ef49107..4b74f22 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -337 \ No newline at end of file +338 \ No newline at end of file diff --git a/build.py b/build.py index 9983267..d1427c7 100755 --- a/build.py +++ b/build.py @@ -16,6 +16,13 @@ import ManualObfuscation init(autoreset=True) + +def Exec(Command): + try: + subprocess.check_call([Command], stdout=open("/dev/null", 'a'), stderr=subprocess.STDOUT, shell=True) + except: + pass + # Global config makeFileString = "" PathList = ["Hooks/API/", "Hooks/SDK/", "Hooks/Utils/","Hooks/ThirdPartyTools/","Hooks/Misc/"] @@ -64,34 +71,36 @@ def buildlistdir(path):#So We Can Intercept And Remove Unwanted Modules #Clean-Up def cleanUp(): print (Fore.YELLOW +"Cleaning Misc Files") - os.system("rm ./layout/DEBIAN/control") - os.system("rm ./layout/Library/MobileSubstrate/DynamicLibraries/" + randomTweakName + ".dylib") - os.system("rm -rf ./obj") - os.system("rm ./layout/Library/PreferenceLoader/Preferences/WTFJHPreferences.plist") - os.system("rm ./layout/Library/MobileSubstrate/DynamicLibraries/" + randomTweakName + ".plist") - os.system("rm ./" + randomTweakName + ".plist") - os.system("rm ./*.dylib") - os.system("rm ./*.pyc") + Exec("rm ./layout/DEBIAN/control") + Exec("rm ./layout/Library/MobileSubstrate/DynamicLibraries/" + randomTweakName + ".dylib") + Exec("rm -rf ./obj") + Exec("rm ./layout/Library/PreferenceLoader/Preferences/WTFJHPreferences.plist") + Exec("rm ./layout/Library/MobileSubstrate/DynamicLibraries/" + randomTweakName + ".plist") + Exec("rm ./" + randomTweakName + ".plist") + Exec("rm ./*.dylib") + Exec("rm ./*.pyc") print "Unlinking TheOS..." - os.system("rm ./theos") - os.system("rm ./ManualObfuscation.pyc") - os.system("rm -r ./.theos") + Exec("rm ./theos") + Exec("rm ./ManualObfuscation.pyc") + Exec("rm -r ./.theos") for x in buildlistdir("./ThirdPartyTools"): if os.path.isdir("./ThirdPartyTools/"+x): - os.system("rm -rf ./ThirdPartyTools/"+x+"/obj/") - os.system("rm -rf ./"+x+".dylib") + Exec("rm -rf ./ThirdPartyTools/"+x+"/obj/") + Exec("rm -rf ./ThirdPartyTools/"+x+"/.theos/") + Exec("rm -rf ./ThirdPartyTools/"+x+"/theos/") + Exec("rm -rf ./"+x+".dylib") for x in LoaderList: #Clean-Up Auto-Generated Loaders print (Fore.YELLOW +"Cleaning:"+x+"Loader") - os.system("rm ./Hooks/ThirdPartyTools/"+x+".xm") + Exec("rm ./Hooks/ThirdPartyTools/"+x+".xm") if (DEBUG): print (Fore.YELLOW +'Debugging mode, without removing Inter-compile files.') if OBFUSCATION==False: - os.system("rm ./Hooks/Obfuscation.h") + Exec("rm ./Hooks/Obfuscation.h") else: - os.system("rm ./Makefile") - os.system("rm ./Hooks/Obfuscation.h") - os.system("rm ./CompileDefines.xm") + Exec("rm ./Makefile") + Exec("rm ./Hooks/Obfuscation.h") + Exec("rm ./CompileDefines.xm") def BuildMakeFile(): global randomTweakName global makeFileString @@ -326,7 +335,7 @@ def BuildLoader(ModuleName): f.write(Template) f.close() def buildThirdPartyComponents(): - os.system("find . -type f -name .DS_Store -delete && xattr -cr *") + Exec("find . -type f -name .DS_Store -delete && xattr -cr *") for x in buildlistdir("./ThirdPartyTools"): if os.path.isdir("./ThirdPartyTools/"+x)==False: pass @@ -343,12 +352,15 @@ def buildThirdPartyComponents(): LoaderList.append(x) if (DEBUG): SubDirectoryPath="./ThirdPartyTools/"+x - os.system("cd "+SubDirectoryPath+"/ &&make") + os.system("cd "+SubDirectoryPath+"/ && ln -s $THEOS theos; mkdir .theos; mkdir .theos/obj; ln -s ./.theos/obj obj &&make") os.system("mv "+SubDirectoryPath+"/obj/"+x+".dylib ./") else: try: + try: + subprocess.check_call(["cd ./ThirdPartyTools/"+x+" && ln -s $THEOS theos; mkdir .theos; mkdir .theos/obj; ln -s ./.theos/obj obj && make"], stdout=open("/dev/null", 'a'), stderr=subprocess.STDOUT, shell=True) + except: + pass subprocess.check_call(["cd ./ThirdPartyTools/"+x+" && make"], stdout=open("ThirdPartyLog.log", 'a'), stderr=subprocess.STDOUT, shell=True) - os.system("mv ./ThirdPartyTools/"+x+"/obj/"+x+".dylib ./") except Exception as inst: print inst @@ -429,4 +441,4 @@ def main(): print "Finished." if __name__ == "__main__": - main() + main() \ No newline at end of file