由于我们公司是一款赚钱的app,有些作弊用户会通过越狱手机,下载一些插件,(xCon(n00neimp0rtant and Lunatik联合开发)、NZT、tsPretector等),从而篡改设备信息.
在网上谷歌的答案千篇一律,基本都被绕过或者被钩住修改过了。
我所检测的方式集合了多种条件、以及获取了本机的所有安装app
代码如下:
一、
#include <string.h>
#import <mach-o/loader.h>
#import <mach-o/dyld.h>
#import <mach-o/arch.h>
#import <objc/runtime.h>
const char* jailbreak_tool_pathes[] = {
"/Applications/Cydia.app",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/bin/bash",
"/usr/sbin/sshd",
"/etc/apt"
};
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
//判断是否存在文件
-(bool) getPathYueYu{
for (int i=0; i<ARRAY_SIZE(jailbreak_tool_pathes); i++) {
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_tool_pathes[i]]]) {
NSLog(@"The device is jail broken!");
return YES;
}
}
NSLog(@"The device is NOT jail broken!");
return NO;
}
二、
检测dylib(动态链接库)的内容这种方法是目前最靠谱的方法,调用_dyld_image_count()和_dyld_get_image_name()来看当前有哪些dylib被加载
bool printDYLD(){
//Get count of all currently loaded DYLD
uint32_t count = _dyld_image_count();
//安装NZT插件后会把原有的越狱文件名称统一修改成在/usr/lib/目录下的libSystem.B.dylib
NSString *jtpath=@"/usr/lib/libSystem.B.dylib";
uint32_t countyueyu=0;
for(uint32_t i = 0; i < count; i++)
{
//Name of image (includes full path)
const char *dyld = _dyld_get_image_name(i);
//Get name of file
int slength = strlen(dyld);
int j;
for(j = slength - 1; j>= 0; --j)
if(dyld[j] == '/') break;
NSString *name = [[NSString alloc]initWithUTF8String:_dyld_get_image_name(i)];
if([name compare:jtpath] == NSOrderedSame)
{
countyueyu++;
}
if([name containsString:@"/Library/MobileSubstrate"])
{
return YES;
}
}
if( countyueyu > 2 )
return YES;
return NO;
printf("\n");
}
未安装越狱防护的越狱机,安装插件后,会安装在/Library/MobileSubstrate目录下,
例如:
/Library/MobileSubstrate/MobileSubstrate.dylib
/Library/MobileSubstrate/DynamicLibraries/RHRevealLoader.dylib
/Library/MobileSubstrate/DynamicLibraries/xCon.dylib
在安装ZNT插件后,检测时会将所有越狱文件伪装成
/usr/lib/libSystem.B.dylib
三、
-(BOOL)getYueYu
{
NSMutableArray *proState = [NSMutableArray array];
//获取用户手机已安装app
Class LSApplicationWorkspace_class =objc_getClass("LSApplicationWorkspace");
SEL mydefault =NSSelectorFromString(@"defaultWorkspace");
NSObject* workspace =[LSApplicationWorkspace_class performSelector:mydefault];
SEL myappinfoinstall =NSSelectorFromString(@"allApplications");
NSString *appinfostring= [NSString stringWithFormat:@"%@",[workspace performSelector:myappinfoinstall]];
NSLog(@"----foo89789-----%@",appinfostring);
appinfostring =[appinfostring stringByReplacingOccurrencesOfString:@"<" withString:@""];
appinfostring =[appinfostring stringByReplacingOccurrencesOfString:@">" withString:@""];
appinfostring =[appinfostring stringByReplacingOccurrencesOfString:@"\"" withString:@""];
appinfostring =[appinfostring stringByReplacingOccurrencesOfString:@"(" withString:@""];
appinfostring =[appinfostring stringByReplacingOccurrencesOfString:@")" withString:@""];
NSLog(@"----foo0000-----:%@",appinfostring);
NSArray* foo = [appinfostring componentsSeparatedByString:@","];
NSLog(@"----foo-----");
BOOL isyueyu = NO;
NSString *cydia = @"com.saurik.Cydia";
NSString *chudong = @"com.touchsprite.ios";
NSString *nzt = @"NZT";
for (NSString *dic in foo)
{
NSLog(@"----foo222-----");
NSString* child string = [NSString stringWithFormat:@"%@",dic ];
// NSLog(@"----foo222-----%@",childstring);
child string = [childstring stringByReplacingOccurrencesOfString:@" " withString:@"&"];
//childstring =[childstring stringByReplacingOccurrencesOfString:@"-" withString:@"."];
NSLog(@"----foo222-----%@",childstring);
NSArray* foo2 = [childstring componentsSeparatedByString:@"&"];
NSString *appname;
@try {
appname = [NSString stringWithFormat:@"%@",[foo2 objectAtIndex: 6]];
}
@catch (NSException *exception) {
appname = [NSString stringWithFormat:@"%@",[foo2 objectAtIndex: 5]];
}
if([appname compare:cydia] == NSOrderedSame)
{
isyueyu = YES;
break;
}
if([appname compare:chudong] == NSOrderedSame)
{
isyueyu = YES;
break;
}
if([appname compare:nzt]==NSOrderedSame)
{
isyueyu = YES;
break;
}
// NSLog(@"----foo222yyyy-----%@",appname);
NSString *msg = [NSString stringWithFormat:@"{\"name\":\"%@\",\"index\":\"%@\"}",appname, @""];
[proState addObject:msg];
NSLog(@"----foo3333-----");
}
return isyueyu;
}
获取应用列表,通过比对info.plist里的应用名称来判断手机是否安装了越狱插件。
四、判断越狱
- (BOOL)isJailBreak
{
if([self getYueYu])
{
NSLog(@"The device is jail broken!");
return YES;
}
else
{
if([self getPathYueYu])
{
return YES;
}
else
{
bool isyueyu = printDYLD();
return isyueyu;
}
}
NSLog(@"The device is NOT jail broken!");
return NO;
}
我在研究两天后,只能通过判断/usr/lib/libSystem.B.dylib 文件的个数和应用名称比对,来判断是否越狱。虽然觉得比较蠢,但是没办法。如果有更高明的方法请告知,感激不尽。
如有不对之处,还请指正。
网友评论