gpt4 book ai didi

ios - 如何通过应用程序ID确定iOS上哪些应用程序是后台应用程序,哪些应用程序是前台应用程序

转载 作者:技术小花猫 更新时间:2023-10-29 10:48:30 26 4
gpt4 key购买 nike

使用 this question 中描述的方法,我可以获得在 iOS 设备上运行的应用程序列表。我知道 PID 并且可以访问它们的 kinfo_proc 结构。如何确定哪些是前台进程哪些是后台进程(假设我的应用程序是后台进程)?

我试图根据 kinfo_proc 中的信息(参见第一个链接)通过 kp_proc.p_priority 找到它,但似乎无法推断出背景/优先级的前景状态。

我真的不在乎这是否适用于 AppStore Review,但我更喜欢一种无需越狱即可工作的方法(即私有(private) API 可以,但哪些?)。我希望它至少能在 iOS 5 上运行

我考虑过编写一个简单的 MobileSubstrate 扩展,将其注入(inject)所有应用程序并 Hook 每个人的 applicationDidBecomeActive,但这需要越狱并且侵入性太大。

最佳答案

好吧,看起来 nm 和 IDA 在模拟器的 SpringBoardServices 二进制文件上的一些用法在这方面帮助了我。以下代码适用于在 iPod Touch 4、iPhone 4 和 iPad1 WiFi(所有非 JB)上运行的 iOS 5.0.1当然,您永远不应该尝试将其提交给 AppStore

- (NSArray*) getActiveApps
{
mach_port_t *p;
void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(uikit, "SBSSpringBoardServerPort");
p = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(uikit);

void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
NSArray* (*SBSCopyApplicationDisplayIdentifiers)(mach_port_t* port, BOOL runningApps,BOOL debuggable) =
dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");
//SBDisplayIdentifierForPID - protype assumed,verification of params done
void* (*SBDisplayIdentifierForPID)(mach_port_t* port, int pid,char * result) =
dlsym(sbserv, "SBDisplayIdentifierForPID");
//SBFrontmostApplicationDisplayIdentifier - prototype assumed,verification of params done,don't call this TOO often(every second on iPod touch 4G is 'too often,every 5 seconds is not)
void* (*SBFrontmostApplicationDisplayIdentifier)(mach_port_t* port,char * result) =
dlsym(sbserv, "SBFrontmostApplicationDisplayIdentifier");



//Get frontmost application
char frontmostAppS[256];
memset(frontmostAppS,sizeof(frontmostAppS),0);
SBFrontmostApplicationDisplayIdentifier(p,frontmostAppS);
NSString * frontmostApp=[NSString stringWithFormat:@"%s",frontmostAppS];
//NSLog(@"Frontmost app is %@",frontmostApp);
//get list of running apps from SpringBoard
NSArray *allApplications = SBSCopyApplicationDisplayIdentifiers(p,NO, NO);
//Really returns ACTIVE applications(from multitasking bar)
/* NSLog(@"Active applications:");
for(NSString *identifier in allApplications) {
// NSString * locName=SBSCopyLocalizedApplicationNameForDisplayIdentifier(p,identifier);
NSLog(@"Active Application:%@",identifier);
}
*/

//get list of all apps from kernel
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;

size_t size;
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);

struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;

do {

size += size / 10;
newprocess = realloc(process, size);

if (!newprocess){

if (process){
free(process);
}

return nil;
}

process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);

} while (st == -1 && errno == ENOMEM);

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--){

int ruid=process[i].kp_eproc.e_pcred.p_ruid;
int uid=process[i].kp_eproc.e_ucred.cr_uid;
//short int nice=process[i].kp_proc.p_nice;
//short int u_prio=process[i].kp_proc.p_usrpri;
short int prio=process[i].kp_proc.p_priority;
NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];


BOOL systemProcess=YES;
if (ruid==501)
systemProcess=NO;



char * appid[256];
memset(appid,sizeof(appid),0);
int intID,intID2;
intID=process[i].kp_proc.p_pid,appid;
SBDisplayIdentifierForPID(p,intID,appid);/

NSString * appId=[NSString stringWithFormat:@"%s",appid];

if (systemProcess==NO)
{
if ([appId isEqualToString:@""])
{
//final check.if no appid this is not springboard app
NSLog(@"(potentially system)Found process with PID:%@ name %@,isSystem:%d,Priority:%d",processID,processName,systemProcess,prio);
}
else
{

BOOL isFrontmost=NO;
if ([frontmostApp isEqualToString:appId])
{
isFrontmost=YES;
}
NSNumber *isFrontmostN=[NSNumber numberWithBool:isFrontmost];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName,appId,isFrontmostN, nil]
forKeys:[NSArray arrayWithObjects:@"ProcessID", @"ProcessName",@"AppID",@"isFrontmost", nil]];

NSLog(@"PID:%@, name: %@, AppID:%@,isFrontmost:%d",processID,processName,appId,isFrontmost);
[array addObject:dict];
}
}
}

free(process);
return array;
}
}
}

dlclose(sbserv);
}

当然,第二个循环并不是绝对必要的,但我也需要非本地化的名称和 PID。

关于ios - 如何通过应用程序ID确定iOS上哪些应用程序是后台应用程序,哪些应用程序是前台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8252396/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com