ios-hooks/README.md
2025-10-14 17:41:08 +08:00

247 lines
6.9 KiB
Markdown

+ (NSDictionary *)collectBatteryInfoIfNeeded {
NSMutableDictionary *dictionary = [NSMutableDictionary new];
UIDevice *device = [UIDevice currentDevice];
BOOL originalBatteryMonitoringEnabled = device.isBatteryMonitoringEnabled;
[device setBatteryMonitoringEnabled:YES];
UIDeviceBatteryState batteryState = device.batteryState;
NSNumber *batteryStateNumber = [NSNumber numberWithInteger:batteryState];
[dictionary setObject:batteryStateNumber forKey:@"ict"];
float batteryLevel = device.batteryLevel;
int batteryPercentage = (int)(batteryLevel * 100);
if (batteryPercentage > 0) {
batteryPercentage = batteryPercentage ^ 0x10101010;
NSNumber *batteryLevelNumber = @(batteryPercentage);
[dictionary setObject:batteryLevelNumber forKey:@"icm"];
}
else {
[dictionary setObject:@"-1" forKey:@"icm"];
}
[device setBatteryMonitoringEnabled:originalBatteryMonitoringEnabled];
return dictionary;
}
+ (NSString *)collectModelRevision {
struct utsname systemInfo;
if (uname(&systemInfo) == 0) {
NSString *modelString = [NSString stringWithUTF8String:systemInfo.machine];
return modelString;
}
return nil;
}
+ (NSString *)collectSubplatform {
if (@available(iOS 14.0, *)) {
if ([[NSProcessInfo processInfo] isiOSAppOnMac]) {
return @"ios_on_mac";
}
}
if (@available(iOS 13.0, *)) {
if ([[NSProcessInfo processInfo] isMacCatalystApp]) {
return @"mac_catalyst";
}
}
return @"ios";
}
+ (NSMutableDictionary *)collectScreenDimensions{
NSMutableDictionary *dict = [NSMutableDictionary new];
UIScreen *mainScreen = [UIScreen mainScreen];
CGRect bounds = [mainScreen bounds];
CGRect nativeBounds = [mainScreen nativeBounds];
CGFloat scale = [mainScreen scale];
[dict setObject:@(bounds.size.width) forKeyedSubscript:@"dx"];
[dict setObject:@(bounds.size.height) forKeyedSubscript:@"dy"];
[dict setObject:@(nativeBounds.size.width) forKeyedSubscript:@"ndx"];
[dict setObject:@(nativeBounds.size.height) forKeyedSubscript:@"ndy"];
[dict setObject:@(scale) forKeyedSubscript:@"scale"];
return dict;
}
+ (NSDictionary *)collectBatteryInfoIfNeeded {
NSMutableDictionary *dictionary = [NSMutableDictionary new];
UIDevice *device = [UIDevice currentDevice];
BOOL originalBatteryMonitoringEnabled = device.isBatteryMonitoringEnabled;
[device setBatteryMonitoringEnabled:YES];
UIDeviceBatteryState batteryState = device.batteryState;
NSNumber *batteryStateNumber = [NSNumber numberWithInteger:batteryState];
[dictionary setObject:batteryStateNumber forKey:@"ict"];
float batteryLevel = device.batteryLevel;
int batteryPercentage = (int)(batteryLevel * 100);
if (batteryPercentage > 0) {
batteryPercentage = batteryPercentage ^ 0x10101010;
NSNumber *batteryLevelNumber = @(batteryPercentage);
[dictionary setObject:batteryLevelNumber forKey:@"icm"];
}
else {
[dictionary setObject:@"-1" forKey:@"icm"];
}
[device setBatteryMonitoringEnabled:originalBatteryMonitoringEnabled];
return dictionary;
}
+ (id)collectTimeZoneOffset {
NSTimeZone *tz = [NSTimeZone localTimeZone];
NSInteger sec = [tz secondsFromGMT];
double hoursFromGMT = (double)sec / 3600.0;
return @(hoursFromGMT);
}
+ (void)userAgent {
static WKWebView *webView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
webView = [WKWebView new];
});
[webView evaluateJavaScript:@"function getAgent() {return navigator.userAgent;} getAgent(); " completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"zzh the useragent:%@ ",result);
}];
}
+ (unsigned long long)collectAccessibilityFeatures {
NSInteger features = 0;
if (UIAccessibilityIsClosedCaptioningEnabled()) {
features |= 0x2;
}
if (UIAccessibilityIsMonoAudioEnabled()) {
features |= 0x4;
}
if (UIAccessibilityIsReduceMotionEnabled()) {
features |= 0x8;
}
if (UIAccessibilityIsGuidedAccessEnabled()) {
features |= 0x10;
}
if (UIAccessibilityIsInvertColorsEnabled()) {
features |= 0x20;
}
if (UIAccessibilityIsVoiceOverRunning()) {
features |= 0x40;
}
if (UIAccessibilityDarkerSystemColorsEnabled()) {
features |= 0x80;
}
if (UIAccessibilityIsBoldTextEnabled()) {
features |= 0x100;
}
if (UIAccessibilityIsGrayscaleEnabled()) {
features |= 0x200;
}
if (UIAccessibilityIsReduceTransparencyEnabled()) {
features |= 0x400;
}
if (UIAccessibilityIsSpeakScreenEnabled()) {
features |= 0x800;
}
if (UIAccessibilityIsSpeakSelectionEnabled()) {
features |= 0x1000;
}
if (UIAccessibilityIsSwitchControlRunning()) {
features |= 0x2000;
}
if (UIAccessibilityIsShakeToUndoEnabled()) {
features |= 0x4000;
}
if (UIAccessibilityIsAssistiveTouchRunning()) {
features |= 0x8000;
}
if (UIAccessibilityHearingDevicePairedEar() != 0) {
features |= 0x400000;
}
if (@available(iOS 13.0, *)) {
if ([UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark) {
features |= 0x10000;
}
if (UIAccessibilityIsOnOffSwitchLabelsEnabled()) {
features |= 0x20000;
}
if (UIAccessibilityIsVideoAutoplayEnabled()) {
features |= 0x40000;
}
if (UIAccessibilityShouldDifferentiateWithoutColor()) {
features |= 0x80000;
}
if (@available(iOS 14.0, *)) {
if (UIAccessibilityPrefersCrossFadeTransitions()) {
features |= 0x100000;
}
if (UIAccessibilityButtonShapesEnabled()) {
features |= 0x200000;
}
}
}
NSLog(@"features:\n%ld",features);
return features;
}
+ (long long)collectMonotonicRawClockTimeMillis {
struct timespec tp;
if(clock_gettime(CLOCK_MONOTONIC_RAW, &tp) != -1) {
long xx = tp.tv_sec*1000 + tp.tv_nsec/1000000;
return xx;
}
return 0;
}
+ (NSString *)collectDeviceKeyboards{
NSArray *lanagues = [NSLocale preferredLanguages];
__block NSString *str = @"";
[lanagues enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (idx < lanagues.count-1) {
str = [str stringByAppendingFormat:@"%@,",obj];
}
else {
str = [str stringByAppendingFormat:@"%@",obj];
}
}];
return str;
}
+ (long long)collectKernelBootTimeMillis {
struct timeval bootTime;
int mib[2] = {CTL_KERN,KERN_BOOTTIME};
size_t size = sizeof(bootTime);
if (sysctl(mib, 2, &bootTime, &size, NULL, 0) != -1) {
return bootTime.tv_sec * 1000;///
};
return 0;
}