在我的应用程序中,我通过这种方式(通过IOKit)获取电池信息。
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSExternalConnectedKey));
printf(" external connected = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSBatteryInstalledKey));
printf(" battery present = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSIsChargingKey));
printf(" battery charging = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &cur_cap);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &max_cap);
}
if( (-1 != cur_cap) && (-1 != max_cap) )
{
printf(" cap = %d/%d\n", cur_cap, max_cap);
gcurCapacity = cur_cap;//hab
gmaxCapacity = max_cap;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSTimeRemainingKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
NSLog(@" time REM = %d:%02d\n", tmp/60, tmp%60);
printf("time cicA = %d:%02d\n", tmp/60, tmp%60);
NSString *stringTimeRem = [NSString stringWithFormat:@"%d:%02d", tmp/60, tmp%60];
[[NSUserDefaults standardUserDefaults] setObject:stringTimeRem forKey:@"stringREM"];
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSAmperageKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
gcurrent = tmp;//hab
printf(" current = %d\n", tmp);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCycleCountKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" cycle count = %d\n", tmp);
gloadcycles = tmp;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSLocationKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" location = %d\n", tmp);
}
printf("\n");
CFRelease(prop);
return;}如何使用dlopen访问这些信息?我需要使用dlopen获取IOReturn和io_registry_entry_t,这样苹果可能就不会发现IOKit在那里了。谢谢。
发布于 2013-04-28 00:27:03
我需要使用dlopen获取
IOReturn和io_registry_entry_t
这些只是类型。它们是在头文件中声明的,不是编译到IOKit库中的类型。使用dlopen()是无法获得这些的。
,所以苹果可能不会发现IOKit在那里
同样,类型没有在二进制文件中显式表示。如果苹果发现你在使用IOKit,那么不的原因就是使用了这些类型。它们是出卖的函数名。
但是,如果您使用dlopen()检索指向这些函数的指针,则表示函数名称的字符串对于苹果的静态分析工具来说仍然是一本打开的书。您可能需要做一些额外的模糊处理,以便二进制文件不会直接公开私有函数名:
NSString *secondPart = @"ateCFProperties";
NSString *firstPart = @"IORegistryEntryCre";
const char *fname = [[firstPart stringByAppendingString:secondPart] UTF8String];
IOReturn (*fptr)(io_registry_entry_t, CFMutableDictionaryRef *, int, int);
fptr = dlsym(dyld_handle, fname);等。
发布于 2013-04-30 07:48:48
H2CO3是正确的。#includeing IOKit完全不会影响编译后的代码。当你直接使用IOKit头中定义的函数和IOKit链接时,私有框架才能在你的应用中清晰地显示出来。一种用于隐藏私有框架和使用的符号的混淆形式是简单的密码转换。例如,以H2CO3为例:
// Deciphers string in-place and returns a pointer to it
__attribute__((always_inline)) char* decipher(char* str) {
int i, n = strlen(str);
for(i = 0; i < n; i++) str[i]--;
return str;
}
//...
char sym[] = "JPSfhjtuszFouszDsfbufDGQspqfsujft";
char fr[] = "Gsbnfxpslt";
char fmwk[] = "JPLju";
char lib[60];
decipher(fmwk);
sprintf(lib, "/System/Library/%s/%s.framework/Versions/A/%s", fr, fmwk, fmwk);
void* handle = dlopen(lib, RTLD_LAZY);
IOReturn (*fptr)(io_registry_event_t, CFMutableDictionaryRef*,i int, int);
fptr = dlsym(handle, decipher(sym));
// Now just call fptr() as if it were IORegistryEntryCreateCFProperties()这与H2CO3版本的不同之处在于,这将阻止人们在没有合理专业知识的情况下手动分析应用程序来查找IOKit。当然,无论您如何努力隐藏IOKit的用法,坚定的逆向程序仍然可以找到它的用法。混淆在这里很有用,因为App Store的审查者可能几天内都不会花时间去撤销你的应用。此外,请记住在提交应用程序之前使用strip。我认为剥离在Xcode中是默认启用的,但我不确定。你需要自己弄清楚这一点。
发布于 2018-10-05 00:42:29
#import "ViewController.h"
#import "IOKit/IOKitLib.h"
#import "IOKit/IOPSKeys.h"
#include <dlfcn.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
static mach_port_t *s_kIOMasterPortDefault;
static kern_return_t (*s_IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options);
static mach_port_t (*s_IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching CF_RELEASES_ARGUMENT);
static CFMutableDictionaryRef (*s_IOServiceMatching)(const char *name);
static CFMutableDictionaryRef g_powerSourceService;
static mach_port_t g_platformExpertDevice;
static BOOL foundSymbols = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
void* handle = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
s_IORegistryEntryCreateCFProperties = dlsym(handle, "IORegistryEntryCreateCFProperties");
s_kIOMasterPortDefault = dlsym(handle, "kIOMasterPortDefault");
s_IOServiceMatching = dlsym(handle, "IOServiceMatching");
s_IOServiceGetMatchingService = dlsym(handle, "IOServiceGetMatchingService");
if (s_IORegistryEntryCreateCFProperties && s_IOServiceMatching && s_IOServiceGetMatchingService) {
g_powerSourceService = s_IOServiceMatching("IOPMPowerSource");
g_platformExpertDevice = s_IOServiceGetMatchingService(*s_kIOMasterPortDefault, g_powerSourceService);
foundSymbols = (g_powerSourceService && g_platformExpertDevice);
}
});
if (!foundSymbols) {
return;
}
print_raw_battery_state(g_platformExpertDevice);
}
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
// battery dictionary
NSLog(@"prop: %@", prop);
printf("\n");
CFRelease(prop);
return;
}
}
@end在iOS 11和12中,您只会得到几个值。
https://stackoverflow.com/questions/16254325
复制相似问题