0


IOS - 越狱检测

判断是否能打开越狱软件

利用URL Scheme来查看是否能够代开比如cydia这些越狱软件

//Check cydia URL hook canOpenURL 来绕过if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.avl.com"]]){return YES;}if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]){return YES;}
 frida-trace -U -f 包名  -m  "+[NSURL URLWithString:]"

包名 可以用 frida-ps -Ua来查看, 然后更改生成的js路径脚本

/*
 * Auto-generated by Frida. Please modify to match the signature of +[NSURL URLWithString:].
 * This stub is currently auto-generated from manpages when available.
 *
 * For full API reference, see: https://frida.re/docs/javascript-api/
 */{/**
   * Called synchronously when about to call +[NSURL URLWithString:].
   *
   * @this {object} - Object allowing you to store state for use in onLeave.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {array} args - Function arguments represented as an array of NativePointer objects.
   * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
   * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
   * @param {object} state - Object allowing you to keep state across function calls.
   * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
   * However, do not use this to store function arguments across onEnter/onLeave, but instead
   * use "this" which is an object for keeping state local to an invocation.
   */onEnter(log, args, state){var URLName = ObjC.Object(args[2]);if(URLName.containsString_){if(URLName.containsString_("http://")||
           URLName.containsString_("https://")||
           URLName.containsString_("file://")){}else{if(URLName.containsString_("://")){log(`+[NSURL URLWithString:]`+ URLName);
                args[2]= ObjC.classes.NSString.stringWithString_("xxxxxx://");}}}},/**
   * Called synchronously when about to return from +[NSURL URLWithString:].
   *
   * See onEnter for details.
   *
   * @this {object} - Object allowing you to access state stored in onEnter.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {NativePointer} retval - Return value represented as a NativePointer object.
   * @param {object} state - Object allowing you to keep state across function calls.
   */onLeave(log, retval, state){}}

判断是否可以访问一些越狱的文件

越狱后会产生额外的文件,通过判断是否存在这些文件来判断是否越狱了,可以用fopen和FileManager两个不同的方法去获取

BOOLfileExist(NSString* path){
    NSFileManager *fileManager =[NSFileManager defaultManager];BOOL isDirectory = NO;if([fileManager fileExistsAtPath:path isDirectory:&isDirectory]){return YES;}return NO;}BOOLdirectoryExist(NSString* path){
    NSFileManager *fileManager =[NSFileManager defaultManager];BOOL isDirectory = YES;if([fileManager fileExistsAtPath:path isDirectory:&isDirectory]){return YES;}return NO;}BOOLcanOpen(NSString* path){
    FILE *file =fopen([path UTF8String],"r");if(file==nil){returnfileExist(path)||directoryExist(path);}fclose(file);return YES;}
 
 NSArray* checks =[[NSArray alloc] initWithObjects:@"/Application/Cydia.app",
                       @"/Library/MobileSubstrate/MobileSubstrate.dylib",
                       @"/bin/bash",
                       @"/usr/sbin/sshd",
                       @"/etc/apt",
                       @"/usr/bin/ssh",
                       @"/private/var/lib/apt",
                       @"/private/var/lib/cydia",
                       @"/private/var/tmp/cydia.log",
                       @"/Applications/WinterBoard.app",
                       @"/var/lib/cydia",
                       @"/private/etc/dpkg/origins/debian",
                       @"/bin.sh",
                       @"/private/etc/apt",
                       @"/etc/ssh/sshd_config",
                       @"/private/etc/ssh/sshd_config",
                       @"/Applications/SBSetttings.app",
                       @"/private/var/mobileLibrary/SBSettingsThemes/",
                       @"/private/var/stash",
                       @"/usr/libexec/sftp-server",
                       @"/usr/libexec/cydia/",
                       @"/usr/sbin/frida-server",
                       @"/usr/bin/cycript",
                       @"/usr/local/bin/cycript",
                       @"/usr/lib/libcycript.dylib",
                       @"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
                       @"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
                       @"/Applications/FakeCarrier.app",
                       @"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
                       @"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
                       @"/usr/libexec/ssh-keysign",
                       @"/usr/libexec/sftp-server",
                       @"/Applications/blackra1n.app",
                       @"/Applications/IntelliScreen.app",
                       @"/Applications/Snoop-itConfig.app"
                       @"/var/lib/dpkg/info", nil];//Check installed appfor(NSString* check in checks){if(canOpen(check)){returnYES;}}
 frida-trace -U -f 包名  -m  "-[NSFileManager fileExistsAtPath:]"
/*
 * Auto-generated by Frida. Please modify to match the signature of -[NSFileManager fileExistsAtPath:].
 * This stub is currently auto-generated from manpages when available.
 *
 * For full API reference, see: https://frida.re/docs/javascript-api/
 */{/**
   * Called synchronously when about to call -[NSFileManager fileExistsAtPath:].
   *
   * @this {object} - Object allowing you to store state for use in onLeave.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {array} args - Function arguments represented as an array of NativePointer objects.
   * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
   * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
   * @param {object} state - Object allowing you to keep state across function calls.
   * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
   * However, do not use this to store function arguments across onEnter/onLeave, but instead
   * use "this" which is an object for keeping state local to an invocation.
   */onEnter(log, args, state){var fileName = ObjC.Object(args[2]);if(fileName.containsString_){if(fileName.containsString_("apt")||
           fileName.containsString_("MobileSubstrate")||
           fileName.containsString_("Cydia")||
           fileName.containsString_("bash")||
           fileName.containsString_("ssh")||
           fileName.containsString_("/bin/sh")||
           fileName.containsString_("Applications")||
           fileName.containsString_("/bin/su")||
           fileName.containsString_("dpkg")){
            console.log('fileExistsAtPath called from:\n'+
                Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n')+'\n');
           args[2]= ObjC.classes.NSString.stringWithString_("/xxxxxx");log(`-[NSFileManager fileExistsAtPath: ${fileName}`);}}//log(`-[NSFileManager fileExistsAtPath: ${fileName}`);},/**
   * Called synchronously when about to return from -[NSFileManager fileExistsAtPath:].
   *
   * See onEnter for details.
   *
   * @this {object} - Object allowing you to access state stored in onEnter.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {NativePointer} retval - Return value represented as a NativePointer object.
   * @param {object} state - Object allowing you to keep state across function calls.
   */onLeave(log, retval, state){}}

关键词检测 :JailBroken 及 JailBreak 等;

使用frida脚本简单干掉:

在启动就注入进去, -f是通过spawn,也就是重启apk注入js

frida -U -f 包名 --no-pause -l 过越狱检测.js

//越狱检测- 简单先将返回1的Nop掉var resolver =newApiResolver('objc');
resolver.enumerateMatches('*[* *Jailb*]',{onMatch:function(match){let funcName = match.name;let funcAddr = match.address;
        Interceptor.attach(ptr(funcAddr),{onEnter:function(args){},onLeave:function(retval){if(retval.toInt32()===1){
                    retval.replace(0);}
                console.log(funcName, retval);}});},onComplete:function(){}});
resolver.enumerateMatches('*[* *JailB*]',{onMatch:function(match){let funcName = match.name;let funcAddr = match.address;
        Interceptor.attach(ptr(funcAddr),{onEnter:function(args){},onLeave:function(retval){if(retval.toInt32()===1){
                    retval.replace(0);}
                console.log(funcName, retval);}});},onComplete:function(){}});
resolver.enumerateMatches('*[* *jailB*]',{onMatch:function(match){let funcName = match.name;let funcAddr = match.address;
        Interceptor.attach(ptr(funcAddr),{onEnter:function(args){},onLeave:function(retval){if(retval.toInt32()===1){
                    retval.replace(0);}
                console.log(funcName, retval);}});},onComplete:function(){}});

本文转载自: https://blog.csdn.net/weixin_38927522/article/details/129370686
版权归原作者 Codeooo 所有, 如有侵权,请联系我们删除。

“IOS - 越狱检测”的评论:

还没有评论