native APP开发和web已经是很熟悉的套路了,但是最近几周看下来,有了更深入的了解,不由的感叹技术的研究是无止境的。
1、APP申请后台常驻权限:
只要在info.plist里声明使用audio play等权限,那么可以获得一定时间内后台生命。
在APP被切入后台时,在AppDelegate的
func applicationDidEnterBackground(_ application: UIApplication) {}
方法中,可以被触发,此时可以计算剩余的时间,在结束前再次申请使用资源,以此循环,可以无限后台运行;注意这里直接使用timeout定时任务在真机上出错,需要手写定时方法。
2、后台运行的APP调起其他应用
非常令人吃惊,后台运行的APP可以轻易的调起其他应用,甚至包括自己,这里是一个OC的方法,前提是需要知道目标APP的bundle identifier(bundle ID)
- (void)openAppByBundleID{
Class lsawsc = objc_getClass("LSApplicationWorkspace");
NSObject* workspace = [lsawsc performSelector:NSSelectorFromString(@"defaultWorkspace")];
// iOS6 没有defaultWorkspace
if ([workspace respondsToSelector:NSSelectorFromString(@"openApplicationWithBundleID:")])
{ [workspace performSelector:NSSelectorFromString(@"openApplicationWithBundleID:") withObject:@"com.xx.demo"]}
}
3、safari调起 APP
app包文件,查看内容,可以在info.plist的URL Type中,看到配置的短链接(可能有多个),浏览器可以直接通过短链接调起APP.
4、app下载lua脚本动态执行方法;
未完待续
5、app通过webview打开网页(注入UA),并分析dom;
6、检查其他APP的安装情况OC
(1)iOS 11及以上
- (void)getAppsOveriOS11{
NSBundle *container = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
if ([container load]) {
Class appContainer = NSClassFromString(@"MCMAppContainer");
id test = [appContainer performSelector:@selector(containerWithIdentifier:error:) withObject:@"com.rovio.angrybirdsfight" withObject:nil];
//bundleId 事先在appstore手工查看,pp助手mac版,只能逐个核对是否已安装
/*
解压该文件
解压后的根目录下会看到一个后缀名为iTunesMetadata.plist的文件
mac下直接打开这个文件,windows可以用plist editor打开
搜索"softwareVersionBundleId"
下面一行的com..就是这个APP的bundleID
*/
NSLog(@"%@",test);
if (test) {
NSLog(@"yes");
} else {
NSLog(@"no");
}
}
}
(2)iOS11以下
- (void)getAppsUnderiOS11{
//ios 11以下可以
NSLog(@"get all apps");
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
NSObject *workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
NSArray *apps = [workspace performSelector:@selector(allInstalledApplications)];
Class LSApplicationProxy_class = objc_getClass("LSApplicationProxy");
for (int i = 0; i < apps.count; i++) {
NSObject *temp = apps[i];
if ([temp isKindOfClass:LSApplicationProxy_class]) {
//应用的bundleId
NSString *appBundleId = [temp performSelector:NSSelectorFromString(@"applicationIdentifier")];
//应用的名称
NSString *appName = [temp performSelector:NSSelectorFromString(@"localizedName")];
//应用的类型是系统的应用还是第三方的应用
NSString * type = [temp performSelector:NSSelectorFromString(@"applicationType")];
//应用的版本
NSString * shortVersionString = [temp performSelector:NSSelectorFromString(@"shortVersionString")];
NSLog(@"类型=%@应用的BundleId=%@ ++++应用的名称=%@版本号=%@",type,appBundleId,appName,shortVersionString);
}
}
}
7、检查正在运行的其他APP,待验证
- (void)getRunningApp{
NSArray * processes = [[UIDevice currentDevice] runningProcesses];
NSLog(@"aaaa");
if(processes){
for (NSDictionary * dict in processes){
NSLog(@"%@ - %@", [dict objectForKey:@"ProcessID"], [dict objectForKey:@"ProcessName"]);
}
}else{
NSLog(@"processes is null");
}
}
h文件单独声明
@interface UIDevice (ProcessesAdditions)
- (NSArray *)runningProcesses;
@end
m文件
@implementation UIDevice (ProcessesAdditions)
- (NSArray *)runningProcesses {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;
size_t size=1000038592;
/*
size_t size
size 不赋予值,在真机上报内存分配错误
malloc: *** mach_vm_map(size=8637038592) failed (error code=3)
iOS真机还是有问题
*/
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
do {
NSLog(@"2222");
size += size / 10;
newprocess = realloc(process, size);
NSLog(@"333");
if (!newprocess){
if (process){
free(process);
}
NSLog(@"4444");
return nil;
}
NSLog(@"77777");
process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);
NSLog(@"8888");
} while (st == -1 && errno == ENOMEM);
NSLog(@"9999");
if (st == 0){
if (size % sizeof(struct kinfo_proc) == 0){
int nprocess = size / sizeof(struct kinfo_proc);
if (nprocess){
NSMutableArray * array = [[NSMutableArray alloc] init];
for (int i = nprocess - 1; i >= 0; i--){
NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil]
forKeys:[NSArray arrayWithObjects:@"ProcessID", @"ProcessName", nil]];
// [processID release];
// [processName release];
[array addObject:dict];
// [dict release];
}
free(process);
// return [array autorelease];
return array;
}
}
}
return nil;
}
@end