2013-04-27 29 views
1

在我的應用程序中,我使用這種方式獲取電池信息(通過IOKit)。使用dlopen的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,所以Apple不會發現IOKit在那裏。 謝謝。

回答

2

我需要使用dlopen

這些都是只是類型得到IOReturnio_registry_entry_t它們在頭文件中聲明,而不是編譯到IOKit庫中。你不能使用dlopen()

因此蘋果不會可能會發現,由於IOKit是有

再次,類型不明確的二進制表示。如果Apple發現您使用的是IOKit,那麼的原因不是就是這些類型的使用。他們是背叛的功能名稱。

但是,如果您使用dlopen()來檢索指向這些函數的指針,表示函數名稱的字符串仍然是Apple靜態分析工具的開放書籍。您可能需要做一些額外的混淆,以二進制不直接暴露私有函數名稱:

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

+0

感謝您的回覆,但我不明白如何獲取這些類型(IOReturn和io_registry_entry_t)。 – 2013-04-27 16:36:47

+0

@AlfredoGalli'#import ' – 2013-04-27 17:03:16

+0

這就是問題所在。我不能在我的iPhone應用程序中使用IOKit,否則Apple會拒絕它。 – 2013-04-27 17:10:25

0

H2CO3是正確的。只需要#include ing 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中是默認啓用的,但我不確定。你需要自己找出一個。