commit fdff95e1fc7dea4d19929f2ea9f7231bb6b8791c Author: xsean Date: Fri Sep 5 18:48:22 2025 +0800 init diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..93f27e5 Binary files /dev/null and b/.DS_Store differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib new file mode 100644 index 0000000..db2fdb7 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist new file mode 100644 index 0000000..32288e8 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib new file mode 100644 index 0000000..29c6297 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib new file mode 100644 index 0000000..476a9a1 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist new file mode 100644 index 0000000..a19e16c Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist differ diff --git a/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib new file mode 100644 index 0000000..13cf575 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib differ diff --git a/.theos/_/Applications/nochange.app/Settings.storyboardc/Info.plist b/.theos/_/Applications/nochange.app/Settings.storyboardc/Info.plist new file mode 100644 index 0000000..8a3db60 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Settings.storyboardc/Info.plist differ diff --git a/.theos/_/Applications/nochange.app/Settings.storyboardc/Settings.nib b/.theos/_/Applications/nochange.app/Settings.storyboardc/Settings.nib new file mode 100644 index 0000000..533d368 Binary files /dev/null and b/.theos/_/Applications/nochange.app/Settings.storyboardc/Settings.nib differ diff --git a/.theos/_/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib b/.theos/_/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib new file mode 100644 index 0000000..a9b833e Binary files /dev/null and b/.theos/_/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib differ diff --git a/.theos/_/Applications/nochange.app/embedded.mobileprovision b/.theos/_/Applications/nochange.app/embedded.mobileprovision new file mode 100644 index 0000000..e1e9918 Binary files /dev/null and b/.theos/_/Applications/nochange.app/embedded.mobileprovision differ diff --git a/.theos/_/DEBIAN/control b/.theos/_/DEBIAN/control new file mode 100644 index 0000000..df27ef5 --- /dev/null +++ b/.theos/_/DEBIAN/control @@ -0,0 +1,10 @@ +Package: com.xyzshell.ioscontrol +Name: XYZShell iOS Control +Description: XYZShell iOS Control Main Application +Maintainer: XYZShell +Author: XYZShell +Section: Utilities +Tag: role::developer +Architecture: iphoneos-arm +Version: 0.0.7-10-2+debug +Installed-Size: 1680 diff --git a/.theos/_/DEBIAN/postinst b/.theos/_/DEBIAN/postinst new file mode 100755 index 0000000..97e8790 --- /dev/null +++ b/.theos/_/DEBIAN/postinst @@ -0,0 +1,2 @@ +#!/bin/sh +uicache --path /Applications/nochange.app diff --git a/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.dylib b/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.dylib new file mode 100755 index 0000000..38042e6 Binary files /dev/null and b/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.dylib differ diff --git a/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.plist b/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.plist new file mode 100644 index 0000000..10dc654 --- /dev/null +++ b/.theos/_/Library/MobileSubstrate/DynamicLibraries/AppRunMan.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.springboard" ); }; } diff --git a/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.dylib b/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.dylib new file mode 100755 index 0000000..158d1c3 Binary files /dev/null and b/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.dylib differ diff --git a/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.plist b/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.plist new file mode 100644 index 0000000..e5c60ee --- /dev/null +++ b/.theos/_/Library/MobileSubstrate/DynamicLibraries/OhNo.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.UIKit" ); }; } diff --git a/.theos/build_session b/.theos/build_session new file mode 100644 index 0000000..e69de29 diff --git a/.theos/fakeroot b/.theos/fakeroot new file mode 100644 index 0000000..e69de29 diff --git a/.theos/last_package b/.theos/last_package new file mode 100644 index 0000000..0562a85 --- /dev/null +++ b/.theos/last_package @@ -0,0 +1 @@ +./packages/com.xyzshell.ioscontrol_0.0.7-10-2+debug_iphoneos-arm.deb diff --git a/.theos/obj/debug/.stamp b/.theos/obj/debug/.stamp new file mode 100644 index 0000000..e69de29 diff --git a/.theos/obj/debug/AppRunMan.dylib b/.theos/obj/debug/AppRunMan.dylib new file mode 100755 index 0000000..38042e6 Binary files /dev/null and b/.theos/obj/debug/AppRunMan.dylib differ diff --git a/.theos/obj/debug/OhNo.dylib b/.theos/obj/debug/OhNo.dylib new file mode 100755 index 0000000..158d1c3 Binary files /dev/null and b/.theos/obj/debug/OhNo.dylib differ diff --git a/.theos/obj/debug/arm64/AppRunMan.dylib b/.theos/obj/debug/arm64/AppRunMan.dylib new file mode 100755 index 0000000..a832a39 Binary files /dev/null and b/.theos/obj/debug/arm64/AppRunMan.dylib differ diff --git a/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Info.plist b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Info.plist new file mode 100644 index 0000000..80e915b --- /dev/null +++ b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.AppRunMan.dylib + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib new file mode 100644 index 0000000..df3d81c Binary files /dev/null and b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib differ diff --git a/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/aarch64/AppRunMan.dylib.yml b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/aarch64/AppRunMan.dylib.yml new file mode 100644 index 0000000..02eb725 --- /dev/null +++ b/.theos/obj/debug/arm64/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/aarch64/AppRunMan.dylib.yml @@ -0,0 +1,1041 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: '/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/AppRunMan.dylib' +relocations: + - { offset: 0x1E, size: 0x8, addend: 0x0, symName: '-[UIWindow(FloatingWindow) addFloatingWindow]', symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x10C } + - { offset: 0x37, size: 0x8, addend: 0x0, symName: _kSBAppTagsHidden, symObjAddr: 0x7F0, symBinAddr: 0x58180, symSize: 0x0 } + - { offset: 0xBD, size: 0x8, addend: 0x0, symName: '__logos_orig$all$SpringBoard$applicationDidFinishLaunching$', symObjAddr: 0x7220, symBinAddr: 0x694E0, symSize: 0x0 } + - { offset: 0x1F98, size: 0x8, addend: 0x0, symName: '__logos_orig$all$SpringBoard$applicationWillTerminate$', symObjAddr: 0x7228, symBinAddr: 0x694E8, symSize: 0x0 } + - { offset: 0x1FA7, size: 0x8, addend: 0x0, symName: '-[UIWindow(FloatingWindow) addFloatingWindow]', symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x10C } + - { offset: 0x1FE7, size: 0x8, addend: 0x0, symName: __logosLocalCtor_a83cb02a, symObjAddr: 0x10C, symBinAddr: 0x410C, symSize: 0x80 } + - { offset: 0x2060, size: 0x8, addend: 0x0, symName: '__logos_method$all$SpringBoard$applicationDidFinishLaunching$', symObjAddr: 0x18C, symBinAddr: 0x418C, symSize: 0x128 } + - { offset: 0x20C8, size: 0x8, addend: 0x0, symName: '__logos_method$all$SpringBoard$applicationWillTerminate$', symObjAddr: 0x2B4, symBinAddr: 0x42B4, symSize: 0x64 } + - { offset: 0x2108, size: 0x8, addend: 0x0, symName: '____logos_method$all$SpringBoard$applicationDidFinishLaunching$_block_invoke', symObjAddr: 0x318, symBinAddr: 0x4318, symSize: 0x28 } + - { offset: 0x2130, size: 0x8, addend: 0x0, symName: '____logos_method$all$SpringBoard$applicationDidFinishLaunching$_block_invoke_2', symObjAddr: 0x340, symBinAddr: 0x4340, symSize: 0x378 } + - { offset: 0x2322, size: 0x8, addend: 0x0, symName: '-[FloatingWindow initWithFrame]', symObjAddr: 0x0, symBinAddr: 0x46B8, symSize: 0x2B8 } + - { offset: 0x74E3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow initWithFrame]', symObjAddr: 0x0, symBinAddr: 0x46B8, symSize: 0x2B8 } + - { offset: 0x7585, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x2B8, symBinAddr: 0x4970, symSize: 0x4C } + - { offset: 0x75EB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow dealloc]', symObjAddr: 0x304, symBinAddr: 0x49BC, symSize: 0x7C } + - { offset: 0x761D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setupUI]', symObjAddr: 0x380, symBinAddr: 0x4A38, symSize: 0xAB0 } + - { offset: 0x765E, size: 0x8, addend: 0x0, symName: '-[FloatingWindow updateInfo]', symObjAddr: 0xE30, symBinAddr: 0x54E8, symSize: 0x1FC } + - { offset: 0x76B6, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateStatus:]', symObjAddr: 0x102C, symBinAddr: 0x56E4, symSize: 0x11C } + - { offset: 0x7718, size: 0x8, addend: 0x0, symName: '___38-[FloatingWindow onEventUpdateStatus:]_block_invoke', symObjAddr: 0x1148, symBinAddr: 0x5800, symSize: 0xC0 } + - { offset: 0x7762, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40w, symObjAddr: 0x1208, symBinAddr: 0x58C0, symSize: 0x54 } + - { offset: 0x7786, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40w, symObjAddr: 0x125C, symBinAddr: 0x5914, symSize: 0x3C } + - { offset: 0x77A2, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateRunStatus:]', symObjAddr: 0x1298, symBinAddr: 0x5950, symSize: 0x11C } + - { offset: 0x7804, size: 0x8, addend: 0x0, symName: '___41-[FloatingWindow onEventUpdateRunStatus:]_block_invoke', symObjAddr: 0x13B4, symBinAddr: 0x5A6C, symSize: 0x12C } + - { offset: 0x786A, size: 0x8, addend: 0x0, symName: '-[FloatingWindow showMyToast:]', symObjAddr: 0x14E0, symBinAddr: 0x5B98, symSize: 0x11C } + - { offset: 0x78CC, size: 0x8, addend: 0x0, symName: '___30-[FloatingWindow showMyToast:]_block_invoke', symObjAddr: 0x15FC, symBinAddr: 0x5CB4, symSize: 0x58 } + - { offset: 0x7916, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateName:]', symObjAddr: 0x1654, symBinAddr: 0x5D0C, symSize: 0xF0 } + - { offset: 0x7978, size: 0x8, addend: 0x0, symName: '___36-[FloatingWindow onEventUpdateName:]_block_invoke', symObjAddr: 0x1744, symBinAddr: 0x5DFC, symSize: 0x114 } + - { offset: 0x79CD, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32w, symObjAddr: 0x1858, symBinAddr: 0x5F10, symSize: 0x34 } + - { offset: 0x79F1, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32w, symObjAddr: 0x188C, symBinAddr: 0x5F44, symSize: 0x28 } + - { offset: 0x7A0D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow actionButtonTapped:]', symObjAddr: 0x18B4, symBinAddr: 0x5F6C, symSize: 0xB0 } + - { offset: 0x7A69, size: 0x8, addend: 0x0, symName: '-[FloatingWindow settingsButtonTapped]', symObjAddr: 0x1964, symBinAddr: 0x601C, symSize: 0x38 } + - { offset: 0x7A9B, size: 0x8, addend: 0x0, symName: '-[FloatingWindow changeBackgroundColor]', symObjAddr: 0x199C, symBinAddr: 0x6054, symSize: 0xD0 } + - { offset: 0x7AFB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow appendLog:]', symObjAddr: 0x1A6C, symBinAddr: 0x6124, symSize: 0x278 } + - { offset: 0x7B85, size: 0x8, addend: 0x0, symName: '-[FloatingWindow detectPan:]', symObjAddr: 0x1CE4, symBinAddr: 0x639C, symSize: 0x124 } + - { offset: 0x7BE1, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x1E08, symBinAddr: 0x64C0, symSize: 0x2C } + - { offset: 0x7C29, size: 0x8, addend: 0x0, symName: '-[FloatingWindow nameLabel]', symObjAddr: 0x1E34, symBinAddr: 0x64EC, symSize: 0x24 } + - { offset: 0x7C5F, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setNameLabel:]', symObjAddr: 0x1E58, symBinAddr: 0x6510, symSize: 0x3C } + - { offset: 0x7C9D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow ipLabel]', symObjAddr: 0x1E94, symBinAddr: 0x654C, symSize: 0x24 } + - { offset: 0x7CD3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setIpLabel:]', symObjAddr: 0x1EB8, symBinAddr: 0x6570, symSize: 0x3C } + - { offset: 0x7D11, size: 0x8, addend: 0x0, symName: '-[FloatingWindow deviceTypeLabel]', symObjAddr: 0x1EF4, symBinAddr: 0x65AC, symSize: 0x24 } + - { offset: 0x7D47, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setDeviceTypeLabel:]', symObjAddr: 0x1F18, symBinAddr: 0x65D0, symSize: 0x3C } + - { offset: 0x7D85, size: 0x8, addend: 0x0, symName: '-[FloatingWindow actionButton]', symObjAddr: 0x1F54, symBinAddr: 0x660C, symSize: 0x24 } + - { offset: 0x7DBB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setActionButton:]', symObjAddr: 0x1F78, symBinAddr: 0x6630, symSize: 0x3C } + - { offset: 0x7DF9, size: 0x8, addend: 0x0, symName: '-[FloatingWindow settingsButton]', symObjAddr: 0x1FB4, symBinAddr: 0x666C, symSize: 0x24 } + - { offset: 0x7E2F, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setSettingsButton:]', symObjAddr: 0x1FD8, symBinAddr: 0x6690, symSize: 0x3C } + - { offset: 0x7E6D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow logTextView]', symObjAddr: 0x2014, symBinAddr: 0x66CC, symSize: 0x24 } + - { offset: 0x7EA3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setLogTextView:]', symObjAddr: 0x2038, symBinAddr: 0x66F0, symSize: 0x3C } + - { offset: 0x7EE1, size: 0x8, addend: 0x0, symName: '-[FloatingWindow http]', symObjAddr: 0x2074, symBinAddr: 0x672C, symSize: 0x24 } + - { offset: 0x7F17, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setHttp:]', symObjAddr: 0x2098, symBinAddr: 0x6750, symSize: 0x3C } + - { offset: 0x7F55, size: 0x8, addend: 0x0, symName: '-[FloatingWindow dataTask]', symObjAddr: 0x20D4, symBinAddr: 0x678C, symSize: 0x24 } + - { offset: 0x7F8B, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setDataTask:]', symObjAddr: 0x20F8, symBinAddr: 0x67B0, symSize: 0x3C } + - { offset: 0x7FC9, size: 0x8, addend: 0x0, symName: '-[FloatingWindow .cxx_destruct]', symObjAddr: 0x2134, symBinAddr: 0x67EC, symSize: 0xE8 } + - { offset: 0x8245, size: 0x8, addend: 0x0, symName: '+[IosSystemCmd sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x68D4, symSize: 0xB0 } + - { offset: 0x8252, size: 0x8, addend: 0x0, symName: '+[IosSystemCmd sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x68D4, symSize: 0xB0 } + - { offset: 0x827B, size: 0x8, addend: 0x0, symName: _sharedInstance.sharedInstance, symObjAddr: 0xABD0, symBinAddr: 0x694F0, symSize: 0x0 } + - { offset: 0x8290, size: 0x8, addend: 0x0, symName: _sharedInstance.onceToken, symObjAddr: 0xABD8, symBinAddr: 0x694F8, symSize: 0x0 } + - { offset: 0x903C, size: 0x8, addend: 0x0, symName: '___30+[IosSystemCmd sharedInstance]_block_invoke', symObjAddr: 0xB0, symBinAddr: 0x6984, symSize: 0x4C } + - { offset: 0x9079, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd init]', symObjAddr: 0xFC, symBinAddr: 0x69D0, symSize: 0x100 } + - { offset: 0x90AF, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd cmdUrl]', symObjAddr: 0x1FC, symBinAddr: 0x6AD0, symSize: 0x98 } + - { offset: 0x90E5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd cmdResUrl]', symObjAddr: 0x294, symBinAddr: 0x6B68, symSize: 0x98 } + - { offset: 0x911B, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd start]', symObjAddr: 0x32C, symBinAddr: 0x6C00, symSize: 0x160 } + - { offset: 0x915B, size: 0x8, addend: 0x0, symName: '___21-[IosSystemCmd start]_block_invoke', symObjAddr: 0x48C, symBinAddr: 0x6D60, symSize: 0x60 } + - { offset: 0x9194, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd runTask]', symObjAddr: 0x548, symBinAddr: 0x6DC0, symSize: 0x358 } + - { offset: 0x9213, size: 0x8, addend: 0x0, symName: '___23-[IosSystemCmd runTask]_block_invoke', symObjAddr: 0x8A0, symBinAddr: 0x7118, symSize: 0x228 } + - { offset: 0x9282, size: 0x8, addend: 0x0, symName: '___23-[IosSystemCmd runTask]_block_invoke.26', symObjAddr: 0xAC8, symBinAddr: 0x7340, symSize: 0x64 } + - { offset: 0x92B8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeTask:]', symObjAddr: 0xB2C, symBinAddr: 0x73A4, symSize: 0x650 } + - { offset: 0x931A, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd putTask:error:data:]', symObjAddr: 0x117C, symBinAddr: 0x79F4, symSize: 0x1C4 } + - { offset: 0x9389, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd putTask:error:data:]_block_invoke', symObjAddr: 0x1340, symBinAddr: 0x7BB8, symSize: 0x94 } + - { offset: 0x93BF, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd putTask:error:data:]_block_invoke_2', symObjAddr: 0x13D4, symBinAddr: 0x7C4C, symSize: 0x64 } + - { offset: 0x93F5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeEditName:data:]', symObjAddr: 0x1438, symBinAddr: 0x7CB0, symSize: 0x144 } + - { offset: 0x9465, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUploadApps:data:]', symObjAddr: 0x157C, symBinAddr: 0x7DF4, symSize: 0x130 } + - { offset: 0x94CF, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeStart:data:]', symObjAddr: 0x16AC, symBinAddr: 0x7F24, symSize: 0x138 } + - { offset: 0x951D, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeStop:data:]', symObjAddr: 0x17E4, symBinAddr: 0x805C, symSize: 0x138 } + - { offset: 0x9583, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeScreenshot:data:]', symObjAddr: 0x191C, symBinAddr: 0x8194, symSize: 0x168 } + - { offset: 0x95E5, size: 0x8, addend: 0x0, symName: '___39-[IosSystemCmd executeScreenshot:data:]_block_invoke', symObjAddr: 0x1A84, symBinAddr: 0x82FC, symSize: 0xEC } + - { offset: 0x966E, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s, symObjAddr: 0x1B70, symBinAddr: 0x83E8, symSize: 0x70 } + - { offset: 0x9692, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s, symObjAddr: 0x1BE0, symBinAddr: 0x8458, symSize: 0x54 } + - { offset: 0x96AE, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUnlock:data:]', symObjAddr: 0x1C34, symBinAddr: 0x84AC, symSize: 0xA4 } + - { offset: 0x9710, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd executeUnlock:data:]_block_invoke', symObjAddr: 0x1CD8, symBinAddr: 0x8550, symSize: 0x28 } + - { offset: 0x9738, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeRestart:data:]', symObjAddr: 0x1D00, symBinAddr: 0x8578, symSize: 0xA4 } + - { offset: 0x979E, size: 0x8, addend: 0x0, symName: '___36-[IosSystemCmd executeRestart:data:]_block_invoke', symObjAddr: 0x1DA4, symBinAddr: 0x861C, symSize: 0x30 } + - { offset: 0x97C8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeReboot:data:]', symObjAddr: 0x1DD4, symBinAddr: 0x864C, symSize: 0xA4 } + - { offset: 0x982E, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd executeReboot:data:]_block_invoke', symObjAddr: 0x1E78, symBinAddr: 0x86F0, symSize: 0x28 } + - { offset: 0x9858, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeTouch:data:]', symObjAddr: 0x1EA0, symBinAddr: 0x8718, symSize: 0x110 } + - { offset: 0x98BE, size: 0x8, addend: 0x0, symName: '___34-[IosSystemCmd executeTouch:data:]_block_invoke', symObjAddr: 0x1FB0, symBinAddr: 0x8828, symSize: 0x29C } + - { offset: 0x9954, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s, symObjAddr: 0x224C, symBinAddr: 0x8AC4, symSize: 0x38 } + - { offset: 0x9978, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s, symObjAddr: 0x2284, symBinAddr: 0x8AFC, symSize: 0x2C } + - { offset: 0x9994, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUpdateKey:data:]', symObjAddr: 0x22B0, symBinAddr: 0x8B28, symSize: 0xA8 } + - { offset: 0x99E5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeKey:data:]', symObjAddr: 0x2358, symBinAddr: 0x8BD0, symSize: 0x110 } + - { offset: 0x9A4B, size: 0x8, addend: 0x0, symName: '___32-[IosSystemCmd executeKey:data:]_block_invoke', symObjAddr: 0x2468, symBinAddr: 0x8CE0, symSize: 0x26C } + - { offset: 0x9AD1, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd getMyApps]', symObjAddr: 0x26D4, symBinAddr: 0x8F4C, symSize: 0x104 } + - { offset: 0x9B26, size: 0x8, addend: 0x0, symName: '___25-[IosSystemCmd getMyApps]_block_invoke', symObjAddr: 0x27D8, symBinAddr: 0x9050, symSize: 0x4C4 } + - { offset: 0x9BE8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd stop]', symObjAddr: 0x2C9C, symBinAddr: 0x9514, symSize: 0x50 } + - { offset: 0x9C1B, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd dealloc]', symObjAddr: 0x2CEC, symBinAddr: 0x9564, symSize: 0x50 } + - { offset: 0x9C4E, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd .cxx_destruct]', symObjAddr: 0x2D3C, symBinAddr: 0x95B4, symSize: 0x68 } + - { offset: 0xA8AE, size: 0x8, addend: 0x0, symName: '+[IPhoneHertbeat sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x961C, symSize: 0x7C } + - { offset: 0xA8BB, size: 0x8, addend: 0x0, symName: '+[IPhoneHertbeat sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x961C, symSize: 0x7C } + - { offset: 0xA8E4, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x9328, symBinAddr: 0x69500, symSize: 0x0 } + - { offset: 0xA8F9, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x9330, symBinAddr: 0x69508, symSize: 0x0 } + - { offset: 0xB596, size: 0x8, addend: 0x0, symName: '___32+[IPhoneHertbeat sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0x9698, symSize: 0x4C } + - { offset: 0xB5BE, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat init]', symObjAddr: 0xC8, symBinAddr: 0x96E4, symSize: 0x16C } + - { offset: 0xB5F4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat stop]', symObjAddr: 0x234, symBinAddr: 0x9850, symSize: 0x50 } + - { offset: 0xB626, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat dealloc]', symObjAddr: 0x284, symBinAddr: 0x98A0, symSize: 0x5C } + - { offset: 0xB658, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat start]', symObjAddr: 0x2E0, symBinAddr: 0x98FC, symSize: 0x164 } + - { offset: 0xB698, size: 0x8, addend: 0x0, symName: '___23-[IPhoneHertbeat start]_block_invoke', symObjAddr: 0x444, symBinAddr: 0x9A60, symSize: 0x60 } + - { offset: 0xB6D1, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat checkxxx]', symObjAddr: 0x500, symBinAddr: 0x9AC0, symSize: 0x174 } + - { offset: 0xB767, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat ping]', symObjAddr: 0x674, symBinAddr: 0x9C34, symSize: 0x708 } + - { offset: 0xB820, size: 0x8, addend: 0x0, symName: '___22-[IPhoneHertbeat ping]_block_invoke', symObjAddr: 0xD7C, symBinAddr: 0xA33C, symSize: 0x54 } + - { offset: 0xB848, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat sendHeartbeat:toURL:]', symObjAddr: 0xDD0, symBinAddr: 0xA390, symSize: 0xD8 } + - { offset: 0xB896, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat sendHeartbeat:toURL:]_block_invoke', symObjAddr: 0xEA8, symBinAddr: 0xA468, symSize: 0xA4 } + - { offset: 0xB8CC, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat sendHeartbeat:toURL:]_block_invoke_2', symObjAddr: 0xF4C, symBinAddr: 0xA50C, symSize: 0x64 } + - { offset: 0xB902, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat constructHeartbeatData]', symObjAddr: 0xFB0, symBinAddr: 0xA570, symSize: 0x580 } + - { offset: 0xB957, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat checkAndPerformTasks]', symObjAddr: 0x1530, symBinAddr: 0xAAF0, symSize: 0x148 } + - { offset: 0xB9A5, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat checkAndPerformTasks]_block_invoke', symObjAddr: 0x1678, symBinAddr: 0xAC38, symSize: 0xD0 } + - { offset: 0xB9F2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat safePerformTouchEvents]', symObjAddr: 0x1748, symBinAddr: 0xAD08, symSize: 0x1CC } + - { offset: 0xBA66, size: 0x8, addend: 0x0, symName: '___40-[IPhoneHertbeat safePerformTouchEvents]_block_invoke', symObjAddr: 0x1914, symBinAddr: 0xAED4, symSize: 0x2B4 } + - { offset: 0xBAF4, size: 0x8, addend: 0x0, symName: '___40-[IPhoneHertbeat safePerformTouchEvents]_block_invoke_2', symObjAddr: 0x1BC8, symBinAddr: 0xB188, symSize: 0x318 } + - { offset: 0xBB83, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat cleanup]', symObjAddr: 0x1F70, symBinAddr: 0xB4A0, symSize: 0x44 } + - { offset: 0xBBB6, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat cancelCurrentTask]', symObjAddr: 0x1FB4, symBinAddr: 0xB4E4, symSize: 0x9C } + - { offset: 0xBBE9, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat reset]', symObjAddr: 0x2050, symBinAddr: 0xB580, symSize: 0x38 } + - { offset: 0xBC1C, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat name]', symObjAddr: 0x2088, symBinAddr: 0xB5B8, symSize: 0x1C } + - { offset: 0xBC52, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setName:]', symObjAddr: 0x20A4, symBinAddr: 0xB5D4, symSize: 0x34 } + - { offset: 0xBC90, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat deviceId]', symObjAddr: 0x20D8, symBinAddr: 0xB608, symSize: 0x1C } + - { offset: 0xBCC6, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setDeviceId:]', symObjAddr: 0x20F4, symBinAddr: 0xB624, symSize: 0x34 } + - { offset: 0xBD04, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat ip]', symObjAddr: 0x2128, symBinAddr: 0xB658, symSize: 0x1C } + - { offset: 0xBD3A, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setIp:]', symObjAddr: 0x2144, symBinAddr: 0xB674, symSize: 0x34 } + - { offset: 0xBD78, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat appId]', symObjAddr: 0x2178, symBinAddr: 0xB6A8, symSize: 0x1C } + - { offset: 0xBDAE, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setAppId:]', symObjAddr: 0x2194, symBinAddr: 0xB6C4, symSize: 0x34 } + - { offset: 0xBDEC, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat apps]', symObjAddr: 0x21C8, symBinAddr: 0xB6F8, symSize: 0x1C } + - { offset: 0xBE22, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setApps:]', symObjAddr: 0x21E4, symBinAddr: 0xB714, symSize: 0x34 } + - { offset: 0xBE60, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat message]', symObjAddr: 0x2218, symBinAddr: 0xB748, symSize: 0x1C } + - { offset: 0xBE96, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setMessage:]', symObjAddr: 0x2234, symBinAddr: 0xB764, symSize: 0x34 } + - { offset: 0xBED4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat status]', symObjAddr: 0x2268, symBinAddr: 0xB798, symSize: 0x1C } + - { offset: 0xBF0A, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setStatus:]', symObjAddr: 0x2284, symBinAddr: 0xB7B4, symSize: 0x34 } + - { offset: 0xBF48, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat diskSize]', symObjAddr: 0x22B8, symBinAddr: 0xB7E8, symSize: 0x1C } + - { offset: 0xBF7E, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setDiskSize:]', symObjAddr: 0x22D4, symBinAddr: 0xB804, symSize: 0x34 } + - { offset: 0xBFBC, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat remoteIp]', symObjAddr: 0x2308, symBinAddr: 0xB838, symSize: 0x1C } + - { offset: 0xBFF2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setRemoteIp:]', symObjAddr: 0x2324, symBinAddr: 0xB854, symSize: 0x34 } + - { offset: 0xC030, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat lastTouchTime]', symObjAddr: 0x2358, symBinAddr: 0xB888, symSize: 0x1C } + - { offset: 0xC066, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setLastTouchTime:]', symObjAddr: 0x2374, symBinAddr: 0xB8A4, symSize: 0x24 } + - { offset: 0xC0A4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat isProcessingTouch]', symObjAddr: 0x2398, symBinAddr: 0xB8C8, symSize: 0x20 } + - { offset: 0xC0DA, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setIsProcessingTouch:]', symObjAddr: 0x23B8, symBinAddr: 0xB8E8, symSize: 0x28 } + - { offset: 0xC118, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat touchQueue]', symObjAddr: 0x23E0, symBinAddr: 0xB910, symSize: 0x1C } + - { offset: 0xC14E, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setTouchQueue:]', symObjAddr: 0x23FC, symBinAddr: 0xB92C, symSize: 0x34 } + - { offset: 0xC18C, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat lastCheckTaskTime]', symObjAddr: 0x2430, symBinAddr: 0xB960, symSize: 0x1C } + - { offset: 0xC1C2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setLastCheckTaskTime:]', symObjAddr: 0x244C, symBinAddr: 0xB97C, symSize: 0x24 } + - { offset: 0xC200, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat touchTimer]', symObjAddr: 0x2470, symBinAddr: 0xB9A0, symSize: 0x1C } + - { offset: 0xC236, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setTouchTimer:]', symObjAddr: 0x248C, symBinAddr: 0xB9BC, symSize: 0x34 } + - { offset: 0xC274, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat .cxx_destruct]', symObjAddr: 0x24C0, symBinAddr: 0xB9F0, symSize: 0x128 } + - { offset: 0xC6DF, size: 0x8, addend: 0x0, symName: _pushAdTaskLog, symObjAddr: 0x0, symBinAddr: 0xBB18, symSize: 0x248 } + - { offset: 0xC88C, size: 0x8, addend: 0x0, symName: _pushAdTaskLog, symObjAddr: 0x0, symBinAddr: 0xBB18, symSize: 0x248 } + - { offset: 0xC8C0, size: 0x8, addend: 0x0, symName: _saveAdTaskLog, symObjAddr: 0x248, symBinAddr: 0xBD60, symSize: 0x120 } + - { offset: 0xC91C, size: 0x8, addend: 0x0, symName: ___saveAdTaskLog_block_invoke, symObjAddr: 0x368, symBinAddr: 0xBE80, symSize: 0x90 } + - { offset: 0xC952, size: 0x8, addend: 0x0, symName: ___saveAdTaskLog_block_invoke_2, symObjAddr: 0x3F8, symBinAddr: 0xBF10, symSize: 0x64 } + - { offset: 0xC988, size: 0x8, addend: 0x0, symName: _getLowEcpm, symObjAddr: 0x45C, symBinAddr: 0xBF74, symSize: 0x250 } + - { offset: 0xC9E4, size: 0x8, addend: 0x0, symName: ___getLowEcpm_block_invoke, symObjAddr: 0x6AC, symBinAddr: 0xC1C4, symSize: 0x1FC } + - { offset: 0xCA4D, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b, symObjAddr: 0x8A8, symBinAddr: 0xC3C0, symSize: 0x38 } + - { offset: 0xCA71, size: 0x8, addend: 0x0, symName: ___getLowEcpm_block_invoke.42, symObjAddr: 0x90C, symBinAddr: 0xC3F8, symSize: 0x9C } + - { offset: 0xCAB8, size: 0x8, addend: 0x0, symName: _needAdContinue, symObjAddr: 0x9A8, symBinAddr: 0xC494, symSize: 0x3FC } + - { offset: 0xCB59, size: 0x8, addend: 0x0, symName: _getChangeInfo, symObjAddr: 0xDA4, symBinAddr: 0xC890, symSize: 0x2E0 } + - { offset: 0xCBC3, size: 0x8, addend: 0x0, symName: ___getChangeInfo_block_invoke, symObjAddr: 0x1084, symBinAddr: 0xCB70, symSize: 0x244 } + - { offset: 0xCC4B, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b40b, symObjAddr: 0x12C8, symBinAddr: 0xCDB4, symSize: 0x5C } + - { offset: 0xCC6F, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s, symObjAddr: 0x1324, symBinAddr: 0xCE10, symSize: 0x44 } + - { offset: 0xCC8B, size: 0x8, addend: 0x0, symName: ___getChangeInfo_block_invoke.56, symObjAddr: 0x1368, symBinAddr: 0xCE54, symSize: 0x80 } + - { offset: 0xCCD2, size: 0x8, addend: 0x0, symName: __newgetChangeInfo, symObjAddr: 0x13E8, symBinAddr: 0xCED4, symSize: 0x2E0 } + - { offset: 0xCD3C, size: 0x8, addend: 0x0, symName: ____newgetChangeInfo_block_invoke, symObjAddr: 0x16C8, symBinAddr: 0xD1B4, symSize: 0x318 } + - { offset: 0xCDE1, size: 0x8, addend: 0x0, symName: ____newgetChangeInfo_block_invoke_2, symObjAddr: 0x19E0, symBinAddr: 0xD4CC, symSize: 0x80 } + - { offset: 0xCE28, size: 0x8, addend: 0x0, symName: _saveChangeDataFile, symObjAddr: 0x1A60, symBinAddr: 0xD54C, symSize: 0x4A4 } + - { offset: 0xCED1, size: 0x8, addend: 0x0, symName: ___saveChangeDataFile_block_invoke, symObjAddr: 0x1F04, symBinAddr: 0xD9F0, symSize: 0x234 } + - { offset: 0xCF48, size: 0x8, addend: 0x0, symName: ___saveChangeDataFile_block_invoke_2, symObjAddr: 0x2138, symBinAddr: 0xDC24, symSize: 0x120 } + - { offset: 0xCFAB, size: 0x8, addend: 0x0, symName: _getAdLoadInfo, symObjAddr: 0x2290, symBinAddr: 0xDD44, symSize: 0xD84 } + - { offset: 0xD05D, size: 0x8, addend: 0x0, symName: ___destructor_8_s0_s8_s16_s24_s32_s40, symObjAddr: 0x3014, symBinAddr: 0xEAC8, symSize: 0x80 } + - { offset: 0xD07D, size: 0x8, addend: 0x0, symName: _pushInfo, symObjAddr: 0x3094, symBinAddr: 0xEB48, symSize: 0x2E8 } + - { offset: 0xD123, size: 0x8, addend: 0x0, symName: ___pushInfo_block_invoke, symObjAddr: 0x337C, symBinAddr: 0xEE30, symSize: 0x28C } + - { offset: 0xD1AF, size: 0x8, addend: 0x0, symName: _pushIphoneLog, symObjAddr: 0x3608, symBinAddr: 0xF0BC, symSize: 0x39C } + - { offset: 0xD256, size: 0x8, addend: 0x0, symName: ___pushIphoneLog_block_invoke, symObjAddr: 0x39A4, symBinAddr: 0xF458, symSize: 0x98 } + - { offset: 0xD2AC, size: 0x8, addend: 0x0, symName: ___pushIphoneLog_block_invoke_2, symObjAddr: 0x3A3C, symBinAddr: 0xF4F0, symSize: 0x64 } + - { offset: 0xD2E5, size: 0x8, addend: 0x0, symName: _logMessage, symObjAddr: 0x3AA0, symBinAddr: 0xF554, symSize: 0x260 } + - { offset: 0xD373, size: 0x8, addend: 0x0, symName: _uncaughtExceptionHandler, symObjAddr: 0x3D00, symBinAddr: 0xF7B4, symSize: 0x1D4 } + - { offset: 0xD3E4, size: 0x8, addend: 0x0, symName: _signalHandler, symObjAddr: 0x3ED4, symBinAddr: 0xF988, symSize: 0x150 } + - { offset: 0xD465, size: 0x8, addend: 0x0, symName: _registerSignalHandler, symObjAddr: 0x4024, symBinAddr: 0xFAD8, symSize: 0x74 } + - { offset: 0xEA2C, size: 0x8, addend: 0x0, symName: '+[MyAdTask2Mangger sharedInstance]', symObjAddr: 0x0, symBinAddr: 0xFB4C, symSize: 0x7C } + - { offset: 0xEA45, size: 0x8, addend: 0x0, symName: _myadTaskManualStop, symObjAddr: 0xC8B5, symBinAddr: 0x69610, symSize: 0x0 } + - { offset: 0xEA60, size: 0x8, addend: 0x0, symName: '+[MyAdTask2Mangger sharedInstance]', symObjAddr: 0x0, symBinAddr: 0xFB4C, symSize: 0x7C } + - { offset: 0xEA89, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xC8B8, symBinAddr: 0x69510, symSize: 0x0 } + - { offset: 0xEA9E, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xC8C0, symBinAddr: 0x69518, symSize: 0x0 } + - { offset: 0xEE16, size: 0x8, addend: 0x0, symName: '___34+[MyAdTask2Mangger sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0xFBC8, symSize: 0x4C } + - { offset: 0xEE3E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger init]', symObjAddr: 0xC8, symBinAddr: 0xFC14, symSize: 0x228 } + - { offset: 0xEEAD, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onShow:]', symObjAddr: 0x2F0, symBinAddr: 0xFE3C, symSize: 0x6CC } + - { offset: 0xEFA8, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger showStatus:]', symObjAddr: 0xA3C, symBinAddr: 0x10508, symSize: 0x8C } + - { offset: 0xEFE8, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setRemoteInfo]', symObjAddr: 0xAC8, symBinAddr: 0x10594, symSize: 0x184 } + - { offset: 0xF044, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger setRemoteInfo]_block_invoke', symObjAddr: 0xC4C, symBinAddr: 0x10718, symSize: 0x314 } + - { offset: 0xF0D1, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger setRemoteInfo]_block_invoke.47', symObjAddr: 0xFBC, symBinAddr: 0x10A2C, symSize: 0x104 } + - { offset: 0xF118, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setRemoteInfo1]', symObjAddr: 0x10C0, symBinAddr: 0x10B30, symSize: 0x20C } + - { offset: 0xF174, size: 0x8, addend: 0x0, symName: '___34-[MyAdTask2Mangger setRemoteInfo1]_block_invoke', symObjAddr: 0x12CC, symBinAddr: 0x10D3C, symSize: 0x3B8 } + - { offset: 0xF212, size: 0x8, addend: 0x0, symName: '___34-[MyAdTask2Mangger setRemoteInfo1]_block_invoke_2', symObjAddr: 0x1684, symBinAddr: 0x110F4, symSize: 0x104 } + - { offset: 0xF259, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onEnd:]', symObjAddr: 0x1788, symBinAddr: 0x111F8, symSize: 0x2E0 } + - { offset: 0xF2D7, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger onEnd:]_block_invoke', symObjAddr: 0x1A68, symBinAddr: 0x114D8, symSize: 0x60 } + - { offset: 0xF310, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger onEnd:]_block_invoke.63', symObjAddr: 0x1AC8, symBinAddr: 0x11538, symSize: 0x60 } + - { offset: 0xF349, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger startApp]', symObjAddr: 0x1B28, symBinAddr: 0x11598, symSize: 0x274 } + - { offset: 0xF3BC, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke', symObjAddr: 0x1D9C, symBinAddr: 0x1180C, symSize: 0x118 } + - { offset: 0xF407, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke_2', symObjAddr: 0x1EB4, symBinAddr: 0x11924, symSize: 0x58 } + - { offset: 0xF455, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke.66', symObjAddr: 0x1F9C, symBinAddr: 0x1197C, symSize: 0x64 } + - { offset: 0xF48E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger start]', symObjAddr: 0x2000, symBinAddr: 0x119E0, symSize: 0x270 } + - { offset: 0xF4D0, size: 0x8, addend: 0x0, symName: '___25-[MyAdTask2Mangger start]_block_invoke', symObjAddr: 0x2270, symBinAddr: 0x11C50, symSize: 0x60 } + - { offset: 0xF50C, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger proc]', symObjAddr: 0x22D0, symBinAddr: 0x11CB0, symSize: 0x120 } + - { offset: 0xF57A, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger toggle]', symObjAddr: 0x23F0, symBinAddr: 0x11DD0, symSize: 0x98 } + - { offset: 0xF5B1, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger stop]', symObjAddr: 0x2488, symBinAddr: 0x11E68, symSize: 0x118 } + - { offset: 0xF5E4, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onChangeInfo:]', symObjAddr: 0x25A0, symBinAddr: 0x11F80, symSize: 0x53C } + - { offset: 0xF694, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger onChangeInfo:]_block_invoke', symObjAddr: 0x2ADC, symBinAddr: 0x124BC, symSize: 0x64 } + - { offset: 0xF6E6, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s, symObjAddr: 0x2B40, symBinAddr: 0x12520, symSize: 0x58 } + - { offset: 0xF70A, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger appKill:]', symObjAddr: 0x2BDC, symBinAddr: 0x12578, symSize: 0x60 } + - { offset: 0xF764, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger unlock]', symObjAddr: 0x2C3C, symBinAddr: 0x125D8, symSize: 0x68 } + - { offset: 0xF7AC, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger unlock]_block_invoke', symObjAddr: 0x2CA4, symBinAddr: 0x12640, symSize: 0x28 } + - { offset: 0xF7D6, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger resetApp:callback:]', symObjAddr: 0x2CCC, symBinAddr: 0x12668, symSize: 0x354 } + - { offset: 0xF885, size: 0x8, addend: 0x0, symName: '___38-[MyAdTask2Mangger resetApp:callback:]_block_invoke', symObjAddr: 0x3020, symBinAddr: 0x129BC, symSize: 0x2D0 } + - { offset: 0xF98D, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56b64w, symObjAddr: 0x32F0, symBinAddr: 0x12C8C, symSize: 0x9C } + - { offset: 0xF9B1, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56s64w, symObjAddr: 0x338C, symBinAddr: 0x12D28, symSize: 0x70 } + - { offset: 0xF9CD, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger frontMostAppId]', symObjAddr: 0x33FC, symBinAddr: 0x12D98, symSize: 0x24 } + - { offset: 0xFA04, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger appRun:]', symObjAddr: 0x3420, symBinAddr: 0x12DBC, symSize: 0x110 } + - { offset: 0xFA5B, size: 0x8, addend: 0x0, symName: '___27-[MyAdTask2Mangger appRun:]_block_invoke', symObjAddr: 0x3530, symBinAddr: 0x12ECC, symSize: 0xBC } + - { offset: 0xFAAC, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger tap:x:y:]', symObjAddr: 0x3650, symBinAddr: 0x12F88, symSize: 0xAC } + - { offset: 0xFB21, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger tap:x:y:]_block_invoke', symObjAddr: 0x36FC, symBinAddr: 0x13034, symSize: 0x78 } + - { offset: 0xFB9E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger restart:]', symObjAddr: 0x3774, symBinAddr: 0x130AC, symSize: 0x144 } + - { offset: 0xFBEF, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger restart:]_block_invoke', symObjAddr: 0x38B8, symBinAddr: 0x131F0, symSize: 0x30C } + - { offset: 0xFC67, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b40w, symObjAddr: 0x3BC4, symBinAddr: 0x134FC, symSize: 0x54 } + - { offset: 0xFC8B, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger rndTouchApp]', symObjAddr: 0x3C18, symBinAddr: 0x13550, symSize: 0x144 } + - { offset: 0xFD1D, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger touchAppTask:]', symObjAddr: 0x3D5C, symBinAddr: 0x13694, symSize: 0x118 } + - { offset: 0xFD8C, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getStr:dic:]', symObjAddr: 0x3E74, symBinAddr: 0x137AC, symSize: 0x1F0 } + - { offset: 0xFDF0, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getNum:dic:]', symObjAddr: 0x4064, symBinAddr: 0x1399C, symSize: 0x238 } + - { offset: 0xFE72, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getInt:dic:]', symObjAddr: 0x429C, symBinAddr: 0x13BD4, symSize: 0x234 } + - { offset: 0xFEF4, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger dealloc]', symObjAddr: 0x44D0, symBinAddr: 0x13E08, symSize: 0x50 } + - { offset: 0xFF27, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger manQueue]', symObjAddr: 0x4520, symBinAddr: 0x13E58, symSize: 0x1C } + - { offset: 0xFF5D, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setManQueue:]', symObjAddr: 0x453C, symBinAddr: 0x13E74, symSize: 0x34 } + - { offset: 0xFF9B, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger .cxx_destruct]', symObjAddr: 0x4570, symBinAddr: 0x13EA8, symSize: 0xD8 } + - { offset: 0x110B5, size: 0x8, addend: 0x0, symName: '+[MyEventBus sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x13F80, symSize: 0xB0 } + - { offset: 0x110C2, size: 0x8, addend: 0x0, symName: '+[MyEventBus sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x13F80, symSize: 0xB0 } + - { offset: 0x110EB, size: 0x8, addend: 0x0, symName: _sharedInstance.sharedInstance, symObjAddr: 0x23B8, symBinAddr: 0x69520, symSize: 0x0 } + - { offset: 0x11100, size: 0x8, addend: 0x0, symName: _sharedInstance.onceToken, symObjAddr: 0x23C0, symBinAddr: 0x69528, symSize: 0x0 } + - { offset: 0x112A4, size: 0x8, addend: 0x0, symName: '___28+[MyEventBus sharedInstance]_block_invoke', symObjAddr: 0xB0, symBinAddr: 0x14030, symSize: 0x4C } + - { offset: 0x112E1, size: 0x8, addend: 0x0, symName: '-[MyEventBus init]', symObjAddr: 0xFC, symBinAddr: 0x1407C, symSize: 0xD8 } + - { offset: 0x11317, size: 0x8, addend: 0x0, symName: '-[MyEventBus registerSubscriber:]', symObjAddr: 0x1D4, symBinAddr: 0x14154, symSize: 0x23C } + - { offset: 0x113C6, size: 0x8, addend: 0x0, symName: '-[MyEventBus unregisterSubscriber:]', symObjAddr: 0x410, symBinAddr: 0x14390, symSize: 0xE8 } + - { offset: 0x11406, size: 0x8, addend: 0x0, symName: '___35-[MyEventBus unregisterSubscriber:]_block_invoke', symObjAddr: 0x4F8, symBinAddr: 0x14478, symSize: 0x90 } + - { offset: 0x11469, size: 0x8, addend: 0x0, symName: '-[MyEventBus postEvent:withObject:]', symObjAddr: 0x5EC, symBinAddr: 0x14508, symSize: 0x2C4 } + - { offset: 0x11504, size: 0x8, addend: 0x0, symName: '-[MyEventBus subscribers]', symObjAddr: 0x8B0, symBinAddr: 0x147CC, symSize: 0x1C } + - { offset: 0x1153A, size: 0x8, addend: 0x0, symName: '-[MyEventBus setSubscribers:]', symObjAddr: 0x8CC, symBinAddr: 0x147E8, symSize: 0x34 } + - { offset: 0x11578, size: 0x8, addend: 0x0, symName: '-[MyEventBus .cxx_destruct]', symObjAddr: 0x900, symBinAddr: 0x1481C, symSize: 0x30 } + - { offset: 0x117CD, size: 0x8, addend: 0x0, symName: '-[MyScriptTask init]', symObjAddr: 0x0, symBinAddr: 0x1484C, symSize: 0x384 } + - { offset: 0x117E8, size: 0x8, addend: 0x0, symName: '+[MyScriptTask sharedInstance]', symObjAddr: 0x3864, symBinAddr: 0x17FB0, symSize: 0x7C } + - { offset: 0x11813, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xD640, symBinAddr: 0x69530, symSize: 0x0 } + - { offset: 0x11829, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xD648, symBinAddr: 0x69538, symSize: 0x0 } + - { offset: 0x11E8A, size: 0x8, addend: 0x0, symName: '-[MyScriptTask init]', symObjAddr: 0x0, symBinAddr: 0x1484C, symSize: 0x384 } + - { offset: 0x11EDC, size: 0x8, addend: 0x0, symName: '-[MyScriptTask showStatus:]', symObjAddr: 0x384, symBinAddr: 0x14BD0, symSize: 0x8C } + - { offset: 0x11F1C, size: 0x8, addend: 0x0, symName: '-[MyScriptTask start]', symObjAddr: 0x410, symBinAddr: 0x14C5C, symSize: 0x34 } + - { offset: 0x11F4E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask stop]', symObjAddr: 0x444, symBinAddr: 0x14C90, symSize: 0x20 } + - { offset: 0x11F80, size: 0x8, addend: 0x0, symName: '-[MyScriptTask nextId]', symObjAddr: 0x464, symBinAddr: 0x14CB0, symSize: 0xBC } + - { offset: 0x11FB6, size: 0x8, addend: 0x0, symName: '-[MyScriptTask enqueue:]', symObjAddr: 0x520, symBinAddr: 0x14D6C, symSize: 0x120 } + - { offset: 0x12008, size: 0x8, addend: 0x0, symName: '___24-[MyScriptTask enqueue:]_block_invoke', symObjAddr: 0x640, symBinAddr: 0x14E8C, symSize: 0x2C8 } + - { offset: 0x12080, size: 0x8, addend: 0x0, symName: '-[MyScriptTask dequeue]', symObjAddr: 0x9A4, symBinAddr: 0x15154, symSize: 0x16C } + - { offset: 0x120C9, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xB10, symBinAddr: 0x152C0, symSize: 0x54 } + - { offset: 0x120ED, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xB64, symBinAddr: 0x15314, symSize: 0x2C } + - { offset: 0x12109, size: 0x8, addend: 0x0, symName: '___23-[MyScriptTask dequeue]_block_invoke', symObjAddr: 0xB90, symBinAddr: 0x15340, symSize: 0x27C } + - { offset: 0x12179, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r, symObjAddr: 0xE0C, symBinAddr: 0x155BC, symSize: 0x58 } + - { offset: 0x1219D, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r, symObjAddr: 0xE64, symBinAddr: 0x15614, symSize: 0x40 } + - { offset: 0x121B9, size: 0x8, addend: 0x0, symName: '-[MyScriptTask reset]', symObjAddr: 0xEA4, symBinAddr: 0x15654, symSize: 0x40 } + - { offset: 0x121EB, size: 0x8, addend: 0x0, symName: '-[MyScriptTask isRun]', symObjAddr: 0xEE4, symBinAddr: 0x15694, symSize: 0x24 } + - { offset: 0x12221, size: 0x8, addend: 0x0, symName: '-[MyScriptTask run]', symObjAddr: 0xF08, symBinAddr: 0x156B8, symSize: 0xC8 } + - { offset: 0x12261, size: 0x8, addend: 0x0, symName: '___19-[MyScriptTask run]_block_invoke', symObjAddr: 0xFD0, symBinAddr: 0x15780, symSize: 0x138 } + - { offset: 0x1229E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask completeTask]', symObjAddr: 0x116C, symBinAddr: 0x158B8, symSize: 0x50 } + - { offset: 0x122D0, size: 0x8, addend: 0x0, symName: '-[MyScriptTask adClosed:]', symObjAddr: 0x11BC, symBinAddr: 0x15908, symSize: 0x8C } + - { offset: 0x12310, size: 0x8, addend: 0x0, symName: '-[MyScriptTask loadIncrCount]', symObjAddr: 0x1248, symBinAddr: 0x15994, symSize: 0x28 } + - { offset: 0x12342, size: 0x8, addend: 0x0, symName: '-[MyScriptTask restart]', symObjAddr: 0x1270, symBinAddr: 0x159BC, symSize: 0xB8 } + - { offset: 0x12374, size: 0x8, addend: 0x0, symName: '___23-[MyScriptTask restart]_block_invoke', symObjAddr: 0x1328, symBinAddr: 0x15A74, symSize: 0x108 } + - { offset: 0x123B1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask killApp:]', symObjAddr: 0x1430, symBinAddr: 0x15B7C, symSize: 0x54 } + - { offset: 0x123F1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStartApp]', symObjAddr: 0x1484, symBinAddr: 0x15BD0, symSize: 0xBC } + - { offset: 0x1243B, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke', symObjAddr: 0x1540, symBinAddr: 0x15C8C, symSize: 0x628 } + - { offset: 0x1251F, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_2', symObjAddr: 0x1B68, symBinAddr: 0x162B4, symSize: 0x34 } + - { offset: 0x12547, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_3', symObjAddr: 0x1B9C, symBinAddr: 0x162E8, symSize: 0x158 } + - { offset: 0x125C8, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_4', symObjAddr: 0x1CF4, symBinAddr: 0x16440, symSize: 0x1F4 } + - { offset: 0x1262B, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke.75', symObjAddr: 0x1EE8, symBinAddr: 0x16634, symSize: 0x4C } + - { offset: 0x12664, size: 0x8, addend: 0x0, symName: '-[MyScriptTask proc]', symObjAddr: 0x1F34, symBinAddr: 0x16680, symSize: 0xAC } + - { offset: 0x126AC, size: 0x8, addend: 0x0, symName: '-[MyScriptTask _proc]', symObjAddr: 0x1FE0, symBinAddr: 0x1672C, symSize: 0xA94 } + - { offset: 0x127A5, size: 0x8, addend: 0x0, symName: ___destructor_8_s0_s8_s16_s24_s32_s40_s48_s56_s64, symObjAddr: 0x2A74, symBinAddr: 0x171C0, symSize: 0xB0 } + - { offset: 0x127C5, size: 0x8, addend: 0x0, symName: ___destructor_8_s16_s24_s40, symObjAddr: 0x2B24, symBinAddr: 0x17270, symSize: 0x54 } + - { offset: 0x127E5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask replaceScript:scriptName:callback:]', symObjAddr: 0x2B78, symBinAddr: 0x172C4, symSize: 0x1A0 } + - { offset: 0x12868, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runAdShowScript:]', symObjAddr: 0x2D18, symBinAddr: 0x17464, symSize: 0x114 } + - { offset: 0x128E6, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStopScript:]', symObjAddr: 0x2E2C, symBinAddr: 0x17578, symSize: 0xE4 } + - { offset: 0x1294C, size: 0x8, addend: 0x0, symName: '___30-[MyScriptTask runStopScript:]_block_invoke', symObjAddr: 0x2F10, symBinAddr: 0x1765C, symSize: 0x74 } + - { offset: 0x12997, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runAdTouchScript:]', symObjAddr: 0x2F84, symBinAddr: 0x176D0, symSize: 0x1D8 } + - { offset: 0x12A01, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStartScript:]', symObjAddr: 0x315C, symBinAddr: 0x178A8, symSize: 0x10C } + - { offset: 0x12A67, size: 0x8, addend: 0x0, symName: '___31-[MyScriptTask runStartScript:]_block_invoke', symObjAddr: 0x3268, symBinAddr: 0x179B4, symSize: 0x74 } + - { offset: 0x12AB2, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runSystemRestartScript]', symObjAddr: 0x32DC, symBinAddr: 0x17A28, symSize: 0x68 } + - { offset: 0x12AF4, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runScript:]', symObjAddr: 0x3344, symBinAddr: 0x17A90, symSize: 0x50 } + - { offset: 0x12B3A, size: 0x8, addend: 0x0, symName: '-[MyScriptTask stopScript:]', symObjAddr: 0x3394, symBinAddr: 0x17AE0, symSize: 0x50 } + - { offset: 0x12B80, size: 0x8, addend: 0x0, symName: '-[MyScriptTask readScript:]', symObjAddr: 0x33E4, symBinAddr: 0x17B30, symSize: 0xA4 } + - { offset: 0x12BD5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask saveScript:name:]', symObjAddr: 0x3488, symBinAddr: 0x17BD4, symSize: 0xC4 } + - { offset: 0x12C39, size: 0x8, addend: 0x0, symName: '-[MyScriptTask getScriptPath:]', symObjAddr: 0x354C, symBinAddr: 0x17C98, symSize: 0x84 } + - { offset: 0x12C7F, size: 0x8, addend: 0x0, symName: '-[MyScriptTask getCurTime]', symObjAddr: 0x35D0, symBinAddr: 0x17D1C, symSize: 0x64 } + - { offset: 0x12CC5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask logServer:title:]', symObjAddr: 0x3634, symBinAddr: 0x17D80, symSize: 0x70 } + - { offset: 0x12D16, size: 0x8, addend: 0x0, symName: '-[MyScriptTask saveAdTaskLog:]', symObjAddr: 0x36A4, symBinAddr: 0x17DF0, symSize: 0xEC } + - { offset: 0x12D58, size: 0x8, addend: 0x0, symName: '-[MyScriptTask statusStr]', symObjAddr: 0x3790, symBinAddr: 0x17EDC, symSize: 0xA0 } + - { offset: 0x12D9E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask appid]', symObjAddr: 0x3830, symBinAddr: 0x17F7C, symSize: 0x1C } + - { offset: 0x12DD5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runTouchAdJs:]', symObjAddr: 0x384C, symBinAddr: 0x17F98, symSize: 0x18 } + - { offset: 0x12EA7, size: 0x8, addend: 0x0, symName: '___30+[MyScriptTask sharedInstance]_block_invoke', symObjAddr: 0x38E0, symBinAddr: 0x1802C, symSize: 0x4C } + - { offset: 0x12ED1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask currentId]', symObjAddr: 0x392C, symBinAddr: 0x18078, symSize: 0x1C } + - { offset: 0x12F07, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setCurrentId:]', symObjAddr: 0x3948, symBinAddr: 0x18094, symSize: 0x24 } + - { offset: 0x12F45, size: 0x8, addend: 0x0, symName: '-[MyScriptTask timer]', symObjAddr: 0x396C, symBinAddr: 0x180B8, symSize: 0x1C } + - { offset: 0x12F7B, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setTimer:]', symObjAddr: 0x3988, symBinAddr: 0x180D4, symSize: 0x34 } + - { offset: 0x12FB9, size: 0x8, addend: 0x0, symName: '-[MyScriptTask inStack]', symObjAddr: 0x39BC, symBinAddr: 0x18108, symSize: 0x1C } + - { offset: 0x12FEF, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setInStack:]', symObjAddr: 0x39D8, symBinAddr: 0x18124, symSize: 0x34 } + - { offset: 0x1302D, size: 0x8, addend: 0x0, symName: '-[MyScriptTask outStack]', symObjAddr: 0x3A0C, symBinAddr: 0x18158, symSize: 0x1C } + - { offset: 0x13063, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setOutStack:]', symObjAddr: 0x3A28, symBinAddr: 0x18174, symSize: 0x34 } + - { offset: 0x130A1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask concurrentQueue]', symObjAddr: 0x3A5C, symBinAddr: 0x181A8, symSize: 0x1C } + - { offset: 0x130D7, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setConcurrentQueue:]', symObjAddr: 0x3A78, symBinAddr: 0x181C4, symSize: 0x34 } + - { offset: 0x13115, size: 0x8, addend: 0x0, symName: '-[MyScriptTask .cxx_destruct]', symObjAddr: 0x3AAC, symBinAddr: 0x181F8, symSize: 0xA8 } + - { offset: 0x14328, size: 0x8, addend: 0x0, symName: _startSimpleServer, symObjAddr: 0x0, symBinAddr: 0x182A0, symSize: 0x6C } + - { offset: 0x14335, size: 0x8, addend: 0x0, symName: _startSimpleServer, symObjAddr: 0x0, symBinAddr: 0x182A0, symSize: 0x6C } + - { offset: 0x14356, size: 0x8, addend: 0x0, symName: _startSimpleServer.onceToken, symObjAddr: 0x1210, symBinAddr: 0x69540, symSize: 0x0 } + - { offset: 0x144A1, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke, symObjAddr: 0x6C, symBinAddr: 0x1830C, symSize: 0xAC } + - { offset: 0x144F9, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke_2, symObjAddr: 0x118, symBinAddr: 0x183B8, symSize: 0x88 } + - { offset: 0x14521, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke_3, symObjAddr: 0x1A0, symBinAddr: 0x18440, symSize: 0x11C } + - { offset: 0x14737, size: 0x8, addend: 0x0, symName: '+[UDPHandler sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x1855C, symSize: 0x7C } + - { offset: 0x14744, size: 0x8, addend: 0x0, symName: '+[UDPHandler sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x1855C, symSize: 0x7C } + - { offset: 0x1476D, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x1EA0, symBinAddr: 0x69548, symSize: 0x0 } + - { offset: 0x14782, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x1EA8, symBinAddr: 0x69550, symSize: 0x0 } + - { offset: 0x148CF, size: 0x8, addend: 0x0, symName: '___28+[UDPHandler sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0x185D8, symSize: 0x4C } + - { offset: 0x148F7, size: 0x8, addend: 0x0, symName: '-[UDPHandler init]', symObjAddr: 0xC8, symBinAddr: 0x18624, symSize: 0xB0 } + - { offset: 0x1494A, size: 0x8, addend: 0x0, symName: '-[UDPHandler handle:]', symObjAddr: 0x178, symBinAddr: 0x186D4, symSize: 0x56C } + - { offset: 0x14A52, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke', symObjAddr: 0x6E4, symBinAddr: 0x18C40, symSize: 0x28 } + - { offset: 0x14A7A, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke_2', symObjAddr: 0x70C, symBinAddr: 0x18C68, symSize: 0x5C } + - { offset: 0x14ABE, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke_3', symObjAddr: 0x768, symBinAddr: 0x18CC4, symSize: 0x5C } + - { offset: 0x14D40, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:]', symObjAddr: 0x0, symBinAddr: 0x18D20, symSize: 0xBC } + - { offset: 0x14D59, size: 0x8, addend: 0x0, symName: _CSToastPositionTop, symObjAddr: 0x4860, symBinAddr: 0x69360, symSize: 0x0 } + - { offset: 0x14DCC, size: 0x8, addend: 0x0, symName: _CSToastPositionCenter, symObjAddr: 0x4868, symBinAddr: 0x69368, symSize: 0x0 } + - { offset: 0x14DE1, size: 0x8, addend: 0x0, symName: _CSToastPositionBottom, symObjAddr: 0x4870, symBinAddr: 0x69370, symSize: 0x0 } + - { offset: 0x14DF6, size: 0x8, addend: 0x0, symName: _CSToastTimerKey, symObjAddr: 0x4878, symBinAddr: 0x69378, symSize: 0x0 } + - { offset: 0x14E15, size: 0x8, addend: 0x0, symName: _CSToastDurationKey, symObjAddr: 0x4880, symBinAddr: 0x69380, symSize: 0x0 } + - { offset: 0x14E2A, size: 0x8, addend: 0x0, symName: _CSToastPositionKey, symObjAddr: 0x4888, symBinAddr: 0x69388, symSize: 0x0 } + - { offset: 0x14E3F, size: 0x8, addend: 0x0, symName: _CSToastCompletionKey, symObjAddr: 0x4890, symBinAddr: 0x69390, symSize: 0x0 } + - { offset: 0x14E54, size: 0x8, addend: 0x0, symName: _CSToastActiveKey, symObjAddr: 0x4898, symBinAddr: 0x69398, symSize: 0x0 } + - { offset: 0x14E69, size: 0x8, addend: 0x0, symName: _CSToastActivityViewKey, symObjAddr: 0x48A0, symBinAddr: 0x693A0, symSize: 0x0 } + - { offset: 0x14E7E, size: 0x8, addend: 0x0, symName: _CSToastQueueKey, symObjAddr: 0x48A8, symBinAddr: 0x693A8, symSize: 0x0 } + - { offset: 0x14E87, size: 0x8, addend: 0x0, symName: '+[CSToastManager sharedManager]', symObjAddr: 0x3E2C, symBinAddr: 0x1CA4C, symSize: 0xB0 } + - { offset: 0x14EB2, size: 0x8, addend: 0x0, symName: _sharedManager._sharedManager, symObjAddr: 0x13088, symBinAddr: 0x69558, symSize: 0x0 } + - { offset: 0x14EC8, size: 0x8, addend: 0x0, symName: _sharedManager.oncePredicate, symObjAddr: 0x13090, symBinAddr: 0x69560, symSize: 0x0 } + - { offset: 0x1633C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:]', symObjAddr: 0x0, symBinAddr: 0x18D20, symSize: 0xBC } + - { offset: 0x1637C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:]', symObjAddr: 0xBC, symBinAddr: 0x18DDC, symSize: 0x98 } + - { offset: 0x163D8, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:style:]', symObjAddr: 0x154, symBinAddr: 0x18E74, symSize: 0xF8 } + - { offset: 0x16450, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:title:image:style:completion:]', symObjAddr: 0x24C, symBinAddr: 0x18F6C, symSize: 0x164 } + - { offset: 0x164F4, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) showToast:]', symObjAddr: 0x3B0, symBinAddr: 0x190D0, symSize: 0xBC } + - { offset: 0x16534, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) showToast:duration:position:completion:]', symObjAddr: 0x46C, symBinAddr: 0x1918C, symSize: 0x254 } + - { offset: 0x1659E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToast]', symObjAddr: 0x6C0, symBinAddr: 0x193E0, symSize: 0x84 } + - { offset: 0x165D0, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToast:]', symObjAddr: 0x744, symBinAddr: 0x19464, symSize: 0x108 } + - { offset: 0x16610, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideAllToasts]', symObjAddr: 0x84C, symBinAddr: 0x1956C, symSize: 0x3C } + - { offset: 0x16642, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideAllToasts:clearQueue:]', symObjAddr: 0x888, symBinAddr: 0x195A8, symSize: 0x1C0 } + - { offset: 0x166A9, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) clearToastQueue]', symObjAddr: 0xA48, symBinAddr: 0x19768, symSize: 0x50 } + - { offset: 0x166DB, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_showToast:duration:position:]', symObjAddr: 0xA98, symBinAddr: 0x197B8, symSize: 0x300 } + - { offset: 0x1674C, size: 0x8, addend: 0x0, symName: '___48-[UIView(Toast) cs_showToast:duration:position:]_block_invoke', symObjAddr: 0xD98, symBinAddr: 0x19AB8, symSize: 0x34 } + - { offset: 0x16785, size: 0x8, addend: 0x0, symName: '___48-[UIView(Toast) cs_showToast:duration:position:]_block_invoke.23', symObjAddr: 0xE30, symBinAddr: 0x19AEC, symSize: 0xE0 } + - { offset: 0x1680E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_hideToast:]', symObjAddr: 0xFAC, symBinAddr: 0x19BCC, symSize: 0x64 } + - { offset: 0x1684E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_hideToast:fromTap:]', symObjAddr: 0x1010, symBinAddr: 0x19C30, symSize: 0x208 } + - { offset: 0x168AA, size: 0x8, addend: 0x0, symName: '___38-[UIView(Toast) cs_hideToast:fromTap:]_block_invoke', symObjAddr: 0x1218, symBinAddr: 0x19E38, symSize: 0x34 } + - { offset: 0x168E3, size: 0x8, addend: 0x0, symName: '___38-[UIView(Toast) cs_hideToast:fromTap:]_block_invoke_2', symObjAddr: 0x124C, symBinAddr: 0x19E6C, symSize: 0x23C } + - { offset: 0x1699C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) toastViewForMessage:title:image:style:]', symObjAddr: 0x1488, symBinAddr: 0x1A0A8, symSize: 0xF48 } + - { offset: 0x16C82, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x23D0, symBinAddr: 0x1AFF0, symSize: 0x4C } + - { offset: 0x16CE8, size: 0x8, addend: 0x0, symName: _CGSizeMake, symObjAddr: 0x241C, symBinAddr: 0x1B03C, symSize: 0x2C } + - { offset: 0x16D30, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_activeToasts]', symObjAddr: 0x2448, symBinAddr: 0x1B068, symSize: 0xB8 } + - { offset: 0x16D76, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_toastQueue]', symObjAddr: 0x2500, symBinAddr: 0x1B120, symSize: 0xB8 } + - { offset: 0x16DBC, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_toastTimerDidFinish:]', symObjAddr: 0x25B8, symBinAddr: 0x1B1D8, symSize: 0x8C } + - { offset: 0x16DFE, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_handleToastTapped:]', symObjAddr: 0x2644, symBinAddr: 0x1B264, symSize: 0xCC } + - { offset: 0x16E5E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToastActivity:]', symObjAddr: 0x2710, symBinAddr: 0x1B330, symSize: 0x554 } + - { offset: 0x16EDE, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x2C64, symBinAddr: 0x1B884, symSize: 0x2C } + - { offset: 0x16F26, size: 0x8, addend: 0x0, symName: '___35-[UIView(Toast) makeToastActivity:]_block_invoke', symObjAddr: 0x2C90, symBinAddr: 0x1B8B0, symSize: 0x34 } + - { offset: 0x16F62, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToastActivity]', symObjAddr: 0x2CC4, symBinAddr: 0x1B8E4, symSize: 0x1B8 } + - { offset: 0x16FA4, size: 0x8, addend: 0x0, symName: '___34-[UIView(Toast) hideToastActivity]_block_invoke', symObjAddr: 0x2E7C, symBinAddr: 0x1BA9C, symSize: 0x34 } + - { offset: 0x16FE0, size: 0x8, addend: 0x0, symName: '___34-[UIView(Toast) hideToastActivity]_block_invoke_2', symObjAddr: 0x2EB0, symBinAddr: 0x1BAD0, symSize: 0x58 } + - { offset: 0x17041, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_centerPointForPosition:withToast:]', symObjAddr: 0x2F08, symBinAddr: 0x1BB28, symSize: 0x3A4 } + - { offset: 0x170D6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle initWithDefaultStyle]', symObjAddr: 0x32AC, symBinAddr: 0x1BECC, symSize: 0x398 } + - { offset: 0x1710D, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMaxWidthPercentage:]', symObjAddr: 0x3644, symBinAddr: 0x1C264, symSize: 0xAC } + - { offset: 0x171AB, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMaxHeightPercentage:]', symObjAddr: 0x36F0, symBinAddr: 0x1C310, symSize: 0xAC } + - { offset: 0x17249, size: 0x8, addend: 0x0, symName: '-[CSToastStyle init]', symObjAddr: 0x379C, symBinAddr: 0x1C3BC, symSize: 0x38 } + - { offset: 0x17280, size: 0x8, addend: 0x0, symName: '-[CSToastStyle backgroundColor]', symObjAddr: 0x37D4, symBinAddr: 0x1C3F4, symSize: 0x1C } + - { offset: 0x172B6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setBackgroundColor:]', symObjAddr: 0x37F0, symBinAddr: 0x1C410, symSize: 0x34 } + - { offset: 0x172F4, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleColor]', symObjAddr: 0x3824, symBinAddr: 0x1C444, symSize: 0x1C } + - { offset: 0x1732A, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleColor:]', symObjAddr: 0x3840, symBinAddr: 0x1C460, symSize: 0x34 } + - { offset: 0x17368, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageColor]', symObjAddr: 0x3874, symBinAddr: 0x1C494, symSize: 0x1C } + - { offset: 0x1739E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageColor:]', symObjAddr: 0x3890, symBinAddr: 0x1C4B0, symSize: 0x34 } + - { offset: 0x173DC, size: 0x8, addend: 0x0, symName: '-[CSToastStyle maxWidthPercentage]', symObjAddr: 0x38C4, symBinAddr: 0x1C4E4, symSize: 0x1C } + - { offset: 0x17412, size: 0x8, addend: 0x0, symName: '-[CSToastStyle maxHeightPercentage]', symObjAddr: 0x38E0, symBinAddr: 0x1C500, symSize: 0x1C } + - { offset: 0x17448, size: 0x8, addend: 0x0, symName: '-[CSToastStyle horizontalPadding]', symObjAddr: 0x38FC, symBinAddr: 0x1C51C, symSize: 0x1C } + - { offset: 0x1747E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setHorizontalPadding:]', symObjAddr: 0x3918, symBinAddr: 0x1C538, symSize: 0x24 } + - { offset: 0x174BC, size: 0x8, addend: 0x0, symName: '-[CSToastStyle verticalPadding]', symObjAddr: 0x393C, symBinAddr: 0x1C55C, symSize: 0x1C } + - { offset: 0x174F3, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setVerticalPadding:]', symObjAddr: 0x3958, symBinAddr: 0x1C578, symSize: 0x24 } + - { offset: 0x17532, size: 0x8, addend: 0x0, symName: '-[CSToastStyle cornerRadius]', symObjAddr: 0x397C, symBinAddr: 0x1C59C, symSize: 0x1C } + - { offset: 0x17569, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setCornerRadius:]', symObjAddr: 0x3998, symBinAddr: 0x1C5B8, symSize: 0x24 } + - { offset: 0x175A8, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleFont]', symObjAddr: 0x39BC, symBinAddr: 0x1C5DC, symSize: 0x1C } + - { offset: 0x175DF, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleFont:]', symObjAddr: 0x39D8, symBinAddr: 0x1C5F8, symSize: 0x34 } + - { offset: 0x1761E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageFont]', symObjAddr: 0x3A0C, symBinAddr: 0x1C62C, symSize: 0x1C } + - { offset: 0x17655, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageFont:]', symObjAddr: 0x3A28, symBinAddr: 0x1C648, symSize: 0x34 } + - { offset: 0x17694, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleAlignment]', symObjAddr: 0x3A5C, symBinAddr: 0x1C67C, symSize: 0x1C } + - { offset: 0x176CB, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleAlignment:]', symObjAddr: 0x3A78, symBinAddr: 0x1C698, symSize: 0x24 } + - { offset: 0x1770A, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageAlignment]', symObjAddr: 0x3A9C, symBinAddr: 0x1C6BC, symSize: 0x1C } + - { offset: 0x17741, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageAlignment:]', symObjAddr: 0x3AB8, symBinAddr: 0x1C6D8, symSize: 0x24 } + - { offset: 0x17780, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleNumberOfLines]', symObjAddr: 0x3ADC, symBinAddr: 0x1C6FC, symSize: 0x1C } + - { offset: 0x177B7, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleNumberOfLines:]', symObjAddr: 0x3AF8, symBinAddr: 0x1C718, symSize: 0x24 } + - { offset: 0x177F6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageNumberOfLines]', symObjAddr: 0x3B1C, symBinAddr: 0x1C73C, symSize: 0x1C } + - { offset: 0x1782D, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageNumberOfLines:]', symObjAddr: 0x3B38, symBinAddr: 0x1C758, symSize: 0x24 } + - { offset: 0x1786C, size: 0x8, addend: 0x0, symName: '-[CSToastStyle displayShadow]', symObjAddr: 0x3B5C, symBinAddr: 0x1C77C, symSize: 0x20 } + - { offset: 0x178A3, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setDisplayShadow:]', symObjAddr: 0x3B7C, symBinAddr: 0x1C79C, symSize: 0x28 } + - { offset: 0x178E2, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowColor]', symObjAddr: 0x3BA4, symBinAddr: 0x1C7C4, symSize: 0x1C } + - { offset: 0x17919, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowColor:]', symObjAddr: 0x3BC0, symBinAddr: 0x1C7E0, symSize: 0x34 } + - { offset: 0x17958, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowOpacity]', symObjAddr: 0x3BF4, symBinAddr: 0x1C814, symSize: 0x1C } + - { offset: 0x1798F, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowOpacity:]', symObjAddr: 0x3C10, symBinAddr: 0x1C830, symSize: 0x24 } + - { offset: 0x179CE, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowRadius]', symObjAddr: 0x3C34, symBinAddr: 0x1C854, symSize: 0x1C } + - { offset: 0x17A05, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowRadius:]', symObjAddr: 0x3C50, symBinAddr: 0x1C870, symSize: 0x24 } + - { offset: 0x17A44, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowOffset]', symObjAddr: 0x3C74, symBinAddr: 0x1C894, symSize: 0x28 } + - { offset: 0x17A7B, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowOffset:]', symObjAddr: 0x3C9C, symBinAddr: 0x1C8BC, symSize: 0x28 } + - { offset: 0x17ABA, size: 0x8, addend: 0x0, symName: '-[CSToastStyle imageSize]', symObjAddr: 0x3CC4, symBinAddr: 0x1C8E4, symSize: 0x28 } + - { offset: 0x17AF1, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setImageSize:]', symObjAddr: 0x3CEC, symBinAddr: 0x1C90C, symSize: 0x28 } + - { offset: 0x17B30, size: 0x8, addend: 0x0, symName: '-[CSToastStyle activitySize]', symObjAddr: 0x3D14, symBinAddr: 0x1C934, symSize: 0x28 } + - { offset: 0x17B67, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setActivitySize:]', symObjAddr: 0x3D3C, symBinAddr: 0x1C95C, symSize: 0x28 } + - { offset: 0x17BA6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle fadeDuration]', symObjAddr: 0x3D64, symBinAddr: 0x1C984, symSize: 0x1C } + - { offset: 0x17BDD, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setFadeDuration:]', symObjAddr: 0x3D80, symBinAddr: 0x1C9A0, symSize: 0x24 } + - { offset: 0x17C1C, size: 0x8, addend: 0x0, symName: '-[CSToastStyle .cxx_destruct]', symObjAddr: 0x3DA4, symBinAddr: 0x1C9C4, symSize: 0x88 } + - { offset: 0x17CE6, size: 0x8, addend: 0x0, symName: '___31+[CSToastManager sharedManager]_block_invoke', symObjAddr: 0x3EDC, symBinAddr: 0x1CAFC, symSize: 0x4C } + - { offset: 0x17D26, size: 0x8, addend: 0x0, symName: '-[CSToastManager init]', symObjAddr: 0x3F28, symBinAddr: 0x1CB48, symSize: 0x128 } + - { offset: 0x17D5D, size: 0x8, addend: 0x0, symName: '+[CSToastManager setSharedStyle:]', symObjAddr: 0x4050, symBinAddr: 0x1CC70, symSize: 0x80 } + - { offset: 0x17D9F, size: 0x8, addend: 0x0, symName: '+[CSToastManager sharedStyle]', symObjAddr: 0x40D0, symBinAddr: 0x1CCF0, symSize: 0x64 } + - { offset: 0x17DD6, size: 0x8, addend: 0x0, symName: '+[CSToastManager setTapToDismissEnabled:]', symObjAddr: 0x4134, symBinAddr: 0x1CD54, symSize: 0x5C } + - { offset: 0x17E18, size: 0x8, addend: 0x0, symName: '+[CSToastManager isTapToDismissEnabled]', symObjAddr: 0x4190, symBinAddr: 0x1CDB0, symSize: 0x5C } + - { offset: 0x17E4F, size: 0x8, addend: 0x0, symName: '+[CSToastManager setQueueEnabled:]', symObjAddr: 0x41EC, symBinAddr: 0x1CE0C, symSize: 0x5C } + - { offset: 0x17E91, size: 0x8, addend: 0x0, symName: '+[CSToastManager isQueueEnabled]', symObjAddr: 0x4248, symBinAddr: 0x1CE68, symSize: 0x5C } + - { offset: 0x17EC8, size: 0x8, addend: 0x0, symName: '+[CSToastManager setDefaultDuration:]', symObjAddr: 0x42A4, symBinAddr: 0x1CEC4, symSize: 0x58 } + - { offset: 0x17F0A, size: 0x8, addend: 0x0, symName: '+[CSToastManager defaultDuration]', symObjAddr: 0x42FC, symBinAddr: 0x1CF1C, symSize: 0x58 } + - { offset: 0x17F41, size: 0x8, addend: 0x0, symName: '+[CSToastManager setDefaultPosition:]', symObjAddr: 0x4354, symBinAddr: 0x1CF74, symSize: 0xC8 } + - { offset: 0x17F83, size: 0x8, addend: 0x0, symName: '+[CSToastManager defaultPosition]', symObjAddr: 0x441C, symBinAddr: 0x1D03C, symSize: 0x64 } + - { offset: 0x17FBA, size: 0x8, addend: 0x0, symName: '-[CSToastManager sharedStyle]', symObjAddr: 0x4480, symBinAddr: 0x1D0A0, symSize: 0x1C } + - { offset: 0x17FF1, size: 0x8, addend: 0x0, symName: '-[CSToastManager setSharedStyle:]', symObjAddr: 0x449C, symBinAddr: 0x1D0BC, symSize: 0x34 } + - { offset: 0x18030, size: 0x8, addend: 0x0, symName: '-[CSToastManager isTapToDismissEnabled]', symObjAddr: 0x44D0, symBinAddr: 0x1D0F0, symSize: 0x20 } + - { offset: 0x18067, size: 0x8, addend: 0x0, symName: '-[CSToastManager setTapToDismissEnabled:]', symObjAddr: 0x44F0, symBinAddr: 0x1D110, symSize: 0x28 } + - { offset: 0x180A6, size: 0x8, addend: 0x0, symName: '-[CSToastManager isQueueEnabled]', symObjAddr: 0x4518, symBinAddr: 0x1D138, symSize: 0x20 } + - { offset: 0x180DD, size: 0x8, addend: 0x0, symName: '-[CSToastManager setQueueEnabled:]', symObjAddr: 0x4538, symBinAddr: 0x1D158, symSize: 0x28 } + - { offset: 0x1811C, size: 0x8, addend: 0x0, symName: '-[CSToastManager defaultDuration]', symObjAddr: 0x4560, symBinAddr: 0x1D180, symSize: 0x1C } + - { offset: 0x18153, size: 0x8, addend: 0x0, symName: '-[CSToastManager setDefaultDuration:]', symObjAddr: 0x457C, symBinAddr: 0x1D19C, symSize: 0x24 } + - { offset: 0x18192, size: 0x8, addend: 0x0, symName: '-[CSToastManager defaultPosition]', symObjAddr: 0x45A0, symBinAddr: 0x1D1C0, symSize: 0x1C } + - { offset: 0x181C9, size: 0x8, addend: 0x0, symName: '-[CSToastManager setDefaultPosition:]', symObjAddr: 0x45BC, symBinAddr: 0x1D1DC, symSize: 0x34 } + - { offset: 0x18208, size: 0x8, addend: 0x0, symName: '-[CSToastManager .cxx_destruct]', symObjAddr: 0x45F0, symBinAddr: 0x1D210, symSize: 0x48 } + - { offset: 0x1952A, size: 0x8, addend: 0x0, symName: _XSGetFrontMostApplication, symObjAddr: 0x0, symBinAddr: 0x1D258, symSize: 0x1EC } + - { offset: 0x19571, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions, symObjAddr: 0x5348, symBinAddr: 0x22508, symSize: 0x160 } + - { offset: 0x19594, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.security, symObjAddr: 0x1D0D0, symBinAddr: 0x69568, symSize: 0x0 } + - { offset: 0x195AA, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.SetEntitlements, symObjAddr: 0x1D0D8, symBinAddr: 0x69570, symSize: 0x0 } + - { offset: 0x195C0, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.onceToken, symObjAddr: 0x1D0E0, symBinAddr: 0x69578, symSize: 0x0 } + - { offset: 0x196BE, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions, symObjAddr: 0x5510, symBinAddr: 0x226D0, symSize: 0x470 } + - { offset: 0x196E5, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.security, symObjAddr: 0x1D0E8, symBinAddr: 0x69580, symSize: 0x0 } + - { offset: 0x196FB, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.SetEntitlements, symObjAddr: 0x1D0F0, symBinAddr: 0x69588, symSize: 0x0 } + - { offset: 0x19711, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.onceToken, symObjAddr: 0x1D0F8, symBinAddr: 0x69590, symSize: 0x0 } + - { offset: 0x197AE, size: 0x8, addend: 0x0, symName: __XSOpenApp, symBinAddr: 0x69618, symSize: 0x0 } + - { offset: 0x1A48F, size: 0x8, addend: 0x0, symName: _XSGetFrontMostApplication, symObjAddr: 0x0, symBinAddr: 0x1D258, symSize: 0x1EC } + - { offset: 0x1A4FD, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x1EC, symBinAddr: 0x1D444, symSize: 0x54 } + - { offset: 0x1A521, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x240, symBinAddr: 0x1D498, symSize: 0x2C } + - { offset: 0x1A53D, size: 0x8, addend: 0x0, symName: ___XSGetFrontMostApplication_block_invoke, symObjAddr: 0x26C, symBinAddr: 0x1D4C4, symSize: 0x1B8 } + - { offset: 0x1A5B5, size: 0x8, addend: 0x0, symName: _XSFrontMostAppId, symObjAddr: 0x4BC, symBinAddr: 0x1D67C, symSize: 0x128 } + - { offset: 0x1A5DD, size: 0x8, addend: 0x0, symName: _XSRuncmd, symObjAddr: 0x5E4, symBinAddr: 0x1D7A4, symSize: 0x11C } + - { offset: 0x1A659, size: 0x8, addend: 0x0, symName: _unlink_cb, symObjAddr: 0x700, symBinAddr: 0x1D8C0, symSize: 0x50 } + - { offset: 0x1A6B9, size: 0x8, addend: 0x0, symName: _XSSystem, symObjAddr: 0x750, symBinAddr: 0x1D910, symSize: 0x50 } + - { offset: 0x1A745, size: 0x8, addend: 0x0, symName: _XSGetAppExecutable, symObjAddr: 0x7A0, symBinAddr: 0x1D960, symSize: 0x4C0 } + - { offset: 0x1A866, size: 0x8, addend: 0x0, symName: _XSReboot, symObjAddr: 0xC60, symBinAddr: 0x1DE20, symSize: 0x70 } + - { offset: 0x1A89C, size: 0x8, addend: 0x0, symName: _XSKillApp, symObjAddr: 0xCD0, symBinAddr: 0x1DE90, symSize: 0x100 } + - { offset: 0x1A90A, size: 0x8, addend: 0x0, symName: _kill2, symObjAddr: 0xDD0, symBinAddr: 0x1DF90, symSize: 0xD4 } + - { offset: 0x1A96A, size: 0x8, addend: 0x0, symName: _system2, symObjAddr: 0xEA4, symBinAddr: 0x1E064, symSize: 0x248 } + - { offset: 0x1A9FC, size: 0x8, addend: 0x0, symName: _XSKillAppByName, symObjAddr: 0x10EC, symBinAddr: 0x1E2AC, symSize: 0x7C } + - { offset: 0x1AA32, size: 0x8, addend: 0x0, symName: _XSBringAppForeground, symObjAddr: 0x1168, symBinAddr: 0x1E328, symSize: 0xE0 } + - { offset: 0x1AA76, size: 0x8, addend: 0x0, symName: _bringAppToForeground, symObjAddr: 0x1248, symBinAddr: 0x1E408, symSize: 0x194 } + - { offset: 0x1AAD9, size: 0x8, addend: 0x0, symName: ___bringAppToForeground_block_invoke, symObjAddr: 0x13DC, symBinAddr: 0x1E59C, symSize: 0x68 } + - { offset: 0x1AB0F, size: 0x8, addend: 0x0, symName: _activateApp, symObjAddr: 0x1444, symBinAddr: 0x1E604, symSize: 0xCC } + - { offset: 0x1AB63, size: 0x8, addend: 0x0, symName: _XSRemoteUnlock, symObjAddr: 0x1510, symBinAddr: 0x1E6D0, symSize: 0x4A0 } + - { offset: 0x1AC15, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x19B0, symBinAddr: 0x1EB70, symSize: 0x2C } + - { offset: 0x1AC5D, size: 0x8, addend: 0x0, symName: _getDeviceName, symObjAddr: 0x19DC, symBinAddr: 0x1EB9C, symSize: 0x80 } + - { offset: 0x1AC87, size: 0x8, addend: 0x0, symName: _roundUp, symObjAddr: 0x1A5C, symBinAddr: 0x1EC1C, symSize: 0x7C } + - { offset: 0x1ACCF, size: 0x8, addend: 0x0, symName: _createScreenShotCGImageRef, symObjAddr: 0x1AD8, symBinAddr: 0x1EC98, symSize: 0x620 } + - { offset: 0x1AECF, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x20F8, symBinAddr: 0x1F2B8, symSize: 0x4C } + - { offset: 0x1AF35, size: 0x8, addend: 0x0, symName: _XSCcaptureScreen2, symObjAddr: 0x2144, symBinAddr: 0x1F304, symSize: 0x90 } + - { offset: 0x1AF6E, size: 0x8, addend: 0x0, symName: _XSCaptureScreen, symObjAddr: 0x21D4, symBinAddr: 0x1F394, symSize: 0x160 } + - { offset: 0x1AF98, size: 0x8, addend: 0x0, symName: _defaultIconWithSize, symObjAddr: 0x2334, symBinAddr: 0x1F4F4, symSize: 0x358 } + - { offset: 0x1B063, size: 0x8, addend: 0x0, symName: _XSGetApps, symObjAddr: 0x268C, symBinAddr: 0x1F84C, symSize: 0xAF0 } + - { offset: 0x1B26D, size: 0x8, addend: 0x0, symName: _CGSizeMake, symObjAddr: 0x317C, symBinAddr: 0x2033C, symSize: 0x2C } + - { offset: 0x1B2B5, size: 0x8, addend: 0x0, symName: _XSCleanSafariHistory, symObjAddr: 0x31A8, symBinAddr: 0x20368, symSize: 0xE0 } + - { offset: 0x1B316, size: 0x8, addend: 0x0, symName: _XSCleanSafari, symObjAddr: 0x3288, symBinAddr: 0x20448, symSize: 0x4D4 } + - { offset: 0x1B44F, size: 0x8, addend: 0x0, symName: _XSCleanKeychain, symObjAddr: 0x375C, symBinAddr: 0x2091C, symSize: 0x158 } + - { offset: 0x1B4A1, size: 0x8, addend: 0x0, symName: _XSCleanPastboard, symObjAddr: 0x38B4, symBinAddr: 0x20A74, symSize: 0x348 } + - { offset: 0x1B54D, size: 0x8, addend: 0x0, symName: _getAppExecutable, symObjAddr: 0x3BFC, symBinAddr: 0x20DBC, symSize: 0x51C } + - { offset: 0x1B693, size: 0x8, addend: 0x0, symName: _getAppSandboxPath, symObjAddr: 0x4118, symBinAddr: 0x212D8, symSize: 0x390 } + - { offset: 0x1B754, size: 0x8, addend: 0x0, symName: _XSGetAppInfoPath, symObjAddr: 0x44A8, symBinAddr: 0x21668, symSize: 0x1D8 } + - { offset: 0x1B7C8, size: 0x8, addend: 0x0, symName: _XSGetAppInfo, symObjAddr: 0x4680, symBinAddr: 0x21840, symSize: 0xA8 } + - { offset: 0x1B80F, size: 0x8, addend: 0x0, symName: _XSSaveAppInfo, symObjAddr: 0x4728, symBinAddr: 0x218E8, symSize: 0x3FC } + - { offset: 0x1B90D, size: 0x8, addend: 0x0, symName: _cleanBundleContainer, symObjAddr: 0x4B24, symBinAddr: 0x21CE4, symSize: 0x358 } + - { offset: 0x1B9B2, size: 0x8, addend: 0x0, symName: _clearAppStringInfo, symObjAddr: 0x4E7C, symBinAddr: 0x2203C, symSize: 0x254 } + - { offset: 0x1BA29, size: 0x8, addend: 0x0, symName: _XSClearAppData, symObjAddr: 0x50D0, symBinAddr: 0x22290, symSize: 0x78 } + - { offset: 0x1BA5E, size: 0x8, addend: 0x0, symName: _screenIsLocked, symObjAddr: 0x5148, symBinAddr: 0x22308, symSize: 0xC8 } + - { offset: 0x1BAB4, size: 0x8, addend: 0x0, symName: _XSClearAll, symObjAddr: 0x5210, symBinAddr: 0x223D0, symSize: 0x54 } + - { offset: 0x1BADA, size: 0x8, addend: 0x0, symName: _getCPUTemperature, symObjAddr: 0x5264, symBinAddr: 0x22424, symSize: 0xE4 } + - { offset: 0x1BC09, size: 0x8, addend: 0x0, symName: ___injectNetworkPermissions_block_invoke, symObjAddr: 0x54A8, symBinAddr: 0x22668, symSize: 0x68 } + - { offset: 0x1BC33, size: 0x8, addend: 0x0, symName: ___injectEntitlementsWithOptions_block_invoke, symObjAddr: 0x5980, symBinAddr: 0x22B40, symSize: 0x68 } + - { offset: 0x1BC5D, size: 0x8, addend: 0x0, symName: _verifyEntitlement, symObjAddr: 0x59E8, symBinAddr: 0x22BA8, symSize: 0x10C } + - { offset: 0x1BCC3, size: 0x8, addend: 0x0, symName: _printInfo, symObjAddr: 0x5AF4, symBinAddr: 0x22CB4, symSize: 0x4A8 } + - { offset: 0x1BF10, size: 0x8, addend: 0x0, symName: _printClassHierarchy, symObjAddr: 0x5F9C, symBinAddr: 0x2315C, symSize: 0x80 } + - { offset: 0x1BF36, size: 0x8, addend: 0x0, symName: _printMethodInfo, symObjAddr: 0x601C, symBinAddr: 0x231DC, symSize: 0x21C } + - { offset: 0x1BFF1, size: 0x8, addend: 0x0, symName: _printPropertyInfo, symObjAddr: 0x6238, symBinAddr: 0x233F8, symSize: 0x240 } + - { offset: 0x1C0A4, size: 0x8, addend: 0x0, symName: _parsePropertyAttributes, symObjAddr: 0x6478, symBinAddr: 0x23638, symSize: 0x4A0 } + - { offset: 0x1C11D, size: 0x8, addend: 0x0, symName: _getFrontAppWindows, symObjAddr: 0x6918, symBinAddr: 0x23AD8, symSize: 0x174 } + - { offset: 0x1C194, size: 0x8, addend: 0x0, symName: _findButtonsInView, symObjAddr: 0x6A8C, symBinAddr: 0x23C4C, symSize: 0x2D4 } + - { offset: 0x1C207, size: 0x8, addend: 0x0, symName: _getKeyWindow, symObjAddr: 0x6D60, symBinAddr: 0x23F20, symSize: 0x408 } + - { offset: 0x1C292, size: 0x8, addend: 0x0, symName: _getAllButtons, symObjAddr: 0x7168, symBinAddr: 0x24328, symSize: 0x54 } + - { offset: 0x1C2BE, size: 0x8, addend: 0x0, symName: ___getAllButtons_block_invoke, symObjAddr: 0x71BC, symBinAddr: 0x2437C, symSize: 0x50 } + - { offset: 0x1FFFF, size: 0x8, addend: 0x0, symName: _XSErrorFromException, symObjAddr: 0x0, symBinAddr: 0x243CC, symSize: 0x1A8 } + - { offset: 0x2000C, size: 0x8, addend: 0x0, symName: _XSCalculateElapsedTime, symObjAddr: 0x1A8, symBinAddr: 0x24574, symSize: 0x90 } + - { offset: 0x20031, size: 0x8, addend: 0x0, symName: _XSCalculateElapsedTime.timebaseInfo, symObjAddr: 0xBDD4, symBinAddr: 0x69598, symSize: 0x0 } + - { offset: 0x20507, size: 0x8, addend: 0x0, symName: _XSErrorFromException, symObjAddr: 0x0, symBinAddr: 0x243CC, symSize: 0x1A8 } + - { offset: 0x2053D, size: 0x8, addend: 0x0, symName: _XSRoundToDecimal, symObjAddr: 0x238, symBinAddr: 0x24604, symSize: 0x4C } + - { offset: 0x20581, size: 0x8, addend: 0x0, symName: _XSAfterNext, symObjAddr: 0x284, symBinAddr: 0x24650, symSize: 0x140 } + - { offset: 0x205C1, size: 0x8, addend: 0x0, symName: ___XSAfterNext_block_invoke, symObjAddr: 0x3C4, symBinAddr: 0x24790, symSize: 0x34 } + - { offset: 0x205FA, size: 0x8, addend: 0x0, symName: '+[XSHelper random:and:]', symObjAddr: 0x45C, symBinAddr: 0x247C4, symSize: 0x4C } + - { offset: 0x2064C, size: 0x8, addend: 0x0, symName: '+[XSHelper str2Data:]', symObjAddr: 0x4A8, symBinAddr: 0x24810, symSize: 0x70 } + - { offset: 0x20690, size: 0x8, addend: 0x0, symName: '+[XSHelper data2str:]', symObjAddr: 0x518, symBinAddr: 0x24880, symSize: 0x74 } + - { offset: 0x206D4, size: 0x8, addend: 0x0, symName: '+[XSHelper strIsEmpty:]', symObjAddr: 0x58C, symBinAddr: 0x248F4, symSize: 0x128 } + - { offset: 0x20772, size: 0x8, addend: 0x0, symName: '+[XSHelper isMatch:test:]', symObjAddr: 0x6B4, symBinAddr: 0x24A1C, symSize: 0x130 } + - { offset: 0x2080F, size: 0x8, addend: 0x0, symName: '+[XSHelper json2Dictionary:]', symObjAddr: 0x7E4, symBinAddr: 0x24B4C, symSize: 0x19C } + - { offset: 0x20853, size: 0x8, addend: 0x0, symName: '+[XSHelper jsonData2Dictionary:]', symObjAddr: 0x980, symBinAddr: 0x24CE8, symSize: 0xFC } + - { offset: 0x208B3, size: 0x8, addend: 0x0, symName: '+[XSHelper obj2JsonData:]', symObjAddr: 0xA7C, symBinAddr: 0x24DE4, symSize: 0xDC } + - { offset: 0x20913, size: 0x8, addend: 0x0, symName: '+[XSHelper dic2Json:]', symObjAddr: 0xB58, symBinAddr: 0x24EC0, symSize: 0xA8 } + - { offset: 0x20965, size: 0x8, addend: 0x0, symName: '+[XSHelper readFileText:]', symObjAddr: 0xC00, symBinAddr: 0x24F68, symSize: 0x12C } + - { offset: 0x209C5, size: 0x8, addend: 0x0, symName: '+[XSHelper saveFile:data:]', symObjAddr: 0xD2C, symBinAddr: 0x25094, symSize: 0x94 } + - { offset: 0x20A17, size: 0x8, addend: 0x0, symName: '+[XSHelper saveFile:text:]', symObjAddr: 0xDC0, symBinAddr: 0x25128, symSize: 0xCC } + - { offset: 0x20A77, size: 0x8, addend: 0x0, symName: '+[XSHelper rmFiles:]', symObjAddr: 0xE8C, symBinAddr: 0x251F4, symSize: 0x2FC } + - { offset: 0x20B1F, size: 0x8, addend: 0x0, symName: '+[XSHelper str2num:]', symObjAddr: 0x1188, symBinAddr: 0x254F0, symSize: 0xCC } + - { offset: 0x20B7F, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceStr:oldStr:newStr:]', symObjAddr: 0x1254, symBinAddr: 0x255BC, symSize: 0xBC } + - { offset: 0x20BDF, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceMulStr:oldStr:newStr:]', symObjAddr: 0x1310, symBinAddr: 0x25678, symSize: 0x104 } + - { offset: 0x20C69, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceStr:regex:newStr:]', symObjAddr: 0x1414, symBinAddr: 0x2577C, symSize: 0x1E8 } + - { offset: 0x20D33, size: 0x8, addend: 0x0, symName: '+[XSHelper base64Encode:]', symObjAddr: 0x15FC, symBinAddr: 0x25964, symSize: 0xA0 } + - { offset: 0x20D85, size: 0x8, addend: 0x0, symName: '+[XSHelper base64Decode:]', symObjAddr: 0x169C, symBinAddr: 0x25A04, symSize: 0xA8 } + - { offset: 0x20DD7, size: 0x8, addend: 0x0, symName: '+[XSHelper imageFromFile:]', symObjAddr: 0x1744, symBinAddr: 0x25AAC, symSize: 0x74 } + - { offset: 0x20E1B, size: 0x8, addend: 0x0, symName: '+[XSHelper base64StringFromJpgImage:]', symObjAddr: 0x17B8, symBinAddr: 0x25B20, symSize: 0xC8 } + - { offset: 0x20E7B, size: 0x8, addend: 0x0, symName: '+[XSHelper imageFromBase64String:]', symObjAddr: 0x1880, symBinAddr: 0x25BE8, symSize: 0xA8 } + - { offset: 0x20ECD, size: 0x8, addend: 0x0, symName: '+[XSHelper png2jpg:]', symObjAddr: 0x1928, symBinAddr: 0x25C90, symSize: 0xA4 } + - { offset: 0x20F1F, size: 0x8, addend: 0x0, symName: '+[XSHelper getCurTime]', symObjAddr: 0x19CC, symBinAddr: 0x25D34, symSize: 0x64 } + - { offset: 0x20F63, size: 0x8, addend: 0x0, symName: '+[XSHelper performOCROnImage:callback:]', symObjAddr: 0x1A30, symBinAddr: 0x25D98, symSize: 0x178 } + - { offset: 0x20FCE, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke', symObjAddr: 0x1BA8, symBinAddr: 0x25F10, symSize: 0x368 } + - { offset: 0x21065, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_2', symObjAddr: 0x1F10, symBinAddr: 0x26278, symSize: 0x480 } + - { offset: 0x21136, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_3', symObjAddr: 0x2390, symBinAddr: 0x266F8, symSize: 0x3C } + - { offset: 0x21171, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_4', symObjAddr: 0x23CC, symBinAddr: 0x26734, symSize: 0x3C } + - { offset: 0x211BE, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40b, symObjAddr: 0x2408, symBinAddr: 0x26770, symSize: 0x58 } + - { offset: 0x211E2, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke.51', symObjAddr: 0x24A4, symBinAddr: 0x267C8, symSize: 0x3C } + - { offset: 0x2121D, size: 0x8, addend: 0x0, symName: '-[NSData(AES) aesEncrypt:iv:]', symObjAddr: 0x24E0, symBinAddr: 0x26804, symSize: 0x9C } + - { offset: 0x21272, size: 0x8, addend: 0x0, symName: '-[NSData(AES) aesDecrypt:iv:]', symObjAddr: 0x257C, symBinAddr: 0x268A0, symSize: 0x9C } + - { offset: 0x212C7, size: 0x8, addend: 0x0, symName: '-[NSData(AES) AES128operation:key:iv:]', symObjAddr: 0x2618, symBinAddr: 0x2693C, symSize: 0x21C } + - { offset: 0x2138F, size: 0x8, addend: 0x0, symName: '-[NSString(AES) aesEncrypt:iv:]', symObjAddr: 0x2834, symBinAddr: 0x26B58, symSize: 0xF8 } + - { offset: 0x213F3, size: 0x8, addend: 0x0, symName: '-[NSString(AES) aesDecrypt:iv:]', symObjAddr: 0x292C, symBinAddr: 0x26C50, symSize: 0x100 } + - { offset: 0x22C73, size: 0x8, addend: 0x0, symName: '+[NSURLSession(SSLBypass) sessionWithoutSSLValidation]', symObjAddr: 0x0, symBinAddr: 0x26D50, symSize: 0xB4 } + - { offset: 0x2381B, size: 0x8, addend: 0x0, symName: '+[NSURLSession(SSLBypass) sessionWithoutSSLValidation]', symObjAddr: 0x0, symBinAddr: 0x26D50, symSize: 0xB4 } + - { offset: 0x2385F, size: 0x8, addend: 0x0, symName: '-[SSLBypassDelegate URLSession:didReceiveChallenge:completionHandler:]', symObjAddr: 0xB4, symBinAddr: 0x26E04, symSize: 0x180 } + - { offset: 0x238CF, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper init]', symObjAddr: 0x234, symBinAddr: 0x26F84, symSize: 0x108 } + - { offset: 0x23905, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doGET:withCallback:withError:]', symObjAddr: 0x33C, symBinAddr: 0x2708C, symSize: 0x3C8 } + - { offset: 0x239A9, size: 0x8, addend: 0x0, symName: '___45-[XSHttpHelper doGET:withCallback:withError:]_block_invoke', symObjAddr: 0x704, symBinAddr: 0x27454, symSize: 0x13C } + - { offset: 0x23A2E, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40b48b, symObjAddr: 0x840, symBinAddr: 0x27590, symSize: 0x74 } + - { offset: 0x23A52, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doGET:]', symObjAddr: 0x908, symBinAddr: 0x27604, symSize: 0x250 } + - { offset: 0x23AD6, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xB58, symBinAddr: 0x27854, symSize: 0x54 } + - { offset: 0x23AFA, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xBAC, symBinAddr: 0x278A8, symSize: 0x2C } + - { offset: 0x23B16, size: 0x8, addend: 0x0, symName: '___22-[XSHttpHelper doGET:]_block_invoke', symObjAddr: 0xBD8, symBinAddr: 0x278D4, symSize: 0x70 } + - { offset: 0x23B74, size: 0x8, addend: 0x0, symName: '___22-[XSHttpHelper doGET:]_block_invoke.77', symObjAddr: 0xCE0, symBinAddr: 0x27944, symSize: 0x58 } + - { offset: 0x23BBB, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doPOST:json:withCallback:withError:]', symObjAddr: 0xD9C, symBinAddr: 0x2799C, symSize: 0x460 } + - { offset: 0x23C7C, size: 0x8, addend: 0x0, symName: '___51-[XSHttpHelper doPOST:json:withCallback:withError:]_block_invoke', symObjAddr: 0x11FC, symBinAddr: 0x27DFC, symSize: 0x130 } + - { offset: 0x23D01, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doPOST:json:]', symObjAddr: 0x132C, symBinAddr: 0x27F2C, symSize: 0x27C } + - { offset: 0x23D93, size: 0x8, addend: 0x0, symName: '___28-[XSHttpHelper doPOST:json:]_block_invoke', symObjAddr: 0x15A8, symBinAddr: 0x281A8, symSize: 0x70 } + - { offset: 0x23DF1, size: 0x8, addend: 0x0, symName: '___28-[XSHttpHelper doPOST:json:]_block_invoke_2', symObjAddr: 0x1618, symBinAddr: 0x28218, symSize: 0x58 } + - { offset: 0x23E38, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper requestNetworkPermissions]', symObjAddr: 0x1670, symBinAddr: 0x28270, symSize: 0x64 } + - { offset: 0x23E78, size: 0x8, addend: 0x0, symName: '___41-[XSHttpHelper requestNetworkPermissions]_block_invoke', symObjAddr: 0x16D4, symBinAddr: 0x282D4, symSize: 0x5C } + - { offset: 0x23EAE, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setupNetworkConfiguration]', symObjAddr: 0x1730, symBinAddr: 0x28330, symSize: 0x94 } + - { offset: 0x23EEE, size: 0x8, addend: 0x0, symName: '___41-[XSHttpHelper setupNetworkConfiguration]_block_invoke', symObjAddr: 0x17C4, symBinAddr: 0x283C4, symSize: 0x78 } + - { offset: 0x23F24, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper dataTask]', symObjAddr: 0x183C, symBinAddr: 0x2843C, symSize: 0x1C } + - { offset: 0x23F5A, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setDataTask:]', symObjAddr: 0x1858, symBinAddr: 0x28458, symSize: 0x34 } + - { offset: 0x23F98, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper postDataTask]', symObjAddr: 0x188C, symBinAddr: 0x2848C, symSize: 0x1C } + - { offset: 0x23FCE, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setPostDataTask:]', symObjAddr: 0x18A8, symBinAddr: 0x284A8, symSize: 0x34 } + - { offset: 0x2400C, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper .cxx_destruct]', symObjAddr: 0x18DC, symBinAddr: 0x284DC, symSize: 0x58 } + - { offset: 0x24CE5, size: 0x8, addend: 0x0, symName: _XSInitGetSenderId, symObjAddr: 0x0, symBinAddr: 0x28534, symSize: 0x290 } + - { offset: 0x24CF2, size: 0x8, addend: 0x0, symName: '+[XSIosTouch sharedInstance]', symObjAddr: 0x3E0, symBinAddr: 0x28914, symSize: 0x7C } + - { offset: 0x24D1B, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xC010, symBinAddr: 0x695B0, symSize: 0x0 } + - { offset: 0x24D30, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xC018, symBinAddr: 0x695B8, symSize: 0x0 } + - { offset: 0x24EA6, size: 0x8, addend: 0x0, symName: '-[XSIosTouch handleEventSystemFailure]', symObjAddr: 0xAE4, symBinAddr: 0x29018, symSize: 0xB0 } + - { offset: 0x24ECB, size: 0x8, addend: 0x0, symName: _handleEventSystemFailure.failureCount, symObjAddr: 0xC020, symBinAddr: 0x695C0, symSize: 0x0 } + - { offset: 0x24EF4, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Keyboard:down:]', symObjAddr: 0x1D7C, symBinAddr: 0x2A254, symSize: 0xB4 } + - { offset: 0x24F1B, size: 0x8, addend: 0x0, symName: '_Keyboard:down:.client', symObjAddr: 0xC028, symBinAddr: 0x695C8, symSize: 0x0 } + - { offset: 0x24F85, size: 0x8, addend: 0x0, symName: __XSSenderID, symObjAddr: 0xC000, symBinAddr: 0x695A0, symSize: 0x0 } + - { offset: 0x24FA1, size: 0x8, addend: 0x0, symName: __XSIoHIDEventSystemForSenderID, symObjAddr: 0xC008, symBinAddr: 0x695A8, symSize: 0x0 } + - { offset: 0x25452, size: 0x8, addend: 0x0, symName: _XSInitGetSenderId, symObjAddr: 0x0, symBinAddr: 0x28534, symSize: 0x290 } + - { offset: 0x254C9, size: 0x8, addend: 0x0, symName: _XSStartSetSenderIDCallBack, symObjAddr: 0x290, symBinAddr: 0x287C4, symSize: 0x74 } + - { offset: 0x254DE, size: 0x8, addend: 0x0, symName: ___XSInitGetSenderId_block_invoke, symObjAddr: 0x304, symBinAddr: 0x28838, symSize: 0xDC } + - { offset: 0x255B2, size: 0x8, addend: 0x0, symName: '___28+[XSIosTouch sharedInstance]_block_invoke', symObjAddr: 0x45C, symBinAddr: 0x28990, symSize: 0x4C } + - { offset: 0x255DA, size: 0x8, addend: 0x0, symName: '-[XSIosTouch init]', symObjAddr: 0x4A8, symBinAddr: 0x289DC, symSize: 0x330 } + - { offset: 0x25641, size: 0x8, addend: 0x0, symName: '-[XSIosTouch dealloc]', symObjAddr: 0x7D8, symBinAddr: 0x28D0C, symSize: 0xB0 } + - { offset: 0x25673, size: 0x8, addend: 0x0, symName: '-[XSIosTouch cleanupResources]', symObjAddr: 0x888, symBinAddr: 0x28DBC, symSize: 0xB0 } + - { offset: 0x256A5, size: 0x8, addend: 0x0, symName: '-[XSIosTouch checkSystemStatus]', symObjAddr: 0x938, symBinAddr: 0x28E6C, symSize: 0xD8 } + - { offset: 0x256E9, size: 0x8, addend: 0x0, symName: '-[XSIosTouch resetEventSystem]', symObjAddr: 0xA10, symBinAddr: 0x28F44, symSize: 0xD4 } + - { offset: 0x2571B, size: 0x8, addend: 0x0, symName: '-[XSIosTouch getAbsoluteTime]', symObjAddr: 0xB94, symBinAddr: 0x290C8, symSize: 0x40 } + - { offset: 0x257C1, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEvent:type:x:y:]', symObjAddr: 0xBD4, symBinAddr: 0x29108, symSize: 0x3E8 } + - { offset: 0x25967, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchDown:x:y:]', symObjAddr: 0xFBC, symBinAddr: 0x294F0, symSize: 0x48 } + - { offset: 0x259CB, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchMove:x:y:]', symObjAddr: 0x1004, symBinAddr: 0x29538, symSize: 0x48 } + - { offset: 0x25A2F, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchUp:x:y:]', symObjAddr: 0x104C, symBinAddr: 0x29580, symSize: 0x48 } + - { offset: 0x25A93, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateParentEvent]', symObjAddr: 0x1094, symBinAddr: 0x295C8, symSize: 0xB0 } + - { offset: 0x25AE8, size: 0x8, addend: 0x0, symName: '-[XSIosTouch getKeyWindow]', symObjAddr: 0x1144, symBinAddr: 0x29678, symSize: 0x200 } + - { offset: 0x25B37, size: 0x8, addend: 0x0, symName: '-[XSIosTouch postIOHIDEvent:]', symObjAddr: 0x1344, symBinAddr: 0x29878, symSize: 0x318 } + - { offset: 0x25B9D, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Down:x:y:]', symObjAddr: 0x165C, symBinAddr: 0x29B90, symSize: 0x84 } + - { offset: 0x25C29, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Move:x:y:]', symObjAddr: 0x16E0, symBinAddr: 0x29C14, symSize: 0x84 } + - { offset: 0x25CB5, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Up:x:y:]', symObjAddr: 0x1764, symBinAddr: 0x29C98, symSize: 0x84 } + - { offset: 0x25D41, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Tap:x:y:]', symObjAddr: 0x17E8, symBinAddr: 0x29D1C, symSize: 0x128 } + - { offset: 0x25DB0, size: 0x8, addend: 0x0, symName: '___22-[XSIosTouch Tap:x:y:]_block_invoke', symObjAddr: 0x1910, symBinAddr: 0x29E44, symSize: 0x2C4 } + - { offset: 0x25E69, size: 0x8, addend: 0x0, symName: '-[XSIosTouch End:]', symObjAddr: 0x1C30, symBinAddr: 0x2A108, symSize: 0x14C } + - { offset: 0x25EC0, size: 0x8, addend: 0x0, symName: '-[XSIosTouch KeyDown:]', symObjAddr: 0x1E30, symBinAddr: 0x2A308, symSize: 0x38 } + - { offset: 0x25F02, size: 0x8, addend: 0x0, symName: '-[XSIosTouch KeyUp:]', symObjAddr: 0x1E68, symBinAddr: 0x2A340, symSize: 0x38 } + - { offset: 0x25F44, size: 0x8, addend: 0x0, symName: '-[XSIosTouch .cxx_destruct]', symObjAddr: 0x1EA0, symBinAddr: 0x2A378, symSize: 0x48 } + - { offset: 0x25F76, size: 0x8, addend: 0x0, symName: _XSSetSenderIdCallback, symObjAddr: 0x1EE8, symBinAddr: 0x2A3C0, symSize: 0x1B0 } + - { offset: 0x27A7A, size: 0x8, addend: 0x0, symName: '+[XSPhoneConfig sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2A570, symSize: 0x7C } + - { offset: 0x27A93, size: 0x8, addend: 0x0, symName: __configPath, symObjAddr: 0x26F0, symBinAddr: 0x69470, symSize: 0x0 } + - { offset: 0x27AFA, size: 0x8, addend: 0x0, symName: '+[XSPhoneConfig sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2A570, symSize: 0x7C } + - { offset: 0x27B23, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x6600, symBinAddr: 0x695D0, symSize: 0x0 } + - { offset: 0x27B38, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x6608, symBinAddr: 0x695D8, symSize: 0x0 } + - { offset: 0x27CBE, size: 0x8, addend: 0x0, symName: '___31+[XSPhoneConfig sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0x2A5EC, symSize: 0x4C } + - { offset: 0x27CE6, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig init]', symObjAddr: 0xC8, symBinAddr: 0x2A638, symSize: 0xE8 } + - { offset: 0x27D1C, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig encryptAndSavePlist:path:]', symObjAddr: 0x1B0, symBinAddr: 0x2A720, symSize: 0x15C } + - { offset: 0x27D94, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig loadAndDecryptPlistFromFile:]', symObjAddr: 0x30C, symBinAddr: 0x2A87C, symSize: 0x1AC } + - { offset: 0x27E11, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig MyConfig]', symObjAddr: 0x4B8, symBinAddr: 0x2AA28, symSize: 0xA0 } + - { offset: 0x27E51, size: 0x8, addend: 0x0, symName: '___25-[XSPhoneConfig MyConfig]_block_invoke', symObjAddr: 0x558, symBinAddr: 0x2AAC8, symSize: 0x200 } + - { offset: 0x27EC6, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetConfigItem:Val:]', symObjAddr: 0x7B4, symBinAddr: 0x2ACC8, symSize: 0x1E4 } + - { offset: 0x27F3B, size: 0x8, addend: 0x0, symName: '___35-[XSPhoneConfig SetConfigItem:Val:]_block_invoke', symObjAddr: 0x998, symBinAddr: 0x2AEAC, symSize: 0x2BC } + - { offset: 0x2800C, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48r56w, symObjAddr: 0xC54, symBinAddr: 0x2B168, symSize: 0x84 } + - { offset: 0x28030, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48r56w, symObjAddr: 0xCD8, symBinAddr: 0x2B1EC, symSize: 0x60 } + - { offset: 0x2804C, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetMyConfigStrVal:defVal:]', symObjAddr: 0xD38, symBinAddr: 0x2B24C, symSize: 0x1F4 } + - { offset: 0x280C1, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xF2C, symBinAddr: 0x2B440, symSize: 0x54 } + - { offset: 0x280E5, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xF80, symBinAddr: 0x2B494, symSize: 0x2C } + - { offset: 0x28101, size: 0x8, addend: 0x0, symName: '___42-[XSPhoneConfig GetMyConfigStrVal:defVal:]_block_invoke', symObjAddr: 0xFAC, symBinAddr: 0x2B4C0, symSize: 0x214 } + - { offset: 0x2819F, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r48w, symObjAddr: 0x11C0, symBinAddr: 0x2B6D4, symSize: 0x6C } + - { offset: 0x281C3, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r48w, symObjAddr: 0x122C, symBinAddr: 0x2B740, symSize: 0x4C } + - { offset: 0x281DF, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetLongVal:defVal:]', symObjAddr: 0x1278, symBinAddr: 0x2B78C, symSize: 0x170 } + - { offset: 0x28231, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetIPhoneName:]', symObjAddr: 0x13E8, symBinAddr: 0x2B8FC, symSize: 0x70 } + - { offset: 0x28275, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetServerURL:]', symObjAddr: 0x1458, symBinAddr: 0x2B96C, symSize: 0x70 } + - { offset: 0x282B9, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig IPhoneName]', symObjAddr: 0x14C8, symBinAddr: 0x2B9DC, symSize: 0x3C } + - { offset: 0x282EF, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig DeviceId]', symObjAddr: 0x1504, symBinAddr: 0x2BA18, symSize: 0x1CC } + - { offset: 0x2835B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig MainServerURL]', symObjAddr: 0x16D0, symBinAddr: 0x2BBE4, symSize: 0x3C } + - { offset: 0x28391, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig ServerURL]', symObjAddr: 0x170C, symBinAddr: 0x2BC20, symSize: 0x3C } + - { offset: 0x283C7, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetFullServerURL:]', symObjAddr: 0x1748, symBinAddr: 0x2BC5C, symSize: 0xBC } + - { offset: 0x2840B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetMainServerURL:]', symObjAddr: 0x1804, symBinAddr: 0x2BD18, symSize: 0xBC } + - { offset: 0x2844F, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetRemoteIPURL]', symObjAddr: 0x18C0, symBinAddr: 0x2BDD4, symSize: 0x3C } + - { offset: 0x28485, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig ApiKey]', symObjAddr: 0x18FC, symBinAddr: 0x2BE10, symSize: 0x3C } + - { offset: 0x284BB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetApiKey:]', symObjAddr: 0x1938, symBinAddr: 0x2BE4C, symSize: 0x64 } + - { offset: 0x284FB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig LastReboot]', symObjAddr: 0x199C, symBinAddr: 0x2BEB0, symSize: 0x38 } + - { offset: 0x28531, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetLastReboot:]', symObjAddr: 0x19D4, symBinAddr: 0x2BEE8, symSize: 0x74 } + - { offset: 0x28571, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SenderId]', symObjAddr: 0x1A48, symBinAddr: 0x2BF5C, symSize: 0x38 } + - { offset: 0x285A7, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetSenderId:]', symObjAddr: 0x1A80, symBinAddr: 0x2BF94, symSize: 0x74 } + - { offset: 0x285E9, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetLastOverTime]', symObjAddr: 0x1AF4, symBinAddr: 0x2C008, symSize: 0x204 } + - { offset: 0x2867B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetLastOverTime:]', symObjAddr: 0x1CF8, symBinAddr: 0x2C20C, symSize: 0x150 } + - { offset: 0x286EB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig reLoad]', symObjAddr: 0x1E48, symBinAddr: 0x2C35C, symSize: 0x9C } + - { offset: 0x2871E, size: 0x8, addend: 0x0, symName: '___23-[XSPhoneConfig reLoad]_block_invoke', symObjAddr: 0x1EE4, symBinAddr: 0x2C3F8, symSize: 0xA8 } + - { offset: 0x2875E, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig dealloc]', symObjAddr: 0x1FF0, symBinAddr: 0x2C4A0, symSize: 0x68 } + - { offset: 0x28791, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig .cxx_destruct]', symObjAddr: 0x2058, symBinAddr: 0x2C508, symSize: 0x48 } + - { offset: 0x28D45, size: 0x8, addend: 0x0, symName: '+[XSPhoneInfo sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2C550, symSize: 0x7C } + - { offset: 0x28D52, size: 0x8, addend: 0x0, symName: '+[XSPhoneInfo sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2C550, symSize: 0x7C } + - { offset: 0x28D7B, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x97A0, symBinAddr: 0x695E0, symSize: 0x0 } + - { offset: 0x28D90, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x97A8, symBinAddr: 0x695E8, symSize: 0x0 } + - { offset: 0x293FF, size: 0x8, addend: 0x0, symName: '___29+[XSPhoneInfo sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0x2C5CC, symSize: 0x4C } + - { offset: 0x29427, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo init]', symObjAddr: 0xC8, symBinAddr: 0x2C618, symSize: 0xFC } + - { offset: 0x2945D, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setupBatteryMonitoring]', symObjAddr: 0x1C4, symBinAddr: 0x2C714, symSize: 0x104 } + - { offset: 0x2948F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo startBatteryMonitoring]', symObjAddr: 0x2C8, symBinAddr: 0x2C818, symSize: 0xB8 } + - { offset: 0x294C1, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateBatteryInfo]', symObjAddr: 0x380, symBinAddr: 0x2C8D0, symSize: 0xFC } + - { offset: 0x294F3, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateDetailedBatteryInfo]', symObjAddr: 0x47C, symBinAddr: 0x2C9CC, symSize: 0x4A0 } + - { offset: 0x29594, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateBatteryStatus:]', symObjAddr: 0x91C, symBinAddr: 0x2CE6C, symSize: 0x114 } + - { offset: 0x295E2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getBatteryInfo]', symObjAddr: 0xA30, symBinAddr: 0x2CF80, symSize: 0x32C } + - { offset: 0x2961A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo stopBatteryMonitoring]', symObjAddr: 0xD5C, symBinAddr: 0x2D2AC, symSize: 0x8C } + - { offset: 0x2964C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryLevelDidChange:]', symObjAddr: 0xDE8, symBinAddr: 0x2D338, symSize: 0x58 } + - { offset: 0x2968C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryStateDidChange:]', symObjAddr: 0xE40, symBinAddr: 0x2D390, symSize: 0x58 } + - { offset: 0x296CC, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateMemoryInfo]', symObjAddr: 0xE98, symBinAddr: 0x2D3E8, symSize: 0x148 } + - { offset: 0x29736, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getMemoryUsageForPid:]', symObjAddr: 0xFE0, symBinAddr: 0x2D530, symSize: 0x90 } + - { offset: 0x297A4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo handleCriticalMemoryPressure]', symObjAddr: 0x1070, symBinAddr: 0x2D5C0, symSize: 0x128 } + - { offset: 0x297D6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo handleWarningMemoryPressure]', symObjAddr: 0x1198, symBinAddr: 0x2D6E8, symSize: 0x128 } + - { offset: 0x29809, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo startMemoryMonitoring]', symObjAddr: 0x12C0, symBinAddr: 0x2D810, symSize: 0x78 } + - { offset: 0x2983C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo stopMemoryMonitoring]', symObjAddr: 0x1338, symBinAddr: 0x2D888, symSize: 0x60 } + - { offset: 0x2986F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo checkMemoryStatus]', symObjAddr: 0x1398, symBinAddr: 0x2D8E8, symSize: 0x2C } + - { offset: 0x298A2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo dealloc]', symObjAddr: 0x13C4, symBinAddr: 0x2D914, symSize: 0xF0 } + - { offset: 0x298D5, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo IPAddress]', symObjAddr: 0x14B4, symBinAddr: 0x2DA04, symSize: 0x158 } + - { offset: 0x29930, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x160C, symBinAddr: 0x2DB5C, symSize: 0x54 } + - { offset: 0x29954, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x1660, symBinAddr: 0x2DBB0, symSize: 0x2C } + - { offset: 0x29970, size: 0x8, addend: 0x0, symName: '___24-[XSPhoneInfo IPAddress]_block_invoke', symObjAddr: 0x168C, symBinAddr: 0x2DBDC, symSize: 0xB0 } + - { offset: 0x299DF, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32r, symObjAddr: 0x173C, symBinAddr: 0x2DC8C, symSize: 0x38 } + - { offset: 0x29A03, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32r, symObjAddr: 0x1774, symBinAddr: 0x2DCC4, symSize: 0x2C } + - { offset: 0x29A1F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getIPAddresses]', symObjAddr: 0x17A0, symBinAddr: 0x2DCF0, symSize: 0x2E4 } + - { offset: 0x29B2B, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo CurrentThermalState]', symObjAddr: 0x1A84, symBinAddr: 0x2DFD4, symSize: 0x134 } + - { offset: 0x29B71, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo DiskSize]', symObjAddr: 0x1BB8, symBinAddr: 0x2E108, symSize: 0x2D4 } + - { offset: 0x29C1B, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo IPhoneStatus]', symObjAddr: 0x1E8C, symBinAddr: 0x2E3DC, symSize: 0x210 } + - { offset: 0x29C8E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryLevel]', symObjAddr: 0x209C, symBinAddr: 0x2E5EC, symSize: 0x1C } + - { offset: 0x29CC4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isFullyCharged]', symObjAddr: 0x20B8, symBinAddr: 0x2E608, symSize: 0x20 } + - { offset: 0x29CFA, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryVoltage]', symObjAddr: 0x20D8, symBinAddr: 0x2E628, symSize: 0x1C } + - { offset: 0x29D30, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo maxCapacity]', symObjAddr: 0x20F4, symBinAddr: 0x2E644, symSize: 0x1C } + - { offset: 0x29D66, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo currentCapacity]', symObjAddr: 0x2110, symBinAddr: 0x2E660, symSize: 0x1C } + - { offset: 0x29D9C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo designCapacity]', symObjAddr: 0x212C, symBinAddr: 0x2E67C, symSize: 0x1C } + - { offset: 0x29DD2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo cycleCount]', symObjAddr: 0x2148, symBinAddr: 0x2E698, symSize: 0x1C } + - { offset: 0x29E08, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryHealth]', symObjAddr: 0x2164, symBinAddr: 0x2E6B4, symSize: 0x1C } + - { offset: 0x29E3E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isCharging]', symObjAddr: 0x2180, symBinAddr: 0x2E6D0, symSize: 0x20 } + - { offset: 0x29E74, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryStatus]', symObjAddr: 0x21A0, symBinAddr: 0x2E6F0, symSize: 0x1C } + - { offset: 0x29EAA, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setBatteryStatus:]', symObjAddr: 0x21BC, symBinAddr: 0x2E70C, symSize: 0x38 } + - { offset: 0x29EE8, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo temperature]', symObjAddr: 0x21F4, symBinAddr: 0x2E744, symSize: 0x1C } + - { offset: 0x29F1E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo voltage]', symObjAddr: 0x2210, symBinAddr: 0x2E760, symSize: 0x1C } + - { offset: 0x29F54, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo totalMemory]', symObjAddr: 0x222C, symBinAddr: 0x2E77C, symSize: 0x1C } + - { offset: 0x29F8A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo availableMemory]', symObjAddr: 0x2248, symBinAddr: 0x2E798, symSize: 0x1C } + - { offset: 0x29FC0, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo usedMemory]', symObjAddr: 0x2264, symBinAddr: 0x2E7B4, symSize: 0x1C } + - { offset: 0x29FF6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo memoryUsage]', symObjAddr: 0x2280, symBinAddr: 0x2E7D0, symSize: 0x1C } + - { offset: 0x2A02C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo pageSize]', symObjAddr: 0x229C, symBinAddr: 0x2E7EC, symSize: 0x1C } + - { offset: 0x2A062, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo remoteIp]', symObjAddr: 0x22B8, symBinAddr: 0x2E808, symSize: 0x1C } + - { offset: 0x2A098, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setRemoteIp:]', symObjAddr: 0x22D4, symBinAddr: 0x2E824, symSize: 0x38 } + - { offset: 0x2A0D6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo monitorTimer]', symObjAddr: 0x230C, symBinAddr: 0x2E85C, symSize: 0x1C } + - { offset: 0x2A10C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setMonitorTimer:]', symObjAddr: 0x2328, symBinAddr: 0x2E878, symSize: 0x34 } + - { offset: 0x2A14A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isMonitoring]', symObjAddr: 0x235C, symBinAddr: 0x2E8AC, symSize: 0x20 } + - { offset: 0x2A180, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setIsMonitoring:]', symObjAddr: 0x237C, symBinAddr: 0x2E8CC, symSize: 0x28 } + - { offset: 0x2A1BE, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo memoryWarningHandler]', symObjAddr: 0x23A4, symBinAddr: 0x2E8F4, symSize: 0x1C } + - { offset: 0x2A1F4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setMemoryWarningHandler:]', symObjAddr: 0x23C0, symBinAddr: 0x2E910, symSize: 0x38 } + - { offset: 0x2A232, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo .cxx_destruct]', symObjAddr: 0x23F8, symBinAddr: 0x2E948, symSize: 0x78 } + - { offset: 0x2AA21, size: 0x8, addend: 0x0, symName: '+[XUDPServer sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2E9C0, symSize: 0x7C } + - { offset: 0x2AA2E, size: 0x8, addend: 0x0, symName: '+[XUDPServer sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2E9C0, symSize: 0x7C } + - { offset: 0x2AA57, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x2E90, symBinAddr: 0x695F0, symSize: 0x0 } + - { offset: 0x2AA6C, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x2E98, symBinAddr: 0x695F8, symSize: 0x0 } + - { offset: 0x2ABE6, size: 0x8, addend: 0x0, symName: '___28+[XUDPServer sharedInstance]_block_invoke', symObjAddr: 0x7C, symBinAddr: 0x2EA3C, symSize: 0x4C } + - { offset: 0x2AC0E, size: 0x8, addend: 0x0, symName: '-[XUDPServer init]', symObjAddr: 0xC8, symBinAddr: 0x2EA88, symSize: 0xB0 } + - { offset: 0x2AC44, size: 0x8, addend: 0x0, symName: '-[XUDPServer start]', symObjAddr: 0x178, symBinAddr: 0x2EB38, symSize: 0x188 } + - { offset: 0x2AC92, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didConnectToAddress:]', symObjAddr: 0x300, symBinAddr: 0x2ECC0, symSize: 0xB4 } + - { offset: 0x2ACE0, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didReceiveData:fromAddress:withFilterContext:]', symObjAddr: 0x3B4, symBinAddr: 0x2ED74, symSize: 0x210 } + - { offset: 0x2AD83, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didNotConnect:]', symObjAddr: 0x5C4, symBinAddr: 0x2EF84, symSize: 0x88 } + - { offset: 0x2ADD1, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didSendDataWithTag:]', symObjAddr: 0x64C, symBinAddr: 0x2F00C, symSize: 0x70 } + - { offset: 0x2AE1F, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didNotSendDataWithTag:dueToError:]', symObjAddr: 0x6BC, symBinAddr: 0x2F07C, symSize: 0x94 } + - { offset: 0x2AE7B, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocketDidClose:withError:]', symObjAddr: 0x750, symBinAddr: 0x2F110, symSize: 0x88 } + - { offset: 0x2AEC9, size: 0x8, addend: 0x0, symName: '-[XUDPServer .cxx_destruct]', symObjAddr: 0x7D8, symBinAddr: 0x2F198, symSize: 0x30 } + - { offset: 0x2B135, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket init]', symObjAddr: 0x0, symBinAddr: 0x2F1C8, symSize: 0x90 } + - { offset: 0x2B14E, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketException, symObjAddr: 0x18560, symBinAddr: 0x58D88, symSize: 0x0 } + - { offset: 0x2B1C6, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketErrorDomain, symObjAddr: 0x18568, symBinAddr: 0x58D90, symSize: 0x0 } + - { offset: 0x2B1DB, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketQueueName, symObjAddr: 0x18570, symBinAddr: 0x58D98, symSize: 0x0 } + - { offset: 0x2B1F0, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketThreadName, symObjAddr: 0x18578, symBinAddr: 0x58DA0, symSize: 0x0 } + - { offset: 0x2B1F9, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket startListenerThreadIfNeeded]', symObjAddr: 0x14228, symBinAddr: 0x430A0, symSize: 0xA8 } + - { offset: 0x2B220, size: 0x8, addend: 0x0, symName: _startListenerThreadIfNeeded.predicate, symObjAddr: 0x38BD8, symBinAddr: 0x69600, symSize: 0x0 } + - { offset: 0x2B29D, size: 0x8, addend: 0x0, symName: _listenerThread, symObjAddr: 0x38BE0, symBinAddr: 0x69608, symSize: 0x0 } + - { offset: 0x2BCCE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket init]', symObjAddr: 0x0, symBinAddr: 0x2F1C8, symSize: 0x90 } + - { offset: 0x2BD05, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket initWithData:timeout:tag:]', symObjAddr: 0x90, symBinAddr: 0x2F258, symSize: 0x10C } + - { offset: 0x2BD69, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket .cxx_destruct]', symObjAddr: 0x19C, symBinAddr: 0x2F364, symSize: 0x68 } + - { offset: 0x2BD9C, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSpecialPacket init]', symObjAddr: 0x204, symBinAddr: 0x2F3CC, symSize: 0x94 } + - { offset: 0x2BDD3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSpecialPacket .cxx_destruct]', symObjAddr: 0x298, symBinAddr: 0x2F460, symSize: 0x48 } + - { offset: 0x2BE06, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket init]', symObjAddr: 0x2E0, symBinAddr: 0x2F4A8, symSize: 0x74 } + - { offset: 0x2BE3D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithSocketQueue:]', symObjAddr: 0x354, symBinAddr: 0x2F51C, symSize: 0x9C } + - { offset: 0x2BE83, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithDelegate:delegateQueue:]', symObjAddr: 0x3F0, symBinAddr: 0x2F5B8, symSize: 0xC0 } + - { offset: 0x2BED8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithDelegate:delegateQueue:socketQueue:]', symObjAddr: 0x4B0, symBinAddr: 0x2F678, symSize: 0x478 } + - { offset: 0x2BF59, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket dealloc]', symObjAddr: 0x928, symBinAddr: 0x2FAF0, symSize: 0x158 } + - { offset: 0x2BF8C, size: 0x8, addend: 0x0, symName: '___28-[GCDAsyncUdpSocket dealloc]_block_invoke', symObjAddr: 0xA80, symBinAddr: 0x2FC48, symSize: 0x34 } + - { offset: 0x2BFCC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket delegate]', symObjAddr: 0xB18, symBinAddr: 0x2FC7C, symSize: 0x154 } + - { offset: 0x2C026, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xC6C, symBinAddr: 0x2FDD0, symSize: 0x54 } + - { offset: 0x2C04A, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xCC0, symBinAddr: 0x2FE24, symSize: 0x2C } + - { offset: 0x2C066, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket delegate]_block_invoke', symObjAddr: 0xCEC, symBinAddr: 0x2FE50, symSize: 0x5C } + - { offset: 0x2C0BE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:synchronously:]', symObjAddr: 0xDE0, symBinAddr: 0x2FEAC, symSize: 0x14C } + - { offset: 0x2C11E, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket setDelegate:synchronously:]_block_invoke', symObjAddr: 0xF2C, symBinAddr: 0x2FFF8, symSize: 0x38 } + - { offset: 0x2C170, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:]', symObjAddr: 0x1000, symBinAddr: 0x30030, symSize: 0x64 } + - { offset: 0x2C1B2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegate:]', symObjAddr: 0x1064, symBinAddr: 0x30094, symSize: 0x64 } + - { offset: 0x2C1F4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket delegateQueue]', symObjAddr: 0x10C8, symBinAddr: 0x300F8, symSize: 0x15C } + - { offset: 0x2C24E, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket delegateQueue]_block_invoke', symObjAddr: 0x1224, symBinAddr: 0x30254, symSize: 0x40 } + - { offset: 0x2C2A6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegateQueue:synchronously:]', symObjAddr: 0x1264, symBinAddr: 0x30294, symSize: 0x14C } + - { offset: 0x2C306, size: 0x8, addend: 0x0, symName: '___52-[GCDAsyncUdpSocket setDelegateQueue:synchronously:]_block_invoke', symObjAddr: 0x13B0, symBinAddr: 0x303E0, symSize: 0x38 } + - { offset: 0x2C358, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegateQueue:]', symObjAddr: 0x13E8, symBinAddr: 0x30418, symSize: 0x64 } + - { offset: 0x2C39A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegateQueue:]', symObjAddr: 0x144C, symBinAddr: 0x3047C, symSize: 0x64 } + - { offset: 0x2C3DC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getDelegate:delegateQueue:]', symObjAddr: 0x14B0, symBinAddr: 0x304E0, symSize: 0x23C } + - { offset: 0x2C465, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket getDelegate:delegateQueue:]_block_invoke', symObjAddr: 0x16EC, symBinAddr: 0x3071C, symSize: 0x78 } + - { offset: 0x2C4D5, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r48r, symObjAddr: 0x1764, symBinAddr: 0x30794, symSize: 0x74 } + - { offset: 0x2C4F9, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r48r, symObjAddr: 0x17D8, symBinAddr: 0x30808, symSize: 0x54 } + - { offset: 0x2C515, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:delegateQueue:synchronously:]', symObjAddr: 0x182C, symBinAddr: 0x3085C, symSize: 0x190 } + - { offset: 0x2C584, size: 0x8, addend: 0x0, symName: '___61-[GCDAsyncUdpSocket setDelegate:delegateQueue:synchronously:]_block_invoke', symObjAddr: 0x19BC, symBinAddr: 0x309EC, symSize: 0x50 } + - { offset: 0x2C5E8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:delegateQueue:]', symObjAddr: 0x1AD0, symBinAddr: 0x30A3C, symSize: 0x8C } + - { offset: 0x2C639, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegate:delegateQueue:]', symObjAddr: 0x1B5C, symBinAddr: 0x30AC8, symSize: 0x8C } + - { offset: 0x2C68A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4Enabled]', symObjAddr: 0x1BE8, symBinAddr: 0x30B54, symSize: 0x14C } + - { offset: 0x2C6E4, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket isIPv4Enabled]_block_invoke', symObjAddr: 0x1D34, symBinAddr: 0x30CA0, symSize: 0x38 } + - { offset: 0x2C73C, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPv4Enabled:]', symObjAddr: 0x1D6C, symBinAddr: 0x30CD8, symSize: 0xE4 } + - { offset: 0x2C78D, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket setIPv4Enabled:]_block_invoke', symObjAddr: 0x1E50, symBinAddr: 0x30DBC, symSize: 0x5C } + - { offset: 0x2C7DF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6Enabled]', symObjAddr: 0x1EAC, symBinAddr: 0x30E18, symSize: 0x14C } + - { offset: 0x2C839, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket isIPv6Enabled]_block_invoke', symObjAddr: 0x1FF8, symBinAddr: 0x30F64, symSize: 0x38 } + - { offset: 0x2C891, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPv6Enabled:]', symObjAddr: 0x2030, symBinAddr: 0x30F9C, symSize: 0xE4 } + - { offset: 0x2C8E2, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket setIPv6Enabled:]_block_invoke', symObjAddr: 0x2114, symBinAddr: 0x31080, symSize: 0x5C } + - { offset: 0x2C934, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4Preferred]', symObjAddr: 0x2170, symBinAddr: 0x310DC, symSize: 0x14C } + - { offset: 0x2C98E, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket isIPv4Preferred]_block_invoke', symObjAddr: 0x22BC, symBinAddr: 0x31228, symSize: 0x44 } + - { offset: 0x2C9E6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6Preferred]', symObjAddr: 0x2300, symBinAddr: 0x3126C, symSize: 0x14C } + - { offset: 0x2CA40, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket isIPv6Preferred]_block_invoke', symObjAddr: 0x244C, symBinAddr: 0x313B8, symSize: 0x44 } + - { offset: 0x2CA98, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPVersionNeutral]', symObjAddr: 0x2490, symBinAddr: 0x313FC, symSize: 0x14C } + - { offset: 0x2CAF2, size: 0x8, addend: 0x0, symName: '___39-[GCDAsyncUdpSocket isIPVersionNeutral]_block_invoke', symObjAddr: 0x25DC, symBinAddr: 0x31548, symSize: 0x38 } + - { offset: 0x2CB4A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setPreferIPv4]', symObjAddr: 0x2614, symBinAddr: 0x31580, symSize: 0xD4 } + - { offset: 0x2CB8C, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket setPreferIPv4]_block_invoke', symObjAddr: 0x26E8, symBinAddr: 0x31654, symSize: 0x3C } + - { offset: 0x2CBCC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setPreferIPv6]', symObjAddr: 0x2724, symBinAddr: 0x31690, symSize: 0xD4 } + - { offset: 0x2CC0E, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket setPreferIPv6]_block_invoke', symObjAddr: 0x27F8, symBinAddr: 0x31764, symSize: 0x3C } + - { offset: 0x2CC4E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPVersionNeutral]', symObjAddr: 0x2834, symBinAddr: 0x317A0, symSize: 0xD4 } + - { offset: 0x2CC90, size: 0x8, addend: 0x0, symName: '___40-[GCDAsyncUdpSocket setIPVersionNeutral]_block_invoke', symObjAddr: 0x2908, symBinAddr: 0x31874, symSize: 0x3C } + - { offset: 0x2CCD0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxReceiveIPv4BufferSize]', symObjAddr: 0x2944, symBinAddr: 0x318B0, symSize: 0x148 } + - { offset: 0x2CD2A, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket maxReceiveIPv4BufferSize]_block_invoke', symObjAddr: 0x2A8C, symBinAddr: 0x319F8, symSize: 0x30 } + - { offset: 0x2CD82, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxReceiveIPv4BufferSize:]', symObjAddr: 0x2ABC, symBinAddr: 0x31A28, symSize: 0xE0 } + - { offset: 0x2CDD3, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket setMaxReceiveIPv4BufferSize:]_block_invoke', symObjAddr: 0x2B9C, symBinAddr: 0x31B08, symSize: 0x28 } + - { offset: 0x2CE25, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxReceiveIPv6BufferSize]', symObjAddr: 0x2BC4, symBinAddr: 0x31B30, symSize: 0x148 } + - { offset: 0x2CE7F, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket maxReceiveIPv6BufferSize]_block_invoke', symObjAddr: 0x2D0C, symBinAddr: 0x31C78, symSize: 0x30 } + - { offset: 0x2CED7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxReceiveIPv6BufferSize:]', symObjAddr: 0x2D3C, symBinAddr: 0x31CA8, symSize: 0xE0 } + - { offset: 0x2CF28, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket setMaxReceiveIPv6BufferSize:]_block_invoke', symObjAddr: 0x2E1C, symBinAddr: 0x31D88, symSize: 0x28 } + - { offset: 0x2CF7A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxSendBufferSize:]', symObjAddr: 0x2E44, symBinAddr: 0x31DB0, symSize: 0xE0 } + - { offset: 0x2CFCB, size: 0x8, addend: 0x0, symName: '___42-[GCDAsyncUdpSocket setMaxSendBufferSize:]_block_invoke', symObjAddr: 0x2F24, symBinAddr: 0x31E90, symSize: 0x28 } + - { offset: 0x2D01D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxSendBufferSize]', symObjAddr: 0x2F4C, symBinAddr: 0x31EB8, symSize: 0x148 } + - { offset: 0x2D077, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket maxSendBufferSize]_block_invoke', symObjAddr: 0x3094, symBinAddr: 0x32000, symSize: 0x30 } + - { offset: 0x2D0CF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket userData]', symObjAddr: 0x30C4, symBinAddr: 0x32030, symSize: 0x17C } + - { offset: 0x2D12A, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket userData]_block_invoke', symObjAddr: 0x3240, symBinAddr: 0x321AC, symSize: 0x40 } + - { offset: 0x2D182, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setUserData:]', symObjAddr: 0x3280, symBinAddr: 0x321EC, symSize: 0x11C } + - { offset: 0x2D1D3, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket setUserData:]_block_invoke', symObjAddr: 0x339C, symBinAddr: 0x32308, symSize: 0x5C } + - { offset: 0x2D225, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidConnectToAddress:]', symObjAddr: 0x33F8, symBinAddr: 0x32364, symSize: 0x188 } + - { offset: 0x2D28B, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket notifyDidConnectToAddress:]_block_invoke', symObjAddr: 0x3580, symBinAddr: 0x324EC, symSize: 0x50 } + - { offset: 0x2D2EF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidNotConnect:]', symObjAddr: 0x35D0, symBinAddr: 0x3253C, symSize: 0x164 } + - { offset: 0x2D340, size: 0x8, addend: 0x0, symName: '___41-[GCDAsyncUdpSocket notifyDidNotConnect:]_block_invoke', symObjAddr: 0x3734, symBinAddr: 0x326A0, symSize: 0x50 } + - { offset: 0x2D3A4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidSendDataWithTag:]', symObjAddr: 0x3784, symBinAddr: 0x326F0, symSize: 0x120 } + - { offset: 0x2D3F5, size: 0x8, addend: 0x0, symName: '___46-[GCDAsyncUdpSocket notifyDidSendDataWithTag:]_block_invoke', symObjAddr: 0x38A4, symBinAddr: 0x32810, symSize: 0x50 } + - { offset: 0x2D459, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidNotSendDataWithTag:dueToError:]', symObjAddr: 0x38F4, symBinAddr: 0x32860, symSize: 0x170 } + - { offset: 0x2D4B9, size: 0x8, addend: 0x0, symName: '___60-[GCDAsyncUdpSocket notifyDidNotSendDataWithTag:dueToError:]_block_invoke', symObjAddr: 0x3A64, symBinAddr: 0x329D0, symSize: 0x54 } + - { offset: 0x2D52F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidReceiveData:fromAddress:withFilterContext:]', symObjAddr: 0x3AB8, symBinAddr: 0x32A24, symSize: 0x204 } + - { offset: 0x2D5AD, size: 0x8, addend: 0x0, symName: '___72-[GCDAsyncUdpSocket notifyDidReceiveData:fromAddress:withFilterContext:]_block_invoke', symObjAddr: 0x3CBC, symBinAddr: 0x32C28, symSize: 0x58 } + - { offset: 0x2D635, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56s64s, symObjAddr: 0x3D14, symBinAddr: 0x32C80, symSize: 0xA0 } + - { offset: 0x2D659, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56s64s, symObjAddr: 0x3DB4, symBinAddr: 0x32D20, symSize: 0x74 } + - { offset: 0x2D675, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidCloseWithError:]', symObjAddr: 0x3E28, symBinAddr: 0x32D94, symSize: 0x164 } + - { offset: 0x2D6C6, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket notifyDidCloseWithError:]_block_invoke', symObjAddr: 0x3F8C, symBinAddr: 0x32EF8, symSize: 0x50 } + - { offset: 0x2D72A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket badConfigError:]', symObjAddr: 0x3FDC, symBinAddr: 0x32F48, symSize: 0x108 } + - { offset: 0x2D77F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket badParamError:]', symObjAddr: 0x40E4, symBinAddr: 0x33050, symSize: 0x104 } + - { offset: 0x2D7D4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket gaiError:]', symObjAddr: 0x41E8, symBinAddr: 0x33154, symSize: 0x12C } + - { offset: 0x2D839, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket errnoErrorWithReason:]', symObjAddr: 0x4314, symBinAddr: 0x33280, symSize: 0x1F0 } + - { offset: 0x2D8A1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket errnoError]', symObjAddr: 0x4504, symBinAddr: 0x33470, symSize: 0x30 } + - { offset: 0x2D8D8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendTimeoutError]', symObjAddr: 0x4534, symBinAddr: 0x334A0, symSize: 0x14C } + - { offset: 0x2D92D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socketClosedError]', symObjAddr: 0x4680, symBinAddr: 0x335EC, symSize: 0x14C } + - { offset: 0x2D982, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket otherError:]', symObjAddr: 0x47CC, symBinAddr: 0x33738, symSize: 0x104 } + - { offset: 0x2D9D7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preOp:]', symObjAddr: 0x48D0, symBinAddr: 0x3383C, symSize: 0x1E8 } + - { offset: 0x2DA47, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]', symObjAddr: 0x4AB8, symBinAddr: 0x33A24, symSize: 0x2CC } + - { offset: 0x2DAF4, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke', symObjAddr: 0x4D84, symBinAddr: 0x33CF0, symSize: 0x50 } + - { offset: 0x2DB42, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke.81', symObjAddr: 0x4E2C, symBinAddr: 0x33D40, symSize: 0x5E0 } + - { offset: 0x2DC9E, size: 0x8, addend: 0x0, symName: __OSSwapInt16, symObjAddr: 0x540C, symBinAddr: 0x34320, symSize: 0x24 } + - { offset: 0x2DCC6, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke_2', symObjAddr: 0x5430, symBinAddr: 0x34344, symSize: 0x50 } + - { offset: 0x2DD26, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48b, symObjAddr: 0x5480, symBinAddr: 0x34394, symSize: 0x70 } + - { offset: 0x2DD4A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getAddress:error:fromAddresses:]', symObjAddr: 0x54F0, symBinAddr: 0x34404, symSize: 0xBC0 } + - { offset: 0x2DF85, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket convertIntefaceDescription:port:intoAddress4:address6:]', symObjAddr: 0x60B0, symBinAddr: 0x34FC4, symSize: 0x690 } + - { offset: 0x2E1C2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket convertNumericHost:port:intoAddress4:address6:]', symObjAddr: 0x6740, symBinAddr: 0x35654, symSize: 0x2BC } + - { offset: 0x2E297, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnectedToAddress4:]', symObjAddr: 0x69FC, symBinAddr: 0x35910, symSize: 0x2A4 } + - { offset: 0x2E2FB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnectedToAddress6:]', symObjAddr: 0x6CA0, symBinAddr: 0x35BB4, symSize: 0x2A4 } + - { offset: 0x2E35F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket indexOfInterfaceAddr4:]', symObjAddr: 0x6F44, symBinAddr: 0x35E58, symSize: 0x15C } + - { offset: 0x2E3FE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket indexOfInterfaceAddr6:]', symObjAddr: 0x70A0, symBinAddr: 0x35FB4, symSize: 0x15C } + - { offset: 0x2E49D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]', symObjAddr: 0x71FC, symBinAddr: 0x36110, symSize: 0x334 } + - { offset: 0x2E4F5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke', symObjAddr: 0x7530, symBinAddr: 0x36444, symSize: 0xE8 } + - { offset: 0x2E535, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke_2', symObjAddr: 0x7618, symBinAddr: 0x3652C, symSize: 0x98 } + - { offset: 0x2E575, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke_3', symObjAddr: 0x76B0, symBinAddr: 0x365C4, symSize: 0x58 } + - { offset: 0x2E5C9, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke.109', symObjAddr: 0x776C, symBinAddr: 0x3661C, symSize: 0x58 } + - { offset: 0x2E61D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]', symObjAddr: 0x77C4, symBinAddr: 0x36674, symSize: 0x334 } + - { offset: 0x2E675, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke', symObjAddr: 0x7AF8, symBinAddr: 0x369A8, symSize: 0xE8 } + - { offset: 0x2E6B5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_2', symObjAddr: 0x7BE0, symBinAddr: 0x36A90, symSize: 0x98 } + - { offset: 0x2E6F5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_3', symObjAddr: 0x7C78, symBinAddr: 0x36B28, symSize: 0x58 } + - { offset: 0x2E749, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_4', symObjAddr: 0x7CD0, symBinAddr: 0x36B80, symSize: 0x58 } + - { offset: 0x2E79D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createSocket4:socket6:error:]', symObjAddr: 0x7D28, symBinAddr: 0x36BD8, symSize: 0x2E8 } + - { offset: 0x2E810, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket createSocket4:socket6:error:]_block_invoke', symObjAddr: 0x8010, symBinAddr: 0x36EC0, symSize: 0x394 } + - { offset: 0x2E8BF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createSockets:]', symObjAddr: 0x83A4, symBinAddr: 0x37254, symSize: 0x64 } + - { offset: 0x2E923, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendSend4Source]', symObjAddr: 0x8408, symBinAddr: 0x372B8, symSize: 0x60 } + - { offset: 0x2E956, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendSend6Source]', symObjAddr: 0x8468, symBinAddr: 0x37318, symSize: 0x60 } + - { offset: 0x2E989, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeSend4Source]', symObjAddr: 0x84C8, symBinAddr: 0x37378, symSize: 0x60 } + - { offset: 0x2E9BC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeSend6Source]', symObjAddr: 0x8528, symBinAddr: 0x373D8, symSize: 0x60 } + - { offset: 0x2E9EF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendReceive4Source]', symObjAddr: 0x8588, symBinAddr: 0x37438, symSize: 0x60 } + - { offset: 0x2EA22, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendReceive6Source]', symObjAddr: 0x85E8, symBinAddr: 0x37498, symSize: 0x60 } + - { offset: 0x2EA55, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeReceive4Source]', symObjAddr: 0x8648, symBinAddr: 0x374F8, symSize: 0x60 } + - { offset: 0x2EA88, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeReceive6Source]', symObjAddr: 0x86A8, symBinAddr: 0x37558, symSize: 0x60 } + - { offset: 0x2EABB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSocket4]', symObjAddr: 0x8708, symBinAddr: 0x375B8, symSize: 0xD8 } + - { offset: 0x2EAEE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSocket6]', symObjAddr: 0x87E0, symBinAddr: 0x37690, symSize: 0xD8 } + - { offset: 0x2EB21, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSockets]', symObjAddr: 0x88B8, symBinAddr: 0x37768, symSize: 0x48 } + - { offset: 0x2EB54, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getLocalAddress:host:port:forSocket:withFamily:]', symObjAddr: 0x8900, symBinAddr: 0x377B0, symSize: 0x2A8 } + - { offset: 0x2EC63, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedLocalAddress4Info]', symObjAddr: 0x8BA8, symBinAddr: 0x37A58, symSize: 0x19C } + - { offset: 0x2ECC3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedLocalAddress6Info]', symObjAddr: 0x8D44, symBinAddr: 0x37BF4, symSize: 0x19C } + - { offset: 0x2ED23, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress]', symObjAddr: 0x8EE0, symBinAddr: 0x37D90, symSize: 0x1F4 } + - { offset: 0x2ED7F, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket localAddress]_block_invoke', symObjAddr: 0x90D4, symBinAddr: 0x37F84, symSize: 0xA0 } + - { offset: 0x2EDD7, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket localAddress]_block_invoke_2', symObjAddr: 0x9174, symBinAddr: 0x38024, symSize: 0x4C } + - { offset: 0x2EE13, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost]', symObjAddr: 0x91F8, symBinAddr: 0x38070, symSize: 0x1F4 } + - { offset: 0x2EE6F, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localHost]_block_invoke', symObjAddr: 0x93EC, symBinAddr: 0x38264, symSize: 0xA0 } + - { offset: 0x2EEC7, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localHost]_block_invoke_2', symObjAddr: 0x948C, symBinAddr: 0x38304, symSize: 0x4C } + - { offset: 0x2EF03, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort]', symObjAddr: 0x94D8, symBinAddr: 0x38350, symSize: 0x1B8 } + - { offset: 0x2EF5D, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localPort]_block_invoke', symObjAddr: 0x9690, symBinAddr: 0x38508, symSize: 0x98 } + - { offset: 0x2EFB5, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localPort]_block_invoke_2', symObjAddr: 0x9728, symBinAddr: 0x385A0, symSize: 0x4C } + - { offset: 0x2EFF1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress_IPv4]', symObjAddr: 0x9774, symBinAddr: 0x385EC, symSize: 0x1F4 } + - { offset: 0x2F04D, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv4]_block_invoke', symObjAddr: 0x9968, symBinAddr: 0x387E0, symSize: 0x50 } + - { offset: 0x2F0A5, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv4]_block_invoke_2', symObjAddr: 0x99B8, symBinAddr: 0x38830, symSize: 0x4C } + - { offset: 0x2F0E1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost_IPv4]', symObjAddr: 0x9A04, symBinAddr: 0x3887C, symSize: 0x1F4 } + - { offset: 0x2F13D, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv4]_block_invoke', symObjAddr: 0x9BF8, symBinAddr: 0x38A70, symSize: 0x50 } + - { offset: 0x2F195, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv4]_block_invoke_2', symObjAddr: 0x9C48, symBinAddr: 0x38AC0, symSize: 0x4C } + - { offset: 0x2F1D1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort_IPv4]', symObjAddr: 0x9C94, symBinAddr: 0x38B0C, symSize: 0x1B8 } + - { offset: 0x2F22B, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv4]_block_invoke', symObjAddr: 0x9E4C, symBinAddr: 0x38CC4, symSize: 0x4C } + - { offset: 0x2F283, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv4]_block_invoke_2', symObjAddr: 0x9E98, symBinAddr: 0x38D10, symSize: 0x4C } + - { offset: 0x2F2BF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress_IPv6]', symObjAddr: 0x9EE4, symBinAddr: 0x38D5C, symSize: 0x1F4 } + - { offset: 0x2F31B, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv6]_block_invoke', symObjAddr: 0xA0D8, symBinAddr: 0x38F50, symSize: 0x50 } + - { offset: 0x2F373, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv6]_block_invoke_2', symObjAddr: 0xA128, symBinAddr: 0x38FA0, symSize: 0x4C } + - { offset: 0x2F3AF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost_IPv6]', symObjAddr: 0xA174, symBinAddr: 0x38FEC, symSize: 0x1F4 } + - { offset: 0x2F40B, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv6]_block_invoke', symObjAddr: 0xA368, symBinAddr: 0x391E0, symSize: 0x50 } + - { offset: 0x2F463, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv6]_block_invoke_2', symObjAddr: 0xA3B8, symBinAddr: 0x39230, symSize: 0x4C } + - { offset: 0x2F49F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort_IPv6]', symObjAddr: 0xA404, symBinAddr: 0x3927C, symSize: 0x1B8 } + - { offset: 0x2F4F9, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv6]_block_invoke', symObjAddr: 0xA5BC, symBinAddr: 0x39434, symSize: 0x4C } + - { offset: 0x2F551, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv6]_block_invoke_2', symObjAddr: 0xA608, symBinAddr: 0x39480, symSize: 0x4C } + - { offset: 0x2F58D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedConnectedAddressInfo]', symObjAddr: 0xA654, symBinAddr: 0x394CC, symSize: 0x318 } + - { offset: 0x2F656, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedAddress]', symObjAddr: 0xA96C, symBinAddr: 0x397E4, symSize: 0x1F4 } + - { offset: 0x2F6B2, size: 0x8, addend: 0x0, symName: '___37-[GCDAsyncUdpSocket connectedAddress]_block_invoke', symObjAddr: 0xAB60, symBinAddr: 0x399D8, symSize: 0x50 } + - { offset: 0x2F70A, size: 0x8, addend: 0x0, symName: '___37-[GCDAsyncUdpSocket connectedAddress]_block_invoke_2', symObjAddr: 0xABB0, symBinAddr: 0x39A28, symSize: 0x4C } + - { offset: 0x2F746, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedHost]', symObjAddr: 0xABFC, symBinAddr: 0x39A74, symSize: 0x1F4 } + - { offset: 0x2F7A2, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedHost]_block_invoke', symObjAddr: 0xADF0, symBinAddr: 0x39C68, symSize: 0x50 } + - { offset: 0x2F7FA, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedHost]_block_invoke_2', symObjAddr: 0xAE40, symBinAddr: 0x39CB8, symSize: 0x4C } + - { offset: 0x2F836, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedPort]', symObjAddr: 0xAE8C, symBinAddr: 0x39D04, symSize: 0x1B8 } + - { offset: 0x2F890, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedPort]_block_invoke', symObjAddr: 0xB044, symBinAddr: 0x39EBC, symSize: 0x4C } + - { offset: 0x2F8E8, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedPort]_block_invoke_2', symObjAddr: 0xB090, symBinAddr: 0x39F08, symSize: 0x4C } + - { offset: 0x2F924, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnected]', symObjAddr: 0xB0DC, symBinAddr: 0x39F54, symSize: 0x14C } + - { offset: 0x2F97E, size: 0x8, addend: 0x0, symName: '___32-[GCDAsyncUdpSocket isConnected]_block_invoke', symObjAddr: 0xB228, symBinAddr: 0x3A0A0, symSize: 0x44 } + - { offset: 0x2F9D6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isClosed]', symObjAddr: 0xB26C, symBinAddr: 0x3A0E4, symSize: 0x150 } + - { offset: 0x2FA30, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket isClosed]_block_invoke', symObjAddr: 0xB3BC, symBinAddr: 0x3A234, symSize: 0x40 } + - { offset: 0x2FA88, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4]', symObjAddr: 0xB3FC, symBinAddr: 0x3A274, symSize: 0x150 } + - { offset: 0x2FAE2, size: 0x8, addend: 0x0, symName: '___27-[GCDAsyncUdpSocket isIPv4]_block_invoke', symObjAddr: 0xB54C, symBinAddr: 0x3A3C4, symSize: 0x84 } + - { offset: 0x2FB3A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6]', symObjAddr: 0xB5D0, symBinAddr: 0x3A448, symSize: 0x150 } + - { offset: 0x2FB94, size: 0x8, addend: 0x0, symName: '___27-[GCDAsyncUdpSocket isIPv6]_block_invoke', symObjAddr: 0xB720, symBinAddr: 0x3A598, symSize: 0x84 } + - { offset: 0x2FBEC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preBind:]', symObjAddr: 0xB7A4, symBinAddr: 0x3A61C, symSize: 0x264 } + - { offset: 0x2FC90, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToPort:error:]', symObjAddr: 0xBA08, symBinAddr: 0x3A880, symSize: 0x40 } + - { offset: 0x2FCE5, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToPort:interface:error:]', symObjAddr: 0xBA48, symBinAddr: 0x3A8C0, symSize: 0x294 } + - { offset: 0x2FD83, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket bindToPort:interface:error:]_block_invoke', symObjAddr: 0xBCDC, symBinAddr: 0x3AB54, symSize: 0x660 } + - { offset: 0x2FF55, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48r56r, symObjAddr: 0xC33C, symBinAddr: 0x3B1B4, symSize: 0x8C } + - { offset: 0x2FF79, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48r56r, symObjAddr: 0xC3C8, symBinAddr: 0x3B240, symSize: 0x68 } + - { offset: 0x2FF95, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToAddress:error:]', symObjAddr: 0xC430, symBinAddr: 0x3B2A8, symSize: 0x288 } + - { offset: 0x30024, size: 0x8, addend: 0x0, symName: '___41-[GCDAsyncUdpSocket bindToAddress:error:]_block_invoke', symObjAddr: 0xC6B8, symBinAddr: 0x3B530, symSize: 0x688 } + - { offset: 0x301F3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preConnect:]', symObjAddr: 0xCD40, symBinAddr: 0x3BBB8, symSize: 0x1D8 } + - { offset: 0x30281, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectToHost:onPort:error:]', symObjAddr: 0xCF18, symBinAddr: 0x3BD90, symSize: 0x29C } + - { offset: 0x3031F, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket connectToHost:onPort:error:]_block_invoke', symObjAddr: 0xD1B4, symBinAddr: 0x3C02C, symSize: 0x2E4 } + - { offset: 0x303EE, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket connectToHost:onPort:error:]_block_invoke_2', symObjAddr: 0xD498, symBinAddr: 0x3C310, symSize: 0xB0 } + - { offset: 0x3045E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectToAddress:error:]', symObjAddr: 0xD548, symBinAddr: 0x3C3C0, symSize: 0x288 } + - { offset: 0x304ED, size: 0x8, addend: 0x0, symName: '___44-[GCDAsyncUdpSocket connectToAddress:error:]_block_invoke', symObjAddr: 0xD7D0, symBinAddr: 0x3C648, symSize: 0x270 } + - { offset: 0x305C8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeConnect]', symObjAddr: 0xDA40, symBinAddr: 0x3C8B8, symSize: 0x364 } + - { offset: 0x3066A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectWithAddress4:error:]', symObjAddr: 0xDDA4, symBinAddr: 0x3CC1C, symSize: 0x1B8 } + - { offset: 0x306CE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectWithAddress6:error:]', symObjAddr: 0xDF5C, symBinAddr: 0x3CDD4, symSize: 0x1B8 } + - { offset: 0x30732, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preJoin:]', symObjAddr: 0xE114, symBinAddr: 0x3CF8C, symSize: 0x194 } + - { offset: 0x307A2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket joinMulticastGroup:error:]', symObjAddr: 0xE2A8, symBinAddr: 0x3D120, symSize: 0x7C } + - { offset: 0x307F7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket joinMulticastGroup:onInterface:error:]', symObjAddr: 0xE324, symBinAddr: 0x3D19C, symSize: 0xA4 } + - { offset: 0x3085B, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket leaveMulticastGroup:error:]', symObjAddr: 0xE3C8, symBinAddr: 0x3D240, symSize: 0x7C } + - { offset: 0x308B0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket leaveMulticastGroup:onInterface:error:]', symObjAddr: 0xE444, symBinAddr: 0x3D2BC, symSize: 0xA4 } + - { offset: 0x30914, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket performMulticastRequest:forGroup:onInterface:error:]', symObjAddr: 0xE4E8, symBinAddr: 0x3D360, symSize: 0x2CC } + - { offset: 0x309C1, size: 0x8, addend: 0x0, symName: '___72-[GCDAsyncUdpSocket performMulticastRequest:forGroup:onInterface:error:]_block_invoke', symObjAddr: 0xE7B4, symBinAddr: 0x3D62C, symSize: 0x584 } + - { offset: 0x30B99, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56r64r, symObjAddr: 0xED38, symBinAddr: 0x3DBB0, symSize: 0xA4 } + - { offset: 0x30BBD, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56r64r, symObjAddr: 0xEDDC, symBinAddr: 0x3DC54, symSize: 0x78 } + - { offset: 0x30BD9, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendIPv4MulticastOnInterface:error:]', symObjAddr: 0xEE54, symBinAddr: 0x3DCCC, symSize: 0x274 } + - { offset: 0x30C68, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendIPv4MulticastOnInterface:error:]_block_invoke', symObjAddr: 0xF0C8, symBinAddr: 0x3DF40, symSize: 0x2E4 } + - { offset: 0x30D72, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendIPv6MulticastOnInterface:error:]', symObjAddr: 0xF3AC, symBinAddr: 0x3E224, symSize: 0x274 } + - { offset: 0x30E01, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendIPv6MulticastOnInterface:error:]_block_invoke', symObjAddr: 0xF620, symBinAddr: 0x3E498, symSize: 0x2D4 } + - { offset: 0x30EFB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableReusePort:error:]', symObjAddr: 0xF8F4, symBinAddr: 0x3E76C, symSize: 0x22C } + - { offset: 0x30F8A, size: 0x8, addend: 0x0, symName: '___43-[GCDAsyncUdpSocket enableReusePort:error:]_block_invoke', symObjAddr: 0xFB20, symBinAddr: 0x3E998, symSize: 0x280 } + - { offset: 0x31063, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableBroadcast:error:]', symObjAddr: 0xFDA0, symBinAddr: 0x3EC18, symSize: 0x22C } + - { offset: 0x310F2, size: 0x8, addend: 0x0, symName: '___43-[GCDAsyncUdpSocket enableBroadcast:error:]_block_invoke', symObjAddr: 0xFFCC, symBinAddr: 0x3EE44, symSize: 0x1D0 } + - { offset: 0x311A0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:withTag:]', symObjAddr: 0x1019C, symBinAddr: 0x3F014, symSize: 0x70 } + - { offset: 0x311F1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:withTimeout:tag:]', symObjAddr: 0x1020C, symBinAddr: 0x3F084, symSize: 0x164 } + - { offset: 0x31260, size: 0x8, addend: 0x0, symName: '___46-[GCDAsyncUdpSocket sendData:withTimeout:tag:]_block_invoke', symObjAddr: 0x10370, symBinAddr: 0x3F1E8, symSize: 0x60 } + - { offset: 0x312B2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]', symObjAddr: 0x103D0, symBinAddr: 0x3F248, symSize: 0x26C } + - { offset: 0x31341, size: 0x8, addend: 0x0, symName: '___58-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]_block_invoke', symObjAddr: 0x1063C, symBinAddr: 0x3F4B4, symSize: 0xC4 } + - { offset: 0x313B1, size: 0x8, addend: 0x0, symName: '___58-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]_block_invoke_2', symObjAddr: 0x10700, symBinAddr: 0x3F578, symSize: 0x60 } + - { offset: 0x31403, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:toAddress:withTimeout:tag:]', symObjAddr: 0x10760, symBinAddr: 0x3F5D8, symSize: 0x1B4 } + - { offset: 0x31481, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendData:toAddress:withTimeout:tag:]_block_invoke', symObjAddr: 0x10914, symBinAddr: 0x3F78C, symSize: 0x60 } + - { offset: 0x314D3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setSendFilter:withQueue:]', symObjAddr: 0x10974, symBinAddr: 0x3F7EC, symSize: 0x8C } + - { offset: 0x31524, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setSendFilter:withQueue:isAsynchronous:]', symObjAddr: 0x10A00, symBinAddr: 0x3F878, symSize: 0x25C } + - { offset: 0x315B1, size: 0x8, addend: 0x0, symName: '___60-[GCDAsyncUdpSocket setSendFilter:withQueue:isAsynchronous:]_block_invoke', symObjAddr: 0x10C5C, symBinAddr: 0x3FAD4, symSize: 0x7C } + - { offset: 0x31627, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeDequeueSend]', symObjAddr: 0x10CD8, symBinAddr: 0x3FB50, symSize: 0x280 } + - { offset: 0x3166F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doPreSend]', symObjAddr: 0x10F58, symBinAddr: 0x3FDD0, symSize: 0x670 } + - { offset: 0x31749, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke', symObjAddr: 0x115C8, symBinAddr: 0x40440, symSize: 0x130 } + - { offset: 0x317B8, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke_2', symObjAddr: 0x116F8, symBinAddr: 0x40570, symSize: 0xC8 } + - { offset: 0x3181C, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke.176', symObjAddr: 0x117C0, symBinAddr: 0x40638, symSize: 0x84 } + - { offset: 0x31874, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doSend]', symObjAddr: 0x11844, symBinAddr: 0x406BC, symSize: 0x3AC } + - { offset: 0x3194A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket endCurrentSend]', symObjAddr: 0x11BF0, symBinAddr: 0x40A68, symSize: 0x60 } + - { offset: 0x3197D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doSendTimeout]', symObjAddr: 0x11C50, symBinAddr: 0x40AC8, symSize: 0x8C } + - { offset: 0x319B0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendTimerWithTimeout:]', symObjAddr: 0x11CDC, symBinAddr: 0x40B54, symSize: 0x208 } + - { offset: 0x31A01, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket setupSendTimerWithTimeout:]_block_invoke', symObjAddr: 0x11EE4, symBinAddr: 0x40D5C, symSize: 0x4C } + - { offset: 0x31A41, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket receiveOnce:]', symObjAddr: 0x11F30, symBinAddr: 0x40DA8, symSize: 0x230 } + - { offset: 0x31AC1, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket receiveOnce:]_block_invoke', symObjAddr: 0x12160, symBinAddr: 0x40FD8, symSize: 0x17C } + - { offset: 0x31B4E, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket receiveOnce:]_block_invoke_2', symObjAddr: 0x122DC, symBinAddr: 0x41154, symSize: 0x4C } + - { offset: 0x31B8E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket beginReceiving:]', symObjAddr: 0x12328, symBinAddr: 0x411A0, symSize: 0x230 } + - { offset: 0x31C0E, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket beginReceiving:]_block_invoke', symObjAddr: 0x12558, symBinAddr: 0x413D0, symSize: 0x17C } + - { offset: 0x31C9B, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket beginReceiving:]_block_invoke_2', symObjAddr: 0x126D4, symBinAddr: 0x4154C, symSize: 0x4C } + - { offset: 0x31CDB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket pauseReceiving]', symObjAddr: 0x12720, symBinAddr: 0x41598, symSize: 0xD4 } + - { offset: 0x31D1D, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket pauseReceiving]_block_invoke', symObjAddr: 0x127F4, symBinAddr: 0x4166C, symSize: 0xA0 } + - { offset: 0x31D5D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setReceiveFilter:withQueue:]', symObjAddr: 0x12894, symBinAddr: 0x4170C, symSize: 0x8C } + - { offset: 0x31DAE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setReceiveFilter:withQueue:isAsynchronous:]', symObjAddr: 0x12920, symBinAddr: 0x41798, symSize: 0x25C } + - { offset: 0x31E3B, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket setReceiveFilter:withQueue:isAsynchronous:]_block_invoke', symObjAddr: 0x12B7C, symBinAddr: 0x419F4, symSize: 0x7C } + - { offset: 0x31EB1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doReceive]', symObjAddr: 0x12BF8, symBinAddr: 0x41A70, symSize: 0xE70 } + - { offset: 0x32054, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke', symObjAddr: 0x13A68, symBinAddr: 0x428E0, symSize: 0x194 } + - { offset: 0x320E8, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke_2', symObjAddr: 0x13BFC, symBinAddr: 0x42A74, symSize: 0x104 } + - { offset: 0x3217C, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke.183', symObjAddr: 0x13D00, symBinAddr: 0x42B78, symSize: 0x98 } + - { offset: 0x32210, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doReceiveEOF]', symObjAddr: 0x13D98, symBinAddr: 0x42C10, symSize: 0x60 } + - { offset: 0x32243, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeWithError:]', symObjAddr: 0x13DF8, symBinAddr: 0x42C70, symSize: 0x158 } + - { offset: 0x32294, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket close]', symObjAddr: 0x13F50, symBinAddr: 0x42DC8, symSize: 0xD4 } + - { offset: 0x322D6, size: 0x8, addend: 0x0, symName: '___26-[GCDAsyncUdpSocket close]_block_invoke', symObjAddr: 0x14024, symBinAddr: 0x42E9C, symSize: 0x50 } + - { offset: 0x32316, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeAfterSending]', symObjAddr: 0x14074, symBinAddr: 0x42EEC, symSize: 0xD4 } + - { offset: 0x32358, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket closeAfterSending]_block_invoke', symObjAddr: 0x14148, symBinAddr: 0x42FC0, symSize: 0x94 } + - { offset: 0x32398, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket ignore:]', symObjAddr: 0x141DC, symBinAddr: 0x43054, symSize: 0x4C } + - { offset: 0x3244A, size: 0x8, addend: 0x0, symName: '___48+[GCDAsyncUdpSocket startListenerThreadIfNeeded]_block_invoke', symObjAddr: 0x142D0, symBinAddr: 0x43148, symSize: 0x80 } + - { offset: 0x3248A, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket listenerThread:]', symObjAddr: 0x14350, symBinAddr: 0x431C8, symSize: 0x138 } + - { offset: 0x324CC, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket addStreamListener:]', symObjAddr: 0x14488, symBinAddr: 0x43300, symSize: 0x1AC } + - { offset: 0x3251D, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket removeStreamListener:]', symObjAddr: 0x14634, symBinAddr: 0x434AC, symSize: 0x1AC } + - { offset: 0x3256E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createReadAndWriteStreams:]', symObjAddr: 0x147E0, symBinAddr: 0x43658, symSize: 0x438 } + - { offset: 0x325D3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket registerForStreamCallbacks:]', symObjAddr: 0x14C18, symBinAddr: 0x43A90, symSize: 0x4F0 } + - { offset: 0x326AE, size: 0x8, addend: 0x0, symName: _CFReadStreamCallback, symObjAddr: 0x15108, symBinAddr: 0x43F80, symSize: 0x1C8 } + - { offset: 0x3272C, size: 0x8, addend: 0x0, symName: _CFWriteStreamCallback, symObjAddr: 0x152D0, symBinAddr: 0x44148, symSize: 0x1C8 } + - { offset: 0x327AA, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket addStreamsToRunLoop:]', symObjAddr: 0x15498, symBinAddr: 0x44310, symSize: 0x1CC } + - { offset: 0x327F0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket openStreams:]', symObjAddr: 0x15664, symBinAddr: 0x444DC, symSize: 0x308 } + - { offset: 0x328AD, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket removeStreamsFromRunLoop]', symObjAddr: 0x1596C, symBinAddr: 0x447E4, symSize: 0xE8 } + - { offset: 0x328E0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeReadAndWriteStreams]', symObjAddr: 0x15A54, symBinAddr: 0x448CC, symSize: 0x150 } + - { offset: 0x32913, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket applicationWillEnterForeground:]', symObjAddr: 0x15BA4, symBinAddr: 0x44A1C, symSize: 0xF4 } + - { offset: 0x32964, size: 0x8, addend: 0x0, symName: '___52-[GCDAsyncUdpSocket applicationWillEnterForeground:]_block_invoke', symObjAddr: 0x15C98, symBinAddr: 0x44B10, symSize: 0x5C } + - { offset: 0x329A4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket markSocketQueueTargetQueue:]', symObjAddr: 0x15CF4, symBinAddr: 0x44B6C, symSize: 0x6C } + - { offset: 0x329F5, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket unmarkSocketQueueTargetQueue:]', symObjAddr: 0x15D60, symBinAddr: 0x44BD8, symSize: 0x64 } + - { offset: 0x32A37, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket performBlock:]', symObjAddr: 0x15DC4, symBinAddr: 0x44C3C, symSize: 0x78 } + - { offset: 0x32A79, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socketFD]', symObjAddr: 0x15E3C, symBinAddr: 0x44CB4, symSize: 0x78 } + - { offset: 0x32AB0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socket4FD]', symObjAddr: 0x15EB4, symBinAddr: 0x44D2C, symSize: 0x54 } + - { offset: 0x32AE7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socket6FD]', symObjAddr: 0x15F08, symBinAddr: 0x44D80, symSize: 0x54 } + - { offset: 0x32B1E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket readStream]', symObjAddr: 0x15F5C, symBinAddr: 0x44DD4, symSize: 0xE4 } + - { offset: 0x32B64, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket writeStream]', symObjAddr: 0x16040, symBinAddr: 0x44EB8, symSize: 0xE4 } + - { offset: 0x32BAA, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableBackgroundingOnSockets]', symObjAddr: 0x16124, symBinAddr: 0x44F9C, symSize: 0x64 } + - { offset: 0x32BE1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromSockaddr4:]', symObjAddr: 0x16188, symBinAddr: 0x45000, symSize: 0x9C } + - { offset: 0x32C36, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromSockaddr6:]', symObjAddr: 0x16224, symBinAddr: 0x4509C, symSize: 0x9C } + - { offset: 0x32C8B, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromSockaddr4:]', symObjAddr: 0x162C0, symBinAddr: 0x45138, symSize: 0x40 } + - { offset: 0x32CD1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromSockaddr6:]', symObjAddr: 0x16300, symBinAddr: 0x45178, symSize: 0x40 } + - { offset: 0x32D17, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromAddress:]', symObjAddr: 0x16340, symBinAddr: 0x451B8, symSize: 0xB0 } + - { offset: 0x32D6C, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromAddress:]', symObjAddr: 0x163F0, symBinAddr: 0x45268, symSize: 0x78 } + - { offset: 0x32DC1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket familyFromAddress:]', symObjAddr: 0x16468, symBinAddr: 0x452E0, symSize: 0x78 } + - { offset: 0x32E16, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket isIPv4Address:]', symObjAddr: 0x164E0, symBinAddr: 0x45358, symSize: 0x80 } + - { offset: 0x32E6B, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket isIPv6Address:]', symObjAddr: 0x16560, symBinAddr: 0x453D8, symSize: 0x80 } + - { offset: 0x32EC0, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket getHost:port:fromAddress:]', symObjAddr: 0x165E0, symBinAddr: 0x45458, symSize: 0x7C } + - { offset: 0x32F24, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket getHost:port:family:fromAddress:]', symObjAddr: 0x1665C, symBinAddr: 0x454D4, symSize: 0x294 } + - { offset: 0x32FEF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket .cxx_destruct]', symObjAddr: 0x168F0, symBinAddr: 0x45768, symSize: 0x174 } + - { offset: 0x33022, size: 0x8, addend: 0x0, symName: ___CFReadStreamCallback_block_invoke, symObjAddr: 0x16A64, symBinAddr: 0x458DC, symSize: 0x9C } + - { offset: 0x33082, size: 0x8, addend: 0x0, symName: ___CFWriteStreamCallback_block_invoke, symObjAddr: 0x16B00, symBinAddr: 0x45978, symSize: 0x9C } +... diff --git a/.theos/obj/debug/arm64/OhNo.dylib b/.theos/obj/debug/arm64/OhNo.dylib new file mode 100755 index 0000000..569c43f Binary files /dev/null and b/.theos/obj/debug/arm64/OhNo.dylib differ diff --git a/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Info.plist b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Info.plist new file mode 100644 index 0000000..cba9de5 --- /dev/null +++ b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.OhNo.dylib + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib new file mode 100644 index 0000000..3c1247a Binary files /dev/null and b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib differ diff --git a/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/Relocations/aarch64/OhNo.dylib.yml b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/Relocations/aarch64/OhNo.dylib.yml new file mode 100644 index 0000000..31461b7 --- /dev/null +++ b/.theos/obj/debug/arm64/OhNo.dylib.dSYM/Contents/Resources/Relocations/aarch64/OhNo.dylib.yml @@ -0,0 +1,180 @@ +--- +triple: 'arm64-apple-darwin' +binary-path: '/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/OhNo.dylib' +relocations: + - { offset: 0x7D, size: 0x8, addend: 0x0, symName: _settings, symBinAddr: 0x14768, symSize: 0x0 } + - { offset: 0xF0, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$ATTrackingManager$trackingAuthorizationStatus', symObjAddr: 0x25178, symBinAddr: 0x145C8, symSize: 0x0 } + - { offset: 0x132, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$ASIdentifierManager$advertisingIdentifier', symObjAddr: 0x25180, symBinAddr: 0x145D0, symSize: 0x0 } + - { offset: 0x1B0, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled', symObjAddr: 0x25188, symBinAddr: 0x145D8, symSize: 0x0 } + - { offset: 0x1EC, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$identifierForVendor', symObjAddr: 0x25190, symBinAddr: 0x145E0, symSize: 0x0 } + - { offset: 0x3C4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$name', symObjAddr: 0x25198, symBinAddr: 0x145E8, symSize: 0x0 } + - { offset: 0x3EE, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$model', symObjAddr: 0x251A0, symBinAddr: 0x145F0, symSize: 0x0 } + - { offset: 0x403, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$localizedModel', symObjAddr: 0x251A8, symBinAddr: 0x145F8, symSize: 0x0 } + - { offset: 0x418, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$systemName', symObjAddr: 0x251B0, symBinAddr: 0x14600, symSize: 0x0 } + - { offset: 0x42D, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$systemVersion', symObjAddr: 0x251B8, symBinAddr: 0x14608, symSize: 0x0 } + - { offset: 0x442, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$batteryState', symObjAddr: 0x251C0, symBinAddr: 0x14610, symSize: 0x0 } + - { offset: 0x46C, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$batteryLevel', symObjAddr: 0x251C8, symBinAddr: 0x14618, symSize: 0x0 } + - { offset: 0x496, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$orientation', symObjAddr: 0x251D0, symBinAddr: 0x14620, symSize: 0x0 } + - { offset: 0x4C0, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$systemUptime', symObjAddr: 0x251D8, symBinAddr: 0x14628, symSize: 0x0 } + - { offset: 0x671, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$physicalMemory', symObjAddr: 0x251E0, symBinAddr: 0x14630, symSize: 0x0 } + - { offset: 0x69B, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$processorCount', symObjAddr: 0x251E8, symBinAddr: 0x14638, symSize: 0x0 } + - { offset: 0x6C5, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$operatingSystemVersion', symObjAddr: 0x251F0, symBinAddr: 0x14640, symSize: 0x0 } + - { offset: 0x6EF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIWindow$safeAreaInsets', symObjAddr: 0x251F8, symBinAddr: 0x14648, symSize: 0x0 } + - { offset: 0x2261, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$brightness', symObjAddr: 0x25200, symBinAddr: 0x14650, symSize: 0x0 } + - { offset: 0x2290, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$bounds', symObjAddr: 0x25208, symBinAddr: 0x14658, symSize: 0x0 } + - { offset: 0x22BA, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$scale', symObjAddr: 0x25210, symBinAddr: 0x14660, symSize: 0x0 } + - { offset: 0x22CF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$nativeBounds', symObjAddr: 0x25218, symBinAddr: 0x14668, symSize: 0x0 } + - { offset: 0x22E4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$isCaptured', symObjAddr: 0x25220, symBinAddr: 0x14670, symSize: 0x0 } + - { offset: 0x230E, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$mirroredScreen', symObjAddr: 0x25228, symBinAddr: 0x14678, symSize: 0x0 } + - { offset: 0x2338, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$AVAudioSession$outputVolume', symObjAddr: 0x25230, symBinAddr: 0x14680, symSize: 0x0 } + - { offset: 0x2372, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreenMode$size', symObjAddr: 0x25238, symBinAddr: 0x14688, symSize: 0x0 } + - { offset: 0x23A1, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSFileManager$attributesOfFileSystemForPath$error$', symObjAddr: 0x25240, symBinAddr: 0x14690, symSize: 0x0 } + - { offset: 0x24CB, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSFileManager$fileExistsAtPath$', symObjAddr: 0x25248, symBinAddr: 0x14698, symSize: 0x0 } + - { offset: 0x24FA, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$preferredLanguages', symObjAddr: 0x25250, symBinAddr: 0x146A0, symSize: 0x0 } + - { offset: 0x2524, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$currentLocale', symObjAddr: 0x25258, symBinAddr: 0x146A8, symSize: 0x0 } + - { offset: 0x2563, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$systemLocale', symObjAddr: 0x25260, symBinAddr: 0x146B0, symSize: 0x0 } + - { offset: 0x2578, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$localTimeZone', symObjAddr: 0x25268, symBinAddr: 0x146B8, symSize: 0x0 } + - { offset: 0x25D1, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$systemTimeZone', symObjAddr: 0x25270, symBinAddr: 0x146C0, symSize: 0x0 } + - { offset: 0x25E6, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$defaultTimeZone', symObjAddr: 0x25278, symBinAddr: 0x146C8, symSize: 0x0 } + - { offset: 0x25FB, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIStatusBarManager$statusBarFrame', symObjAddr: 0x25280, symBinAddr: 0x146D0, symSize: 0x0 } + - { offset: 0x2667, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSMutableURLRequest$initWithURL$', symObjAddr: 0x25288, symBinAddr: 0x146D8, symSize: 0x0 } + - { offset: 0x2901, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$', symObjAddr: 0x25290, symBinAddr: 0x146E0, symSize: 0x0 } + - { offset: 0x2936, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSURLSession$sessionWithConfiguration$', symObjAddr: 0x25298, symBinAddr: 0x146E8, symSize: 0x0 } + - { offset: 0x3057, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSURLSession$dataTaskWithRequest$completionHandler$', symObjAddr: 0x252A0, symBinAddr: 0x146F0, symSize: 0x0 } + - { offset: 0x32C8, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$evaluateJavaScript$completionHandler$', symObjAddr: 0x252A8, symBinAddr: 0x146F8, symSize: 0x0 } + - { offset: 0x4DCF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$setCustomUserAgent$', symObjAddr: 0x252B0, symBinAddr: 0x14700, symSize: 0x0 } + - { offset: 0x4DFA, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$customUserAgent', symObjAddr: 0x252B8, symBinAddr: 0x14708, symSize: 0x0 } + - { offset: 0x4E24, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology', symObjAddr: 0x252C0, symBinAddr: 0x14710, symSize: 0x0 } + - { offset: 0x4FD4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders', symObjAddr: 0x252C8, symBinAddr: 0x14718, symSize: 0x0 } + - { offset: 0x4FE9, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$', symObjAddr: 0x252D0, symBinAddr: 0x14720, symSize: 0x0 } + - { offset: 0x5533, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$uname', symObjAddr: 0x252D8, symBinAddr: 0x14728, symSize: 0x0 } + - { offset: 0x55B5, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$sysctl', symObjAddr: 0x252E0, symBinAddr: 0x14730, symSize: 0x0 } + - { offset: 0x560E, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$sysctlbyname', symObjAddr: 0x252E8, symBinAddr: 0x14738, symSize: 0x0 } + - { offset: 0x5648, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$clock_gettime', symObjAddr: 0x252F0, symBinAddr: 0x14740, symSize: 0x0 } + - { offset: 0x56E8, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$getifaddrs', symObjAddr: 0x252F8, symBinAddr: 0x14748, symSize: 0x0 } + - { offset: 0x57C6, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$SCNetworkReachabilityGetFlags', symObjAddr: 0x25300, symBinAddr: 0x14750, symSize: 0x0 } + - { offset: 0x5876, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIAccessibilityIsClosedCaptioningEnabled', symObjAddr: 0x25308, symBinAddr: 0x14758, symSize: 0x0 } + - { offset: 0x5898, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIAccessibilityIsMonoAudioEnabled', symObjAddr: 0x25310, symBinAddr: 0x14760, symSize: 0x0 } + - { offset: 0x5A66, size: 0x8, addend: 0x0, symName: _reloadConfig, symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x1E0 } + - { offset: 0x5AB2, size: 0x8, addend: 0x0, symName: _str2uuid, symObjAddr: 0x1E0, symBinAddr: 0x41E0, symSize: 0x64 } + - { offset: 0x5ADA, size: 0x8, addend: 0x0, symName: _str2int, symObjAddr: 0x244, symBinAddr: 0x4244, symSize: 0x58 } + - { offset: 0x5B02, size: 0x8, addend: 0x0, symName: _str2float, symObjAddr: 0x29C, symBinAddr: 0x429C, symSize: 0x54 } + - { offset: 0x5B2A, size: 0x8, addend: 0x0, symName: _str2double, symObjAddr: 0x2F0, symBinAddr: 0x42F0, symSize: 0x54 } + - { offset: 0x5B52, size: 0x8, addend: 0x0, symName: _str2ull, symObjAddr: 0x344, symBinAddr: 0x4344, symSize: 0x58 } + - { offset: 0x5B7A, size: 0x8, addend: 0x0, symName: _tryGetVal, symObjAddr: 0x39C, symBinAddr: 0x439C, symSize: 0x190 } + - { offset: 0x5BD4, size: 0x8, addend: 0x0, symName: _str2chars, symObjAddr: 0x52C, symBinAddr: 0x452C, symSize: 0x6C } + - { offset: 0x5C0A, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData rotationRate]', symObjAddr: 0x598, symBinAddr: 0x4598, symSize: 0x44 } + - { offset: 0x5C41, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData customRotationRate]', symObjAddr: 0x5DC, symBinAddr: 0x45DC, symSize: 0x40 } + - { offset: 0x5C78, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData setCustomRotationRate:]', symObjAddr: 0x61C, symBinAddr: 0x461C, symSize: 0x40 } + - { offset: 0x5CB7, size: 0x8, addend: 0x0, symName: __logosLocalCtor_d7de9a12, symObjAddr: 0x65C, symBinAddr: 0x465C, symSize: 0xCE8 } + - { offset: 0x5F5A, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$ATTrackingManager$trackingAuthorizationStatus', symObjAddr: 0x1344, symBinAddr: 0x5344, symSize: 0x110 } + - { offset: 0x5FA3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$ASIdentifierManager$advertisingIdentifier', symObjAddr: 0x1454, symBinAddr: 0x5454, symSize: 0x158 } + - { offset: 0x5FEC, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled', symObjAddr: 0x15AC, symBinAddr: 0x55AC, symSize: 0xE8 } + - { offset: 0x6035, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$identifierForVendor', symObjAddr: 0x1694, symBinAddr: 0x5694, symSize: 0x158 } + - { offset: 0x607E, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$name', symObjAddr: 0x17EC, symBinAddr: 0x57EC, symSize: 0x158 } + - { offset: 0x60C7, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$model', symObjAddr: 0x1944, symBinAddr: 0x5944, symSize: 0x34 } + - { offset: 0x60FD, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$localizedModel', symObjAddr: 0x1978, symBinAddr: 0x5978, symSize: 0x34 } + - { offset: 0x6133, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$systemName', symObjAddr: 0x19AC, symBinAddr: 0x59AC, symSize: 0x34 } + - { offset: 0x6169, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$systemVersion', symObjAddr: 0x19E0, symBinAddr: 0x59E0, symSize: 0x158 } + - { offset: 0x61B2, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$batteryState', symObjAddr: 0x1B38, symBinAddr: 0x5B38, symSize: 0xF0 } + - { offset: 0x61FB, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$batteryLevel', symObjAddr: 0x1C28, symBinAddr: 0x5C28, symSize: 0xF0 } + - { offset: 0x6244, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$orientation', symObjAddr: 0x1D18, symBinAddr: 0x5D18, symSize: 0x18 } + - { offset: 0x627A, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$systemUptime', symObjAddr: 0x1D30, symBinAddr: 0x5D30, symSize: 0xF0 } + - { offset: 0x62C3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$physicalMemory', symObjAddr: 0x1E20, symBinAddr: 0x5E20, symSize: 0x110 } + - { offset: 0x630C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$processorCount', symObjAddr: 0x1F30, symBinAddr: 0x5F30, symSize: 0xF0 } + - { offset: 0x6355, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$operatingSystemVersion', symObjAddr: 0x2020, symBinAddr: 0x6020, symSize: 0x614 } + - { offset: 0x63DE, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIWindow$safeAreaInsets', symObjAddr: 0x2634, symBinAddr: 0x6634, symSize: 0x214 } + - { offset: 0x642C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$brightness', symObjAddr: 0x2848, symBinAddr: 0x6848, symSize: 0xF0 } + - { offset: 0x6479, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$bounds', symObjAddr: 0x2938, symBinAddr: 0x6938, symSize: 0x12C } + - { offset: 0x64C7, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$scale', symObjAddr: 0x2A64, symBinAddr: 0x6A64, symSize: 0xF0 } + - { offset: 0x6514, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$nativeBounds', symObjAddr: 0x2B54, symBinAddr: 0x6B54, symSize: 0x12C } + - { offset: 0x6562, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$isCaptured', symObjAddr: 0x2C80, symBinAddr: 0x6C80, symSize: 0x1C } + - { offset: 0x659B, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$mirroredScreen', symObjAddr: 0x2C9C, symBinAddr: 0x6C9C, symSize: 0x18 } + - { offset: 0x65D4, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$AVAudioSession$outputVolume', symObjAddr: 0x2CB4, symBinAddr: 0x6CB4, symSize: 0xF0 } + - { offset: 0x6621, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreenMode$size', symObjAddr: 0x2DA4, symBinAddr: 0x6DA4, symSize: 0x104 } + - { offset: 0x666F, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$', symObjAddr: 0x2EA8, symBinAddr: 0x6EA8, symSize: 0x248 } + - { offset: 0x66F3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSFileManager$fileExistsAtPath$', symObjAddr: 0x30F0, symBinAddr: 0x70F0, symSize: 0x3A0 } + - { offset: 0x675E, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$preferredLanguages', symObjAddr: 0x3490, symBinAddr: 0x7490, symSize: 0x88 } + - { offset: 0x6797, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$currentLocale', symObjAddr: 0x3518, symBinAddr: 0x7518, symSize: 0x138 } + - { offset: 0x67E4, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$systemLocale', symObjAddr: 0x3650, symBinAddr: 0x7650, symSize: 0x138 } + - { offset: 0x6831, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$localTimeZone', symObjAddr: 0x3788, symBinAddr: 0x7788, symSize: 0x138 } + - { offset: 0x687E, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$systemTimeZone', symObjAddr: 0x38C0, symBinAddr: 0x78C0, symSize: 0x138 } + - { offset: 0x68CB, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$defaultTimeZone', symObjAddr: 0x39F8, symBinAddr: 0x79F8, symSize: 0x138 } + - { offset: 0x6918, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIStatusBarManager$statusBarFrame', symObjAddr: 0x3B30, symBinAddr: 0x7B30, symSize: 0x12C } + - { offset: 0x6966, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSMutableURLRequest$initWithURL$', symObjAddr: 0x3C5C, symBinAddr: 0x7C5C, symSize: 0x134 } + - { offset: 0x69AE, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$', symObjAddr: 0x3D90, symBinAddr: 0x7D90, symSize: 0x18C } + - { offset: 0x6A16, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSURLSession$sessionWithConfiguration$', symObjAddr: 0x3F1C, symBinAddr: 0x7F1C, symSize: 0xF4 } + - { offset: 0x6A5E, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSURLSession$dataTaskWithRequest$completionHandler$', symObjAddr: 0x4010, symBinAddr: 0x8010, symSize: 0x134 } + - { offset: 0x6AC4, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$evaluateJavaScript$completionHandler$', symObjAddr: 0x4144, symBinAddr: 0x8144, symSize: 0x1F0 } + - { offset: 0x6B2C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$setCustomUserAgent$', symObjAddr: 0x4334, symBinAddr: 0x8334, symSize: 0x140 } + - { offset: 0x6B85, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$customUserAgent', symObjAddr: 0x4474, symBinAddr: 0x8474, symSize: 0x12C } + - { offset: 0x6BD2, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology', symObjAddr: 0x45A0, symBinAddr: 0x85A0, symSize: 0x168 } + - { offset: 0x6C29, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders', symObjAddr: 0x4708, symBinAddr: 0x8708, symSize: 0x168 } + - { offset: 0x6C80, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$', symObjAddr: 0x4870, symBinAddr: 0x8870, symSize: 0x150 } + - { offset: 0x6CE2, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$uname', symObjAddr: 0x49C0, symBinAddr: 0x89C0, symSize: 0x88 } + - { offset: 0x6D1B, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$sysctl', symObjAddr: 0x4A48, symBinAddr: 0x8A48, symSize: 0x104 } + - { offset: 0x6DBC, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$sysctlbyname', symObjAddr: 0x4B4C, symBinAddr: 0x8B4C, symSize: 0x3E8 } + - { offset: 0x6EA4, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$clock_gettime', symObjAddr: 0x4F34, symBinAddr: 0x8F34, symSize: 0x5C } + - { offset: 0x6EEC, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$getifaddrs', symObjAddr: 0x4F90, symBinAddr: 0x8F90, symSize: 0x698 } + - { offset: 0x7072, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$SCNetworkReachabilityGetFlags', symObjAddr: 0x5628, symBinAddr: 0x9628, symSize: 0x84 } + - { offset: 0x70BA, size: 0x8, addend: 0x0, symName: __logosLocalDtor_444f8b65, symObjAddr: 0x56AC, symBinAddr: 0x96AC, symSize: 0x28 } + - { offset: 0x70FE, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$ATTrackingManager$trackingAuthorizationStatus_block_invoke', symObjAddr: 0x56D4, symBinAddr: 0x96D4, symSize: 0x68 } + - { offset: 0x714B, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32r, symObjAddr: 0x573C, symBinAddr: 0x973C, symSize: 0x38 } + - { offset: 0x716F, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32r, symObjAddr: 0x5774, symBinAddr: 0x9774, symSize: 0x2C } + - { offset: 0x718B, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x57A0, symBinAddr: 0x97A0, symSize: 0x54 } + - { offset: 0x71AF, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x57F4, symBinAddr: 0x97F4, symSize: 0x2C } + - { offset: 0x71CB, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$ASIdentifierManager$advertisingIdentifier_block_invoke', symObjAddr: 0x5820, symBinAddr: 0x9820, symSize: 0x80 } + - { offset: 0x7218, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled_block_invoke', symObjAddr: 0x58A0, symBinAddr: 0x98A0, symSize: 0x84 } + - { offset: 0x7281, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$identifierForVendor_block_invoke', symObjAddr: 0x5924, symBinAddr: 0x9924, symSize: 0x80 } + - { offset: 0x72CE, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$name_block_invoke', symObjAddr: 0x59A4, symBinAddr: 0x99A4, symSize: 0x64 } + - { offset: 0x731B, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$systemVersion_block_invoke', symObjAddr: 0x5A08, symBinAddr: 0x9A08, symSize: 0x64 } + - { offset: 0x7368, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$batteryState_block_invoke', symObjAddr: 0x5A6C, symBinAddr: 0x9A6C, symSize: 0x70 } + - { offset: 0x73D1, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$batteryLevel_block_invoke', symObjAddr: 0x5ADC, symBinAddr: 0x9ADC, symSize: 0x64 } + - { offset: 0x741E, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$systemUptime_block_invoke', symObjAddr: 0x5B40, symBinAddr: 0x9B40, symSize: 0x88 } + - { offset: 0x7487, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$physicalMemory_block_invoke', symObjAddr: 0x5BC8, symBinAddr: 0x9BC8, symSize: 0x74 } + - { offset: 0x74F0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$processorCount_block_invoke', symObjAddr: 0x5C3C, symBinAddr: 0x9C3C, symSize: 0x74 } + - { offset: 0x7559, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$operatingSystemVersion_block_invoke', symObjAddr: 0x5CB0, symBinAddr: 0x9CB0, symSize: 0x64 } + - { offset: 0x75A6, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIWindow$safeAreaInsets_block_invoke', symObjAddr: 0x5D14, symBinAddr: 0x9D14, symSize: 0x160 } + - { offset: 0x7623, size: 0x8, addend: 0x0, symName: _UIEdgeInsetsMake, symObjAddr: 0x5E74, symBinAddr: 0x9E74, symSize: 0x4C } + - { offset: 0x7683, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$brightness_block_invoke', symObjAddr: 0x5EC0, symBinAddr: 0x9EC0, symSize: 0x78 } + - { offset: 0x76F1, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$bounds_block_invoke', symObjAddr: 0x5F38, symBinAddr: 0x9F38, symSize: 0x12C } + - { offset: 0x778D, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$scale_block_invoke', symObjAddr: 0x6064, symBinAddr: 0xA064, symSize: 0x78 } + - { offset: 0x77FB, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$nativeBounds_block_invoke', symObjAddr: 0x60DC, symBinAddr: 0xA0DC, symSize: 0x12C } + - { offset: 0x7897, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$AVAudioSession$outputVolume_block_invoke', symObjAddr: 0x6208, symBinAddr: 0xA208, symSize: 0x78 } + - { offset: 0x7905, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreenMode$size_block_invoke', symObjAddr: 0x6280, symBinAddr: 0xA280, symSize: 0x118 } + - { offset: 0x79A0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$_block_invoke', symObjAddr: 0x6398, symBinAddr: 0xA398, symSize: 0xB0 } + - { offset: 0x7A08, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s, symObjAddr: 0x6448, symBinAddr: 0xA448, symSize: 0x38 } + - { offset: 0x7A2C, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s, symObjAddr: 0x6480, symBinAddr: 0xA480, symSize: 0x2C } + - { offset: 0x7A48, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$_block_invoke.243', symObjAddr: 0x64AC, symBinAddr: 0xA4AC, symSize: 0xB0 } + - { offset: 0x7AB0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$fileExistsAtPath$_block_invoke', symObjAddr: 0x655C, symBinAddr: 0xA55C, symSize: 0x9C } + - { offset: 0x7B3A, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSLocale$currentLocale_block_invoke', symObjAddr: 0x65F8, symBinAddr: 0xA5F8, symSize: 0xB0 } + - { offset: 0x7BA8, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSLocale$systemLocale_block_invoke', symObjAddr: 0x66A8, symBinAddr: 0xA6A8, symSize: 0xB0 } + - { offset: 0x7C16, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$localTimeZone_block_invoke', symObjAddr: 0x6758, symBinAddr: 0xA758, symSize: 0xB4 } + - { offset: 0x7C84, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$systemTimeZone_block_invoke', symObjAddr: 0x680C, symBinAddr: 0xA80C, symSize: 0xB4 } + - { offset: 0x7CF2, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$defaultTimeZone_block_invoke', symObjAddr: 0x68C0, symBinAddr: 0xA8C0, symSize: 0xB4 } + - { offset: 0x7D60, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIStatusBarManager$statusBarFrame_block_invoke', symObjAddr: 0x6974, symBinAddr: 0xA974, symSize: 0xE0 } + - { offset: 0x7DEC, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSMutableURLRequest$initWithURL$_block_invoke', symObjAddr: 0x6A54, symBinAddr: 0xAA54, symSize: 0x68 } + - { offset: 0x7E37, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$_block_invoke', symObjAddr: 0x6ABC, symBinAddr: 0xAABC, symSize: 0x64 } + - { offset: 0x7E88, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSURLSession$sessionWithConfiguration$_block_invoke', symObjAddr: 0x6B20, symBinAddr: 0xAB20, symSize: 0xDC } + - { offset: 0x7ED3, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSURLSession$dataTaskWithRequest$completionHandler$_block_invoke', symObjAddr: 0x6BFC, symBinAddr: 0xABFC, symSize: 0x68 } + - { offset: 0x7F1E, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$evaluateJavaScript$completionHandler$_block_invoke', symObjAddr: 0x6C64, symBinAddr: 0xAC64, symSize: 0x64 } + - { offset: 0x7F6F, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$setCustomUserAgent$_block_invoke', symObjAddr: 0x6CC8, symBinAddr: 0xACC8, symSize: 0x64 } + - { offset: 0x7FC0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$customUserAgent_block_invoke', symObjAddr: 0x6D2C, symBinAddr: 0xAD2C, symSize: 0x64 } + - { offset: 0x8011, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology_block_invoke', symObjAddr: 0x6D90, symBinAddr: 0xAD90, symSize: 0x268 } + - { offset: 0x80B9, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders_block_invoke', symObjAddr: 0x6FF8, symBinAddr: 0xAFF8, symSize: 0x364 } + - { offset: 0x8161, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$_block_invoke', symObjAddr: 0x735C, symBinAddr: 0xB35C, symSize: 0x15C } + - { offset: 0x8206, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b, symObjAddr: 0x74B8, symBinAddr: 0xB4B8, symSize: 0x38 } + - { offset: 0x822A, size: 0x8, addend: 0x0, symName: _randomRadiansPerSecond, symObjAddr: 0x74F0, symBinAddr: 0xB4F0, symSize: 0x44 } + - { offset: 0x8254, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$uname_block_invoke', symObjAddr: 0x7534, symBinAddr: 0xB534, symSize: 0xB0 } + - { offset: 0x82BD, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctl_block_invoke', symObjAddr: 0x75E4, symBinAddr: 0xB5E4, symSize: 0x78 } + - { offset: 0x8325, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctlbyname_block_invoke', symObjAddr: 0x765C, symBinAddr: 0xB65C, symSize: 0xC4 } + - { offset: 0x838B, size: 0x8, addend: 0x0, symName: _safe_copy_string, symObjAddr: 0x7720, symBinAddr: 0xB720, symSize: 0xEC } + - { offset: 0x83F1, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctlbyname_block_invoke_2', symObjAddr: 0x780C, symBinAddr: 0xB80C, symSize: 0xC4 } + - { offset: 0x8457, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$getifaddrs_block_invoke', symObjAddr: 0x78D0, symBinAddr: 0xB8D0, symSize: 0x84 } + - { offset: 0x84A8, size: 0x8, addend: 0x0, symName: _modifyInterfaceIP, symObjAddr: 0x7954, symBinAddr: 0xB954, symSize: 0x16C } + - { offset: 0x853B, size: 0x8, addend: 0x0, symName: _createInterface, symObjAddr: 0x7AC0, symBinAddr: 0xBAC0, symSize: 0x3F4 } + - { offset: 0x85E4, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$UIAccessibilityIsClosedCaptioningEnabled', symObjAddr: 0x7EB4, symBinAddr: 0xBEB4, symSize: 0xC } + - { offset: 0x85FE, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$UIAccessibilityIsMonoAudioEnabled', symObjAddr: 0x7EC0, symBinAddr: 0xBEC0, symSize: 0xC } + - { offset: 0x8618, size: 0x8, addend: 0x0, symName: _cleanup, symObjAddr: 0x7ECC, symBinAddr: 0xBECC, symSize: 0x38 } + - { offset: 0x862E, size: 0x8, addend: 0x0, symName: ___GLOBAL_init_65535, symObjAddr: 0x84C0, symBinAddr: 0xBF04, symSize: 0x28 } +... diff --git a/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.Td b/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.Td new file mode 100644 index 0000000..55b15ca --- /dev/null +++ b/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.Td @@ -0,0 +1,12 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.o: \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/Tweak.x.m \ + /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h \ + /Users/mac/theos/vendor/include/substrate.h \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h: +/Users/mac/theos/vendor/include/substrate.h: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h: diff --git a/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.o b/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.o new file mode 100644 index 0000000..6fa27e4 Binary files /dev/null and b/.theos/obj/debug/arm64/Tweak.x.6ac62e6b.o differ diff --git a/.theos/obj/debug/arm64/Tweak.x.f9bf742d.Td b/.theos/obj/debug/arm64/Tweak.x.f9bf742d.Td new file mode 100644 index 0000000..9b32a48 --- /dev/null +++ b/.theos/obj/debug/arm64/Tweak.x.f9bf742d.Td @@ -0,0 +1,38 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/Tweak.x.f9bf742d.o: \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/Tweak.x.m \ + /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBAlertItemsController.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBUserNotificationAlert.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/module.modulemap \ + /Users/mac/theos/vendor/include/SpringBoardUI/SpringBoardUI.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/SBAlertItem.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/_SBAlertController.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBApplication.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBActivationSettings.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBWorkspace.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBApplicationController.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/MySimpleServer.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/FloatingWindow.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/XSHttpHelper.h \ + /Users/mac/theos/vendor/include/substrate.h \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h: +/Users/mac/theos/vendor/include/SpringBoard/SBAlertItemsController.h: +/Users/mac/theos/vendor/include/SpringBoard/SBUserNotificationAlert.h: +/Users/mac/theos/vendor/include/SpringBoardUI/module.modulemap: +/Users/mac/theos/vendor/include/SpringBoardUI/SpringBoardUI.h: +/Users/mac/theos/vendor/include/SpringBoardUI/SBAlertItem.h: +/Users/mac/theos/vendor/include/SpringBoardUI/_SBAlertController.h: +/Users/mac/theos/vendor/include/SpringBoard/SBApplication.h: +/Users/mac/theos/vendor/include/SpringBoard/SBActivationSettings.h: +/Users/mac/theos/vendor/include/SpringBoard/SBWorkspace.h: +/Users/mac/theos/vendor/include/SpringBoard/SBApplicationController.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/MySimpleServer.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/FloatingWindow.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/XSHttpHelper.h: +/Users/mac/theos/vendor/include/substrate.h: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h: diff --git a/.theos/obj/debug/arm64/Tweak.x.f9bf742d.o b/.theos/obj/debug/arm64/Tweak.x.f9bf742d.o new file mode 100644 index 0000000..1959da4 Binary files /dev/null and b/.theos/obj/debug/arm64/Tweak.x.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.Td new file mode 100644 index 0000000..b1d8473 --- /dev/null +++ b/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.Td @@ -0,0 +1,15 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.o: \ + server/FloatingWindow.m /Users/mac/theos/Prefix.pch \ + server/FloatingWindow.h server/XSHttpHelper.h server/XSPhoneConfig.h \ + server/XSPhoneInfo.h server/UIView+Toast.h server/MyEventBus.h \ + server/XSHelper.h server/MyAdTask2.h server/IPhoneHertbeat.h +/Users/mac/theos/Prefix.pch: +server/FloatingWindow.h: +server/XSHttpHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/UIView+Toast.h: +server/MyEventBus.h: +server/XSHelper.h: +server/MyAdTask2.h: +server/IPhoneHertbeat.h: diff --git a/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.o b/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.o new file mode 100644 index 0000000..468eb29 Binary files /dev/null and b/.theos/obj/debug/arm64/server/FloatingWindow.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.Td new file mode 100644 index 0000000..814ce5f --- /dev/null +++ b/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.Td @@ -0,0 +1,5 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.o: \ + server/GCD/GCDAsyncUdpSocket.m /Users/mac/theos/Prefix.pch \ + server/GCD/GCDAsyncUdpSocket.h +/Users/mac/theos/Prefix.pch: +server/GCD/GCDAsyncUdpSocket.h: diff --git a/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.o b/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.o new file mode 100644 index 0000000..254cd20 Binary files /dev/null and b/.theos/obj/debug/arm64/server/GCD/GCDAsyncUdpSocket.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.Td new file mode 100644 index 0000000..87516cd --- /dev/null +++ b/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.Td @@ -0,0 +1,47 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.o: \ + server/IPhoneHertbeat.m /Users/mac/theos/Prefix.pch \ + server/IPhoneHertbeat.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSHttpHelper.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/MyAdServer.h server/MyAdTask2.h +/Users/mac/theos/Prefix.pch: +server/IPhoneHertbeat.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSHttpHelper.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/MyAdServer.h: +server/MyAdTask2.h: diff --git a/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.o b/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.o new file mode 100644 index 0000000..a0a218f Binary files /dev/null and b/.theos/obj/debug/arm64/server/IPhoneHertbeat.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.Td new file mode 100644 index 0000000..ab68220 --- /dev/null +++ b/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.Td @@ -0,0 +1,50 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.o: \ + server/IosSystemCmd.m /Users/mac/theos/Prefix.pch \ + server/IosSystemCmd.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/MyEventBus.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/MyAdTask2.h +/Users/mac/theos/Prefix.pch: +server/IosSystemCmd.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/MyEventBus.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/MyAdTask2.h: diff --git a/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.o b/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.o new file mode 100644 index 0000000..908d7e3 Binary files /dev/null and b/.theos/obj/debug/arm64/server/IosSystemCmd.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.Td new file mode 100644 index 0000000..e72ae9c --- /dev/null +++ b/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.Td @@ -0,0 +1,10 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.o: \ + server/MyAdServer.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/MyAdServer.h server/XSHttpHelper.h server/XSPhoneConfig.h \ + server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.o b/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.o new file mode 100644 index 0000000..4b9d076 Binary files /dev/null and b/.theos/obj/debug/arm64/server/MyAdServer.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.Td new file mode 100644 index 0000000..ac73c97 --- /dev/null +++ b/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.Td @@ -0,0 +1,48 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.o: \ + server/MyAdTask2.m /Users/mac/theos/Prefix.pch server/IPhoneHertbeat.h \ + server/XSHackIos.h /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSHelper.h server/XSPhoneInfo.h \ + server/XSPhoneConfig.h server/MyAdServer.h server/XSHttpHelper.h \ + server/MyAdTask2.h server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/IPhoneHertbeat.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSHelper.h: +server/XSPhoneInfo.h: +server/XSPhoneConfig.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/MyAdTask2.h: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.o b/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.o new file mode 100644 index 0000000..a40daa7 Binary files /dev/null and b/.theos/obj/debug/arm64/server/MyAdTask2.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.Td new file mode 100644 index 0000000..b748166 --- /dev/null +++ b/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.Td @@ -0,0 +1,4 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.o: \ + server/MyEventBus.m /Users/mac/theos/Prefix.pch server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.o b/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.o new file mode 100644 index 0000000..b84ef47 Binary files /dev/null and b/.theos/obj/debug/arm64/server/MyEventBus.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.Td new file mode 100644 index 0000000..efaba29 --- /dev/null +++ b/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.Td @@ -0,0 +1,48 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.o: \ + server/MyScriptTask.m /Users/mac/theos/Prefix.pch \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/XSHelper.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/MyEventBus.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h +/Users/mac/theos/Prefix.pch: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/MyEventBus.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: diff --git a/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.o b/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.o new file mode 100644 index 0000000..ec18096 Binary files /dev/null and b/.theos/obj/debug/arm64/server/MyScriptTask.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.Td new file mode 100644 index 0000000..0c366e2 --- /dev/null +++ b/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.Td @@ -0,0 +1,53 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.o: \ + server/MySimpleServer.m /Users/mac/theos/Prefix.pch \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/XSHelper.h server/IPhoneHertbeat.h server/MySimpleServer.h \ + server/IosSystemCmd.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSHackIos.h server/MyAdTask2.h \ + server/XUDPServer.h server/CocoaAsyncSocket.h \ + server/GCD/GCDAsyncUdpSocket.h +/Users/mac/theos/Prefix.pch: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSHelper.h: +server/IPhoneHertbeat.h: +server/MySimpleServer.h: +server/IosSystemCmd.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSHackIos.h: +server/MyAdTask2.h: +server/XUDPServer.h: +server/CocoaAsyncSocket.h: +server/GCD/GCDAsyncUdpSocket.h: diff --git a/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.o b/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.o new file mode 100644 index 0000000..bb056ff Binary files /dev/null and b/.theos/obj/debug/arm64/server/MySimpleServer.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.Td new file mode 100644 index 0000000..96e4bbb --- /dev/null +++ b/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.Td @@ -0,0 +1,18 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.o: \ + server/UDPHandler.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/XSHackIos.h /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/MyAdTask2.h server/UDPHandler.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/MyAdTask2.h: +server/UDPHandler.h: diff --git a/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.o b/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.o new file mode 100644 index 0000000..26fe436 Binary files /dev/null and b/.theos/obj/debug/arm64/server/UDPHandler.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.Td new file mode 100644 index 0000000..c654714 --- /dev/null +++ b/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.Td @@ -0,0 +1,5 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.o: \ + server/UIView+Toast.m /Users/mac/theos/Prefix.pch \ + server/UIView+Toast.h +/Users/mac/theos/Prefix.pch: +server/UIView+Toast.h: diff --git a/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.o b/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.o new file mode 100644 index 0000000..5707a7e Binary files /dev/null and b/.theos/obj/debug/arm64/server/UIView+Toast.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.Td new file mode 100644 index 0000000..8d00035 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.Td @@ -0,0 +1,73 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.o: \ + server/XSHackIos.m /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SBWindow.h \ + /Users/mac/theos/vendor/include/FrontBoard/module.modulemap \ + /Users/mac/theos/vendor/include/FrontBoard/FrontBoard.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBApplicationInfo.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBBundleInfo.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBApplicationProcess.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcess.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBDisplayManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcessManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcessState.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSMutableSceneSettings.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettings.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettingsDiff.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBScene.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneClient.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneClientProvider.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneHostManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneHostWrapperView.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemApp.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemGestureManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemService.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWindow.h \ + /Users/mac/theos/vendor/include/UIKit/UIWindow+Private.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWindowContextHostManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEvent.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEventQueue.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSPhoneConfig.h server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SBWindow.h: +/Users/mac/theos/vendor/include/FrontBoard/module.modulemap: +/Users/mac/theos/vendor/include/FrontBoard/FrontBoard.h: +/Users/mac/theos/vendor/include/FrontBoard/FBApplicationInfo.h: +/Users/mac/theos/vendor/include/FrontBoard/FBBundleInfo.h: +/Users/mac/theos/vendor/include/FrontBoard/FBApplicationProcess.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcess.h: +/Users/mac/theos/vendor/include/FrontBoard/FBDisplayManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcessManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcessState.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSMutableSceneSettings.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettings.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettingsDiff.h: +/Users/mac/theos/vendor/include/FrontBoard/FBScene.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneClient.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneClientProvider.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneHostManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneHostWrapperView.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemApp.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemGestureManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemService.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWindow.h: +/Users/mac/theos/vendor/include/UIKit/UIWindow+Private.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWindowContextHostManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEvent.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEventQueue.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.o new file mode 100644 index 0000000..2965596 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSHackIos.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.Td new file mode 100644 index 0000000..152758f --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.Td @@ -0,0 +1,4 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.o: \ + server/XSHelper.m /Users/mac/theos/Prefix.pch server/XSHelper.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: diff --git a/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.o new file mode 100644 index 0000000..0bd4ee4 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSHelper.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.Td new file mode 100644 index 0000000..ded2ef2 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.Td @@ -0,0 +1,7 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.o: \ + server/XSHttpHelper.m /Users/mac/theos/Prefix.pch \ + server/XSHttpHelper.h server/XSHelper.h server/XSPhoneConfig.h +/Users/mac/theos/Prefix.pch: +server/XSHttpHelper.h: +server/XSHelper.h: +server/XSPhoneConfig.h: diff --git a/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.o new file mode 100644 index 0000000..65097b3 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSHttpHelper.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.Td new file mode 100644 index 0000000..788c283 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.Td @@ -0,0 +1,38 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.o: \ + server/XSIosTouch.m /Users/mac/theos/Prefix.pch server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSPhoneConfig.h server/XSHelper.h +/Users/mac/theos/Prefix.pch: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSPhoneConfig.h: +server/XSHelper.h: diff --git a/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.o new file mode 100644 index 0000000..0af13e2 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSIosTouch.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.Td new file mode 100644 index 0000000..cdd42b9 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.Td @@ -0,0 +1,7 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.o: \ + server/XSPhoneConfig.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/XSPhoneConfig.h server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/XSPhoneConfig.h: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.o new file mode 100644 index 0000000..d27fabd Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSPhoneConfig.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.Td new file mode 100644 index 0000000..05b7296 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.Td @@ -0,0 +1,19 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.o: \ + server/XSPhoneInfo.m /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/ps/IOPowerSources.h \ + /Users/mac/theos/vendor/include/IOKit/ps/IOPSKeys.h \ + server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/ps/IOPowerSources.h: +/Users/mac/theos/vendor/include/IOKit/ps/IOPSKeys.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.o new file mode 100644 index 0000000..279ee54 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XSPhoneInfo.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.Td b/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.Td new file mode 100644 index 0000000..ca878e0 --- /dev/null +++ b/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.Td @@ -0,0 +1,9 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.o: \ + server/XUDPServer.m /Users/mac/theos/Prefix.pch server/XUDPServer.h \ + server/CocoaAsyncSocket.h server/GCD/GCDAsyncUdpSocket.h \ + server/UDPHandler.h +/Users/mac/theos/Prefix.pch: +server/XUDPServer.h: +server/CocoaAsyncSocket.h: +server/GCD/GCDAsyncUdpSocket.h: +server/UDPHandler.h: diff --git a/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.o b/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.o new file mode 100644 index 0000000..709e246 Binary files /dev/null and b/.theos/obj/debug/arm64/server/XUDPServer.m.f9bf742d.o differ diff --git a/.theos/obj/debug/arm64e/AppRunMan.dylib b/.theos/obj/debug/arm64e/AppRunMan.dylib new file mode 100755 index 0000000..277e4c6 Binary files /dev/null and b/.theos/obj/debug/arm64e/AppRunMan.dylib differ diff --git a/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Info.plist b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Info.plist new file mode 100644 index 0000000..80e915b --- /dev/null +++ b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.AppRunMan.dylib + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib new file mode 100644 index 0000000..35f32e1 Binary files /dev/null and b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/DWARF/AppRunMan.dylib differ diff --git a/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/arm64e/AppRunMan.dylib.yml b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/arm64e/AppRunMan.dylib.yml new file mode 100644 index 0000000..f5a14aa --- /dev/null +++ b/.theos/obj/debug/arm64e/AppRunMan.dylib.dSYM/Contents/Resources/Relocations/arm64e/AppRunMan.dylib.yml @@ -0,0 +1,1041 @@ +--- +triple: 'arm64e-apple-darwin' +binary-path: '/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/AppRunMan.dylib' +relocations: + - { offset: 0x1E, size: 0x8, addend: 0x0, symName: '-[UIWindow(FloatingWindow) addFloatingWindow]', symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x110 } + - { offset: 0x37, size: 0x8, addend: 0x0, symName: _kSBAppTagsHidden, symObjAddr: 0x820, symBinAddr: 0x5C860, symSize: 0x0 } + - { offset: 0xBD, size: 0x8, addend: 0x0, symName: '__logos_orig$all$SpringBoard$applicationDidFinishLaunching$', symObjAddr: 0x7250, symBinAddr: 0x69630, symSize: 0x0 } + - { offset: 0x1F98, size: 0x8, addend: 0x0, symName: '__logos_orig$all$SpringBoard$applicationWillTerminate$', symObjAddr: 0x7258, symBinAddr: 0x69638, symSize: 0x0 } + - { offset: 0x1FA7, size: 0x8, addend: 0x0, symName: '-[UIWindow(FloatingWindow) addFloatingWindow]', symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x110 } + - { offset: 0x1FE7, size: 0x8, addend: 0x0, symName: __logosLocalCtor_a83cb02a, symObjAddr: 0x110, symBinAddr: 0x4110, symSize: 0x9C } + - { offset: 0x2060, size: 0x8, addend: 0x0, symName: '__logos_method$all$SpringBoard$applicationDidFinishLaunching$', symObjAddr: 0x1AC, symBinAddr: 0x41AC, symSize: 0x12C } + - { offset: 0x20C8, size: 0x8, addend: 0x0, symName: '__logos_method$all$SpringBoard$applicationWillTerminate$', symObjAddr: 0x2D8, symBinAddr: 0x42D8, symSize: 0x68 } + - { offset: 0x2108, size: 0x8, addend: 0x0, symName: '____logos_method$all$SpringBoard$applicationDidFinishLaunching$_block_invoke', symObjAddr: 0x340, symBinAddr: 0x4340, symSize: 0x2C } + - { offset: 0x2130, size: 0x8, addend: 0x0, symName: '____logos_method$all$SpringBoard$applicationDidFinishLaunching$_block_invoke_2', symObjAddr: 0x36C, symBinAddr: 0x436C, symSize: 0x37C } + - { offset: 0x2322, size: 0x8, addend: 0x0, symName: '-[FloatingWindow initWithFrame]', symObjAddr: 0x0, symBinAddr: 0x46E8, symSize: 0x2BC } + - { offset: 0x74E3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow initWithFrame]', symObjAddr: 0x0, symBinAddr: 0x46E8, symSize: 0x2BC } + - { offset: 0x7585, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x2BC, symBinAddr: 0x49A4, symSize: 0x4C } + - { offset: 0x75EB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow dealloc]', symObjAddr: 0x308, symBinAddr: 0x49F0, symSize: 0x80 } + - { offset: 0x761D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setupUI]', symObjAddr: 0x388, symBinAddr: 0x4A70, symSize: 0xAB4 } + - { offset: 0x765E, size: 0x8, addend: 0x0, symName: '-[FloatingWindow updateInfo]', symObjAddr: 0xE3C, symBinAddr: 0x5524, symSize: 0x200 } + - { offset: 0x76B6, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateStatus:]', symObjAddr: 0x103C, symBinAddr: 0x5724, symSize: 0x138 } + - { offset: 0x7718, size: 0x8, addend: 0x0, symName: '___38-[FloatingWindow onEventUpdateStatus:]_block_invoke', symObjAddr: 0x1174, symBinAddr: 0x585C, symSize: 0xC4 } + - { offset: 0x7762, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40w, symObjAddr: 0x1238, symBinAddr: 0x5920, symSize: 0x58 } + - { offset: 0x7786, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40w, symObjAddr: 0x1290, symBinAddr: 0x5978, symSize: 0x40 } + - { offset: 0x77A2, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateRunStatus:]', symObjAddr: 0x12D0, symBinAddr: 0x59B8, symSize: 0x138 } + - { offset: 0x7804, size: 0x8, addend: 0x0, symName: '___41-[FloatingWindow onEventUpdateRunStatus:]_block_invoke', symObjAddr: 0x1408, symBinAddr: 0x5AF0, symSize: 0x130 } + - { offset: 0x786A, size: 0x8, addend: 0x0, symName: '-[FloatingWindow showMyToast:]', symObjAddr: 0x1538, symBinAddr: 0x5C20, symSize: 0x138 } + - { offset: 0x78CC, size: 0x8, addend: 0x0, symName: '___30-[FloatingWindow showMyToast:]_block_invoke', symObjAddr: 0x1670, symBinAddr: 0x5D58, symSize: 0x5C } + - { offset: 0x7916, size: 0x8, addend: 0x0, symName: '-[FloatingWindow onEventUpdateName:]', symObjAddr: 0x16CC, symBinAddr: 0x5DB4, symSize: 0x10C } + - { offset: 0x7978, size: 0x8, addend: 0x0, symName: '___36-[FloatingWindow onEventUpdateName:]_block_invoke', symObjAddr: 0x17D8, symBinAddr: 0x5EC0, symSize: 0x118 } + - { offset: 0x79CD, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32w, symObjAddr: 0x18F0, symBinAddr: 0x5FD8, symSize: 0x38 } + - { offset: 0x79F1, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32w, symObjAddr: 0x1928, symBinAddr: 0x6010, symSize: 0x2C } + - { offset: 0x7A0D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow actionButtonTapped:]', symObjAddr: 0x1954, symBinAddr: 0x603C, symSize: 0xB4 } + - { offset: 0x7A69, size: 0x8, addend: 0x0, symName: '-[FloatingWindow settingsButtonTapped]', symObjAddr: 0x1A08, symBinAddr: 0x60F0, symSize: 0x3C } + - { offset: 0x7A9B, size: 0x8, addend: 0x0, symName: '-[FloatingWindow changeBackgroundColor]', symObjAddr: 0x1A44, symBinAddr: 0x612C, symSize: 0xD4 } + - { offset: 0x7AFB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow appendLog:]', symObjAddr: 0x1B18, symBinAddr: 0x6200, symSize: 0x27C } + - { offset: 0x7B85, size: 0x8, addend: 0x0, symName: '-[FloatingWindow detectPan:]', symObjAddr: 0x1D94, symBinAddr: 0x647C, symSize: 0x128 } + - { offset: 0x7BE1, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x1EBC, symBinAddr: 0x65A4, symSize: 0x2C } + - { offset: 0x7C29, size: 0x8, addend: 0x0, symName: '-[FloatingWindow nameLabel]', symObjAddr: 0x1EE8, symBinAddr: 0x65D0, symSize: 0x24 } + - { offset: 0x7C5F, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setNameLabel:]', symObjAddr: 0x1F0C, symBinAddr: 0x65F4, symSize: 0x40 } + - { offset: 0x7C9D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow ipLabel]', symObjAddr: 0x1F4C, symBinAddr: 0x6634, symSize: 0x24 } + - { offset: 0x7CD3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setIpLabel:]', symObjAddr: 0x1F70, symBinAddr: 0x6658, symSize: 0x40 } + - { offset: 0x7D11, size: 0x8, addend: 0x0, symName: '-[FloatingWindow deviceTypeLabel]', symObjAddr: 0x1FB0, symBinAddr: 0x6698, symSize: 0x24 } + - { offset: 0x7D47, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setDeviceTypeLabel:]', symObjAddr: 0x1FD4, symBinAddr: 0x66BC, symSize: 0x40 } + - { offset: 0x7D85, size: 0x8, addend: 0x0, symName: '-[FloatingWindow actionButton]', symObjAddr: 0x2014, symBinAddr: 0x66FC, symSize: 0x24 } + - { offset: 0x7DBB, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setActionButton:]', symObjAddr: 0x2038, symBinAddr: 0x6720, symSize: 0x40 } + - { offset: 0x7DF9, size: 0x8, addend: 0x0, symName: '-[FloatingWindow settingsButton]', symObjAddr: 0x2078, symBinAddr: 0x6760, symSize: 0x24 } + - { offset: 0x7E2F, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setSettingsButton:]', symObjAddr: 0x209C, symBinAddr: 0x6784, symSize: 0x40 } + - { offset: 0x7E6D, size: 0x8, addend: 0x0, symName: '-[FloatingWindow logTextView]', symObjAddr: 0x20DC, symBinAddr: 0x67C4, symSize: 0x24 } + - { offset: 0x7EA3, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setLogTextView:]', symObjAddr: 0x2100, symBinAddr: 0x67E8, symSize: 0x40 } + - { offset: 0x7EE1, size: 0x8, addend: 0x0, symName: '-[FloatingWindow http]', symObjAddr: 0x2140, symBinAddr: 0x6828, symSize: 0x24 } + - { offset: 0x7F17, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setHttp:]', symObjAddr: 0x2164, symBinAddr: 0x684C, symSize: 0x40 } + - { offset: 0x7F55, size: 0x8, addend: 0x0, symName: '-[FloatingWindow dataTask]', symObjAddr: 0x21A4, symBinAddr: 0x688C, symSize: 0x24 } + - { offset: 0x7F8B, size: 0x8, addend: 0x0, symName: '-[FloatingWindow setDataTask:]', symObjAddr: 0x21C8, symBinAddr: 0x68B0, symSize: 0x40 } + - { offset: 0x7FC9, size: 0x8, addend: 0x0, symName: '-[FloatingWindow .cxx_destruct]', symObjAddr: 0x2208, symBinAddr: 0x68F0, symSize: 0xEC } + - { offset: 0x8245, size: 0x8, addend: 0x0, symName: '+[IosSystemCmd sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x69DC, symSize: 0xDC } + - { offset: 0x8252, size: 0x8, addend: 0x0, symName: '+[IosSystemCmd sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x69DC, symSize: 0xDC } + - { offset: 0x827B, size: 0x8, addend: 0x0, symName: _sharedInstance.sharedInstance, symObjAddr: 0xAD68, symBinAddr: 0x69640, symSize: 0x0 } + - { offset: 0x8290, size: 0x8, addend: 0x0, symName: _sharedInstance.onceToken, symObjAddr: 0xAD70, symBinAddr: 0x69648, symSize: 0x0 } + - { offset: 0x903C, size: 0x8, addend: 0x0, symName: '___30+[IosSystemCmd sharedInstance]_block_invoke', symObjAddr: 0xDC, symBinAddr: 0x6AB8, symSize: 0x50 } + - { offset: 0x9079, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd init]', symObjAddr: 0x12C, symBinAddr: 0x6B08, symSize: 0x104 } + - { offset: 0x90AF, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd cmdUrl]', symObjAddr: 0x230, symBinAddr: 0x6C0C, symSize: 0xAC } + - { offset: 0x90E5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd cmdResUrl]', symObjAddr: 0x2DC, symBinAddr: 0x6CB8, symSize: 0xAC } + - { offset: 0x911B, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd start]', symObjAddr: 0x388, symBinAddr: 0x6D64, symSize: 0x17C } + - { offset: 0x915B, size: 0x8, addend: 0x0, symName: '___21-[IosSystemCmd start]_block_invoke', symObjAddr: 0x504, symBinAddr: 0x6EE0, symSize: 0x64 } + - { offset: 0x9194, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd runTask]', symObjAddr: 0x5CC, symBinAddr: 0x6F44, symSize: 0x374 } + - { offset: 0x9213, size: 0x8, addend: 0x0, symName: '___23-[IosSystemCmd runTask]_block_invoke', symObjAddr: 0x940, symBinAddr: 0x72B8, symSize: 0x22C } + - { offset: 0x9282, size: 0x8, addend: 0x0, symName: '___23-[IosSystemCmd runTask]_block_invoke.36', symObjAddr: 0xB6C, symBinAddr: 0x74E4, symSize: 0x68 } + - { offset: 0x92B8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeTask:]', symObjAddr: 0xBD4, symBinAddr: 0x754C, symSize: 0x654 } + - { offset: 0x931A, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd putTask:error:data:]', symObjAddr: 0x1228, symBinAddr: 0x7BA0, symSize: 0x1C8 } + - { offset: 0x9389, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd putTask:error:data:]_block_invoke', symObjAddr: 0x13F0, symBinAddr: 0x7D68, symSize: 0x98 } + - { offset: 0x93BF, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd putTask:error:data:]_block_invoke_2', symObjAddr: 0x1488, symBinAddr: 0x7E00, symSize: 0x68 } + - { offset: 0x93F5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeEditName:data:]', symObjAddr: 0x14F0, symBinAddr: 0x7E68, symSize: 0x148 } + - { offset: 0x9465, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUploadApps:data:]', symObjAddr: 0x1638, symBinAddr: 0x7FB0, symSize: 0x134 } + - { offset: 0x94CF, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeStart:data:]', symObjAddr: 0x176C, symBinAddr: 0x80E4, symSize: 0x13C } + - { offset: 0x951D, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeStop:data:]', symObjAddr: 0x18A8, symBinAddr: 0x8220, symSize: 0x13C } + - { offset: 0x9583, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeScreenshot:data:]', symObjAddr: 0x19E4, symBinAddr: 0x835C, symSize: 0x184 } + - { offset: 0x95E5, size: 0x8, addend: 0x0, symName: '___39-[IosSystemCmd executeScreenshot:data:]_block_invoke', symObjAddr: 0x1B68, symBinAddr: 0x84E0, symSize: 0xF0 } + - { offset: 0x966E, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s, symObjAddr: 0x1C58, symBinAddr: 0x85D0, symSize: 0x74 } + - { offset: 0x9692, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s, symObjAddr: 0x1CCC, symBinAddr: 0x8644, symSize: 0x58 } + - { offset: 0x96AE, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUnlock:data:]', symObjAddr: 0x1D24, symBinAddr: 0x869C, symSize: 0xA8 } + - { offset: 0x9710, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd executeUnlock:data:]_block_invoke', symObjAddr: 0x1DCC, symBinAddr: 0x8744, symSize: 0x2C } + - { offset: 0x9738, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeRestart:data:]', symObjAddr: 0x1DF8, symBinAddr: 0x8770, symSize: 0xA8 } + - { offset: 0x979E, size: 0x8, addend: 0x0, symName: '___36-[IosSystemCmd executeRestart:data:]_block_invoke', symObjAddr: 0x1EA0, symBinAddr: 0x8818, symSize: 0x34 } + - { offset: 0x97C8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeReboot:data:]', symObjAddr: 0x1ED4, symBinAddr: 0x884C, symSize: 0xA8 } + - { offset: 0x982E, size: 0x8, addend: 0x0, symName: '___35-[IosSystemCmd executeReboot:data:]_block_invoke', symObjAddr: 0x1F7C, symBinAddr: 0x88F4, symSize: 0x2C } + - { offset: 0x9858, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeTouch:data:]', symObjAddr: 0x1FA8, symBinAddr: 0x8920, symSize: 0x12C } + - { offset: 0x98BE, size: 0x8, addend: 0x0, symName: '___34-[IosSystemCmd executeTouch:data:]_block_invoke', symObjAddr: 0x20D4, symBinAddr: 0x8A4C, symSize: 0x2A0 } + - { offset: 0x9954, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s, symObjAddr: 0x2374, symBinAddr: 0x8CEC, symSize: 0x3C } + - { offset: 0x9978, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s, symObjAddr: 0x23B0, symBinAddr: 0x8D28, symSize: 0x30 } + - { offset: 0x9994, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeUpdateKey:data:]', symObjAddr: 0x23E0, symBinAddr: 0x8D58, symSize: 0xAC } + - { offset: 0x99E5, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd executeKey:data:]', symObjAddr: 0x248C, symBinAddr: 0x8E04, symSize: 0x12C } + - { offset: 0x9A4B, size: 0x8, addend: 0x0, symName: '___32-[IosSystemCmd executeKey:data:]_block_invoke', symObjAddr: 0x25B8, symBinAddr: 0x8F30, symSize: 0x270 } + - { offset: 0x9AD1, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd getMyApps]', symObjAddr: 0x2828, symBinAddr: 0x91A0, symSize: 0x130 } + - { offset: 0x9B26, size: 0x8, addend: 0x0, symName: '___25-[IosSystemCmd getMyApps]_block_invoke', symObjAddr: 0x2958, symBinAddr: 0x92D0, symSize: 0x4C8 } + - { offset: 0x9BE8, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd stop]', symObjAddr: 0x2E20, symBinAddr: 0x9798, symSize: 0x54 } + - { offset: 0x9C1B, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd dealloc]', symObjAddr: 0x2E74, symBinAddr: 0x97EC, symSize: 0x54 } + - { offset: 0x9C4E, size: 0x8, addend: 0x0, symName: '-[IosSystemCmd .cxx_destruct]', symObjAddr: 0x2EC8, symBinAddr: 0x9840, symSize: 0x6C } + - { offset: 0xA8AE, size: 0x8, addend: 0x0, symName: '+[IPhoneHertbeat sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x98AC, symSize: 0x90 } + - { offset: 0xA8BB, size: 0x8, addend: 0x0, symName: '+[IPhoneHertbeat sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x98AC, symSize: 0x90 } + - { offset: 0xA8E4, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x9448, symBinAddr: 0x69650, symSize: 0x0 } + - { offset: 0xA8F9, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x9450, symBinAddr: 0x69658, symSize: 0x0 } + - { offset: 0xB596, size: 0x8, addend: 0x0, symName: '___32+[IPhoneHertbeat sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x993C, symSize: 0x50 } + - { offset: 0xB5BE, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat init]', symObjAddr: 0xE0, symBinAddr: 0x998C, symSize: 0x170 } + - { offset: 0xB5F4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat stop]', symObjAddr: 0x250, symBinAddr: 0x9AFC, symSize: 0x54 } + - { offset: 0xB626, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat dealloc]', symObjAddr: 0x2A4, symBinAddr: 0x9B50, symSize: 0x60 } + - { offset: 0xB658, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat start]', symObjAddr: 0x304, symBinAddr: 0x9BB0, symSize: 0x180 } + - { offset: 0xB698, size: 0x8, addend: 0x0, symName: '___23-[IPhoneHertbeat start]_block_invoke', symObjAddr: 0x484, symBinAddr: 0x9D30, symSize: 0x64 } + - { offset: 0xB6D1, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat checkxxx]', symObjAddr: 0x54C, symBinAddr: 0x9D94, symSize: 0x178 } + - { offset: 0xB767, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat ping]', symObjAddr: 0x6C4, symBinAddr: 0x9F0C, symSize: 0x70C } + - { offset: 0xB820, size: 0x8, addend: 0x0, symName: '___22-[IPhoneHertbeat ping]_block_invoke', symObjAddr: 0xDD0, symBinAddr: 0xA618, symSize: 0x58 } + - { offset: 0xB848, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat sendHeartbeat:toURL:]', symObjAddr: 0xE28, symBinAddr: 0xA670, symSize: 0xDC } + - { offset: 0xB896, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat sendHeartbeat:toURL:]_block_invoke', symObjAddr: 0xF04, symBinAddr: 0xA74C, symSize: 0xA8 } + - { offset: 0xB8CC, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat sendHeartbeat:toURL:]_block_invoke_2', symObjAddr: 0xFAC, symBinAddr: 0xA7F4, symSize: 0x68 } + - { offset: 0xB902, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat constructHeartbeatData]', symObjAddr: 0x1014, symBinAddr: 0xA85C, symSize: 0x594 } + - { offset: 0xB957, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat checkAndPerformTasks]', symObjAddr: 0x15A8, symBinAddr: 0xADF0, symSize: 0x164 } + - { offset: 0xB9A5, size: 0x8, addend: 0x0, symName: '___38-[IPhoneHertbeat checkAndPerformTasks]_block_invoke', symObjAddr: 0x170C, symBinAddr: 0xAF54, symSize: 0xD4 } + - { offset: 0xB9F2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat safePerformTouchEvents]', symObjAddr: 0x17E0, symBinAddr: 0xB028, symSize: 0x1E8 } + - { offset: 0xBA66, size: 0x8, addend: 0x0, symName: '___40-[IPhoneHertbeat safePerformTouchEvents]_block_invoke', symObjAddr: 0x19C8, symBinAddr: 0xB210, symSize: 0x2D0 } + - { offset: 0xBAF4, size: 0x8, addend: 0x0, symName: '___40-[IPhoneHertbeat safePerformTouchEvents]_block_invoke_2', symObjAddr: 0x1C98, symBinAddr: 0xB4E0, symSize: 0x31C } + - { offset: 0xBB83, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat cleanup]', symObjAddr: 0x204C, symBinAddr: 0xB7FC, symSize: 0x48 } + - { offset: 0xBBB6, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat cancelCurrentTask]', symObjAddr: 0x2094, symBinAddr: 0xB844, symSize: 0xA0 } + - { offset: 0xBBE9, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat reset]', symObjAddr: 0x2134, symBinAddr: 0xB8E4, symSize: 0x3C } + - { offset: 0xBC1C, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat name]', symObjAddr: 0x2170, symBinAddr: 0xB920, symSize: 0x1C } + - { offset: 0xBC52, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setName:]', symObjAddr: 0x218C, symBinAddr: 0xB93C, symSize: 0x38 } + - { offset: 0xBC90, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat deviceId]', symObjAddr: 0x21C4, symBinAddr: 0xB974, symSize: 0x1C } + - { offset: 0xBCC6, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setDeviceId:]', symObjAddr: 0x21E0, symBinAddr: 0xB990, symSize: 0x38 } + - { offset: 0xBD04, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat ip]', symObjAddr: 0x2218, symBinAddr: 0xB9C8, symSize: 0x1C } + - { offset: 0xBD3A, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setIp:]', symObjAddr: 0x2234, symBinAddr: 0xB9E4, symSize: 0x38 } + - { offset: 0xBD78, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat appId]', symObjAddr: 0x226C, symBinAddr: 0xBA1C, symSize: 0x1C } + - { offset: 0xBDAE, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setAppId:]', symObjAddr: 0x2288, symBinAddr: 0xBA38, symSize: 0x38 } + - { offset: 0xBDEC, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat apps]', symObjAddr: 0x22C0, symBinAddr: 0xBA70, symSize: 0x1C } + - { offset: 0xBE22, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setApps:]', symObjAddr: 0x22DC, symBinAddr: 0xBA8C, symSize: 0x38 } + - { offset: 0xBE60, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat message]', symObjAddr: 0x2314, symBinAddr: 0xBAC4, symSize: 0x1C } + - { offset: 0xBE96, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setMessage:]', symObjAddr: 0x2330, symBinAddr: 0xBAE0, symSize: 0x38 } + - { offset: 0xBED4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat status]', symObjAddr: 0x2368, symBinAddr: 0xBB18, symSize: 0x1C } + - { offset: 0xBF0A, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setStatus:]', symObjAddr: 0x2384, symBinAddr: 0xBB34, symSize: 0x38 } + - { offset: 0xBF48, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat diskSize]', symObjAddr: 0x23BC, symBinAddr: 0xBB6C, symSize: 0x1C } + - { offset: 0xBF7E, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setDiskSize:]', symObjAddr: 0x23D8, symBinAddr: 0xBB88, symSize: 0x38 } + - { offset: 0xBFBC, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat remoteIp]', symObjAddr: 0x2410, symBinAddr: 0xBBC0, symSize: 0x1C } + - { offset: 0xBFF2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setRemoteIp:]', symObjAddr: 0x242C, symBinAddr: 0xBBDC, symSize: 0x38 } + - { offset: 0xC030, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat lastTouchTime]', symObjAddr: 0x2464, symBinAddr: 0xBC14, symSize: 0x1C } + - { offset: 0xC066, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setLastTouchTime:]', symObjAddr: 0x2480, symBinAddr: 0xBC30, symSize: 0x24 } + - { offset: 0xC0A4, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat isProcessingTouch]', symObjAddr: 0x24A4, symBinAddr: 0xBC54, symSize: 0x20 } + - { offset: 0xC0DA, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setIsProcessingTouch:]', symObjAddr: 0x24C4, symBinAddr: 0xBC74, symSize: 0x28 } + - { offset: 0xC118, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat touchQueue]', symObjAddr: 0x24EC, symBinAddr: 0xBC9C, symSize: 0x1C } + - { offset: 0xC14E, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setTouchQueue:]', symObjAddr: 0x2508, symBinAddr: 0xBCB8, symSize: 0x38 } + - { offset: 0xC18C, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat lastCheckTaskTime]', symObjAddr: 0x2540, symBinAddr: 0xBCF0, symSize: 0x1C } + - { offset: 0xC1C2, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setLastCheckTaskTime:]', symObjAddr: 0x255C, symBinAddr: 0xBD0C, symSize: 0x24 } + - { offset: 0xC200, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat touchTimer]', symObjAddr: 0x2580, symBinAddr: 0xBD30, symSize: 0x1C } + - { offset: 0xC236, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat setTouchTimer:]', symObjAddr: 0x259C, symBinAddr: 0xBD4C, symSize: 0x38 } + - { offset: 0xC274, size: 0x8, addend: 0x0, symName: '-[IPhoneHertbeat .cxx_destruct]', symObjAddr: 0x25D4, symBinAddr: 0xBD84, symSize: 0x12C } + - { offset: 0xC6DF, size: 0x8, addend: 0x0, symName: _pushAdTaskLog, symObjAddr: 0x0, symBinAddr: 0xBEB0, symSize: 0x24C } + - { offset: 0xC88C, size: 0x8, addend: 0x0, symName: _pushAdTaskLog, symObjAddr: 0x0, symBinAddr: 0xBEB0, symSize: 0x24C } + - { offset: 0xC8C0, size: 0x8, addend: 0x0, symName: _saveAdTaskLog, symObjAddr: 0x24C, symBinAddr: 0xC0FC, symSize: 0x124 } + - { offset: 0xC91C, size: 0x8, addend: 0x0, symName: ___saveAdTaskLog_block_invoke, symObjAddr: 0x370, symBinAddr: 0xC220, symSize: 0x94 } + - { offset: 0xC952, size: 0x8, addend: 0x0, symName: ___saveAdTaskLog_block_invoke_2, symObjAddr: 0x404, symBinAddr: 0xC2B4, symSize: 0x68 } + - { offset: 0xC988, size: 0x8, addend: 0x0, symName: _getLowEcpm, symObjAddr: 0x46C, symBinAddr: 0xC31C, symSize: 0x284 } + - { offset: 0xC9E4, size: 0x8, addend: 0x0, symName: ___getLowEcpm_block_invoke, symObjAddr: 0x6F0, symBinAddr: 0xC5A0, symSize: 0x214 } + - { offset: 0xCA4D, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b, symObjAddr: 0x904, symBinAddr: 0xC7B4, symSize: 0x3C } + - { offset: 0xCA71, size: 0x8, addend: 0x0, symName: ___getLowEcpm_block_invoke.59, symObjAddr: 0x970, symBinAddr: 0xC7F0, symSize: 0xA4 } + - { offset: 0xCAB8, size: 0x8, addend: 0x0, symName: _needAdContinue, symObjAddr: 0xA14, symBinAddr: 0xC894, symSize: 0x400 } + - { offset: 0xCB59, size: 0x8, addend: 0x0, symName: _getChangeInfo, symObjAddr: 0xE14, symBinAddr: 0xCC94, symSize: 0x314 } + - { offset: 0xCBC3, size: 0x8, addend: 0x0, symName: ___getChangeInfo_block_invoke, symObjAddr: 0x1128, symBinAddr: 0xCFA8, symSize: 0x250 } + - { offset: 0xCC4B, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b40b, symObjAddr: 0x1378, symBinAddr: 0xD1F8, symSize: 0x60 } + - { offset: 0xCC6F, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s, symObjAddr: 0x13D8, symBinAddr: 0xD258, symSize: 0x48 } + - { offset: 0xCC8B, size: 0x8, addend: 0x0, symName: ___getChangeInfo_block_invoke.81, symObjAddr: 0x1420, symBinAddr: 0xD2A0, symSize: 0x88 } + - { offset: 0xCCD2, size: 0x8, addend: 0x0, symName: __newgetChangeInfo, symObjAddr: 0x14A8, symBinAddr: 0xD328, symSize: 0x314 } + - { offset: 0xCD3C, size: 0x8, addend: 0x0, symName: ____newgetChangeInfo_block_invoke, symObjAddr: 0x17BC, symBinAddr: 0xD63C, symSize: 0x324 } + - { offset: 0xCDE1, size: 0x8, addend: 0x0, symName: ____newgetChangeInfo_block_invoke_2, symObjAddr: 0x1AE0, symBinAddr: 0xD960, symSize: 0x88 } + - { offset: 0xCE28, size: 0x8, addend: 0x0, symName: _saveChangeDataFile, symObjAddr: 0x1B68, symBinAddr: 0xD9E8, symSize: 0x4C0 } + - { offset: 0xCED1, size: 0x8, addend: 0x0, symName: ___saveChangeDataFile_block_invoke, symObjAddr: 0x2028, symBinAddr: 0xDEA8, symSize: 0x250 } + - { offset: 0xCF48, size: 0x8, addend: 0x0, symName: ___saveChangeDataFile_block_invoke_2, symObjAddr: 0x2278, symBinAddr: 0xE0F8, symSize: 0x124 } + - { offset: 0xCFAB, size: 0x8, addend: 0x0, symName: _getAdLoadInfo, symObjAddr: 0x23D8, symBinAddr: 0xE21C, symSize: 0xD88 } + - { offset: 0xD05D, size: 0x8, addend: 0x0, symName: ___destructor_8_s0_s8_s16_s24_s32_s40, symObjAddr: 0x3160, symBinAddr: 0xEFA4, symSize: 0x84 } + - { offset: 0xD07D, size: 0x8, addend: 0x0, symName: _pushInfo, symObjAddr: 0x31E4, symBinAddr: 0xF028, symSize: 0x304 } + - { offset: 0xD123, size: 0x8, addend: 0x0, symName: ___pushInfo_block_invoke, symObjAddr: 0x34E8, symBinAddr: 0xF32C, symSize: 0x294 } + - { offset: 0xD1AF, size: 0x8, addend: 0x0, symName: _pushIphoneLog, symObjAddr: 0x377C, symBinAddr: 0xF5C0, symSize: 0x3A0 } + - { offset: 0xD256, size: 0x8, addend: 0x0, symName: ___pushIphoneLog_block_invoke, symObjAddr: 0x3B1C, symBinAddr: 0xF960, symSize: 0x9C } + - { offset: 0xD2AC, size: 0x8, addend: 0x0, symName: ___pushIphoneLog_block_invoke_2, symObjAddr: 0x3BB8, symBinAddr: 0xF9FC, symSize: 0x68 } + - { offset: 0xD2E5, size: 0x8, addend: 0x0, symName: _logMessage, symObjAddr: 0x3C20, symBinAddr: 0xFA64, symSize: 0x264 } + - { offset: 0xD373, size: 0x8, addend: 0x0, symName: _uncaughtExceptionHandler, symObjAddr: 0x3E84, symBinAddr: 0xFCC8, symSize: 0x1D8 } + - { offset: 0xD3E4, size: 0x8, addend: 0x0, symName: _signalHandler, symObjAddr: 0x405C, symBinAddr: 0xFEA0, symSize: 0x154 } + - { offset: 0xD465, size: 0x8, addend: 0x0, symName: _registerSignalHandler, symObjAddr: 0x41B0, symBinAddr: 0xFFF4, symSize: 0x8C } + - { offset: 0xEA2C, size: 0x8, addend: 0x0, symName: '+[MyAdTask2Mangger sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x10080, symSize: 0x90 } + - { offset: 0xEA45, size: 0x8, addend: 0x0, symName: _myadTaskManualStop, symObjAddr: 0xCB35, symBinAddr: 0x69760, symSize: 0x0 } + - { offset: 0xEA60, size: 0x8, addend: 0x0, symName: '+[MyAdTask2Mangger sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x10080, symSize: 0x90 } + - { offset: 0xEA89, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xCB38, symBinAddr: 0x69660, symSize: 0x0 } + - { offset: 0xEA9E, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xCB40, symBinAddr: 0x69668, symSize: 0x0 } + - { offset: 0xEE16, size: 0x8, addend: 0x0, symName: '___34+[MyAdTask2Mangger sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x10110, symSize: 0x50 } + - { offset: 0xEE3E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger init]', symObjAddr: 0xE0, symBinAddr: 0x10160, symSize: 0x22C } + - { offset: 0xEEAD, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onShow:]', symObjAddr: 0x30C, symBinAddr: 0x1038C, symSize: 0x6D0 } + - { offset: 0xEFA8, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger showStatus:]', symObjAddr: 0xA60, symBinAddr: 0x10A5C, symSize: 0x90 } + - { offset: 0xEFE8, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setRemoteInfo]', symObjAddr: 0xAF0, symBinAddr: 0x10AEC, symSize: 0x1B8 } + - { offset: 0xF044, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger setRemoteInfo]_block_invoke', symObjAddr: 0xCA8, symBinAddr: 0x10CA4, symSize: 0x318 } + - { offset: 0xF0D1, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger setRemoteInfo]_block_invoke.64', symObjAddr: 0x1024, symBinAddr: 0x10FBC, symSize: 0x108 } + - { offset: 0xF118, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setRemoteInfo1]', symObjAddr: 0x112C, symBinAddr: 0x110C4, symSize: 0x240 } + - { offset: 0xF174, size: 0x8, addend: 0x0, symName: '___34-[MyAdTask2Mangger setRemoteInfo1]_block_invoke', symObjAddr: 0x136C, symBinAddr: 0x11304, symSize: 0x3BC } + - { offset: 0xF212, size: 0x8, addend: 0x0, symName: '___34-[MyAdTask2Mangger setRemoteInfo1]_block_invoke_2', symObjAddr: 0x1728, symBinAddr: 0x116C0, symSize: 0x108 } + - { offset: 0xF259, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onEnd:]', symObjAddr: 0x1830, symBinAddr: 0x117C8, symSize: 0x314 } + - { offset: 0xF2D7, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger onEnd:]_block_invoke', symObjAddr: 0x1B44, symBinAddr: 0x11ADC, symSize: 0x64 } + - { offset: 0xF310, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger onEnd:]_block_invoke.91', symObjAddr: 0x1BA8, symBinAddr: 0x11B40, symSize: 0x64 } + - { offset: 0xF349, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger startApp]', symObjAddr: 0x1C0C, symBinAddr: 0x11BA4, symSize: 0x290 } + - { offset: 0xF3BC, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke', symObjAddr: 0x1E9C, symBinAddr: 0x11E34, symSize: 0x134 } + - { offset: 0xF407, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke_2', symObjAddr: 0x1FD0, symBinAddr: 0x11F68, symSize: 0x5C } + - { offset: 0xF455, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger startApp]_block_invoke.96', symObjAddr: 0x20C4, symBinAddr: 0x11FC4, symSize: 0x68 } + - { offset: 0xF48E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger start]', symObjAddr: 0x212C, symBinAddr: 0x1202C, symSize: 0x28C } + - { offset: 0xF4D0, size: 0x8, addend: 0x0, symName: '___25-[MyAdTask2Mangger start]_block_invoke', symObjAddr: 0x23B8, symBinAddr: 0x122B8, symSize: 0x64 } + - { offset: 0xF50C, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger proc]', symObjAddr: 0x241C, symBinAddr: 0x1231C, symSize: 0x124 } + - { offset: 0xF57A, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger toggle]', symObjAddr: 0x2540, symBinAddr: 0x12440, symSize: 0xAC } + - { offset: 0xF5B1, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger stop]', symObjAddr: 0x25EC, symBinAddr: 0x124EC, symSize: 0x11C } + - { offset: 0xF5E4, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger onChangeInfo:]', symObjAddr: 0x2708, symBinAddr: 0x12608, symSize: 0x558 } + - { offset: 0xF694, size: 0x8, addend: 0x0, symName: '___33-[MyAdTask2Mangger onChangeInfo:]_block_invoke', symObjAddr: 0x2C60, symBinAddr: 0x12B60, symSize: 0x68 } + - { offset: 0xF6E6, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s, symObjAddr: 0x2CC8, symBinAddr: 0x12BC8, symSize: 0x5C } + - { offset: 0xF70A, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger appKill:]', symObjAddr: 0x2D6C, symBinAddr: 0x12C24, symSize: 0x64 } + - { offset: 0xF764, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger unlock]', symObjAddr: 0x2DD0, symBinAddr: 0x12C88, symSize: 0x6C } + - { offset: 0xF7AC, size: 0x8, addend: 0x0, symName: '___26-[MyAdTask2Mangger unlock]_block_invoke', symObjAddr: 0x2E3C, symBinAddr: 0x12CF4, symSize: 0x2C } + - { offset: 0xF7D6, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger resetApp:callback:]', symObjAddr: 0x2E68, symBinAddr: 0x12D20, symSize: 0x370 } + - { offset: 0xF885, size: 0x8, addend: 0x0, symName: '___38-[MyAdTask2Mangger resetApp:callback:]_block_invoke', symObjAddr: 0x31D8, symBinAddr: 0x13090, symSize: 0x2D8 } + - { offset: 0xF98D, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56b64w, symObjAddr: 0x34B0, symBinAddr: 0x13368, symSize: 0xA0 } + - { offset: 0xF9B1, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56s64w, symObjAddr: 0x3550, symBinAddr: 0x13408, symSize: 0x74 } + - { offset: 0xF9CD, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger frontMostAppId]', symObjAddr: 0x35C4, symBinAddr: 0x1347C, symSize: 0x28 } + - { offset: 0xFA04, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger appRun:]', symObjAddr: 0x35EC, symBinAddr: 0x134A4, symSize: 0x12C } + - { offset: 0xFA5B, size: 0x8, addend: 0x0, symName: '___27-[MyAdTask2Mangger appRun:]_block_invoke', symObjAddr: 0x3718, symBinAddr: 0x135D0, symSize: 0xC0 } + - { offset: 0xFAAC, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger tap:x:y:]', symObjAddr: 0x3844, symBinAddr: 0x13690, symSize: 0xC8 } + - { offset: 0xFB21, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger tap:x:y:]_block_invoke', symObjAddr: 0x390C, symBinAddr: 0x13758, symSize: 0x7C } + - { offset: 0xFB9E, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger restart:]', symObjAddr: 0x3988, symBinAddr: 0x137D4, symSize: 0x160 } + - { offset: 0xFBEF, size: 0x8, addend: 0x0, symName: '___28-[MyAdTask2Mangger restart:]_block_invoke', symObjAddr: 0x3AE8, symBinAddr: 0x13934, symSize: 0x310 } + - { offset: 0xFC67, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b40w, symObjAddr: 0x3DF8, symBinAddr: 0x13C44, symSize: 0x58 } + - { offset: 0xFC8B, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger rndTouchApp]', symObjAddr: 0x3E50, symBinAddr: 0x13C9C, symSize: 0x148 } + - { offset: 0xFD1D, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger touchAppTask:]', symObjAddr: 0x3F98, symBinAddr: 0x13DE4, symSize: 0x11C } + - { offset: 0xFD8C, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getStr:dic:]', symObjAddr: 0x40B4, symBinAddr: 0x13F00, symSize: 0x204 } + - { offset: 0xFDF0, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getNum:dic:]', symObjAddr: 0x42B8, symBinAddr: 0x14104, symSize: 0x24C } + - { offset: 0xFE72, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger getInt:dic:]', symObjAddr: 0x4504, symBinAddr: 0x14350, symSize: 0x238 } + - { offset: 0xFEF4, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger dealloc]', symObjAddr: 0x473C, symBinAddr: 0x14588, symSize: 0x54 } + - { offset: 0xFF27, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger manQueue]', symObjAddr: 0x4790, symBinAddr: 0x145DC, symSize: 0x1C } + - { offset: 0xFF5D, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger setManQueue:]', symObjAddr: 0x47AC, symBinAddr: 0x145F8, symSize: 0x38 } + - { offset: 0xFF9B, size: 0x8, addend: 0x0, symName: '-[MyAdTask2Mangger .cxx_destruct]', symObjAddr: 0x47E4, symBinAddr: 0x14630, symSize: 0xDC } + - { offset: 0x110B5, size: 0x8, addend: 0x0, symName: '+[MyEventBus sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x1470C, symSize: 0xDC } + - { offset: 0x110C2, size: 0x8, addend: 0x0, symName: '+[MyEventBus sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x1470C, symSize: 0xDC } + - { offset: 0x110EB, size: 0x8, addend: 0x0, symName: _sharedInstance.sharedInstance, symObjAddr: 0x2430, symBinAddr: 0x69670, symSize: 0x0 } + - { offset: 0x11100, size: 0x8, addend: 0x0, symName: _sharedInstance.onceToken, symObjAddr: 0x2438, symBinAddr: 0x69678, symSize: 0x0 } + - { offset: 0x112A4, size: 0x8, addend: 0x0, symName: '___28+[MyEventBus sharedInstance]_block_invoke', symObjAddr: 0xDC, symBinAddr: 0x147E8, symSize: 0x50 } + - { offset: 0x112E1, size: 0x8, addend: 0x0, symName: '-[MyEventBus init]', symObjAddr: 0x12C, symBinAddr: 0x14838, symSize: 0xDC } + - { offset: 0x11317, size: 0x8, addend: 0x0, symName: '-[MyEventBus registerSubscriber:]', symObjAddr: 0x208, symBinAddr: 0x14914, symSize: 0x240 } + - { offset: 0x113C6, size: 0x8, addend: 0x0, symName: '-[MyEventBus unregisterSubscriber:]', symObjAddr: 0x448, symBinAddr: 0x14B54, symSize: 0x104 } + - { offset: 0x11406, size: 0x8, addend: 0x0, symName: '___35-[MyEventBus unregisterSubscriber:]_block_invoke', symObjAddr: 0x54C, symBinAddr: 0x14C58, symSize: 0x94 } + - { offset: 0x11469, size: 0x8, addend: 0x0, symName: '-[MyEventBus postEvent:withObject:]', symObjAddr: 0x64C, symBinAddr: 0x14CEC, symSize: 0x2C8 } + - { offset: 0x11504, size: 0x8, addend: 0x0, symName: '-[MyEventBus subscribers]', symObjAddr: 0x914, symBinAddr: 0x14FB4, symSize: 0x1C } + - { offset: 0x1153A, size: 0x8, addend: 0x0, symName: '-[MyEventBus setSubscribers:]', symObjAddr: 0x930, symBinAddr: 0x14FD0, symSize: 0x38 } + - { offset: 0x11578, size: 0x8, addend: 0x0, symName: '-[MyEventBus .cxx_destruct]', symObjAddr: 0x968, symBinAddr: 0x15008, symSize: 0x34 } + - { offset: 0x117CD, size: 0x8, addend: 0x0, symName: '-[MyScriptTask init]', symObjAddr: 0x0, symBinAddr: 0x1503C, symSize: 0x388 } + - { offset: 0x117E8, size: 0x8, addend: 0x0, symName: '+[MyScriptTask sharedInstance]', symObjAddr: 0x3A48, symBinAddr: 0x18974, symSize: 0x90 } + - { offset: 0x11813, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xD858, symBinAddr: 0x69680, symSize: 0x0 } + - { offset: 0x11829, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xD860, symBinAddr: 0x69688, symSize: 0x0 } + - { offset: 0x11E8A, size: 0x8, addend: 0x0, symName: '-[MyScriptTask init]', symObjAddr: 0x0, symBinAddr: 0x1503C, symSize: 0x388 } + - { offset: 0x11EDC, size: 0x8, addend: 0x0, symName: '-[MyScriptTask showStatus:]', symObjAddr: 0x388, symBinAddr: 0x153C4, symSize: 0x90 } + - { offset: 0x11F1C, size: 0x8, addend: 0x0, symName: '-[MyScriptTask start]', symObjAddr: 0x418, symBinAddr: 0x15454, symSize: 0x38 } + - { offset: 0x11F4E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask stop]', symObjAddr: 0x450, symBinAddr: 0x1548C, symSize: 0x20 } + - { offset: 0x11F80, size: 0x8, addend: 0x0, symName: '-[MyScriptTask nextId]', symObjAddr: 0x470, symBinAddr: 0x154AC, symSize: 0xC0 } + - { offset: 0x11FB6, size: 0x8, addend: 0x0, symName: '-[MyScriptTask enqueue:]', symObjAddr: 0x530, symBinAddr: 0x1556C, symSize: 0x13C } + - { offset: 0x12008, size: 0x8, addend: 0x0, symName: '___24-[MyScriptTask enqueue:]_block_invoke', symObjAddr: 0x66C, symBinAddr: 0x156A8, symSize: 0x2CC } + - { offset: 0x12080, size: 0x8, addend: 0x0, symName: '-[MyScriptTask dequeue]', symObjAddr: 0x9DC, symBinAddr: 0x15974, symSize: 0x1AC } + - { offset: 0x120C9, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xB88, symBinAddr: 0x15B20, symSize: 0x58 } + - { offset: 0x120ED, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xBE0, symBinAddr: 0x15B78, symSize: 0x30 } + - { offset: 0x12109, size: 0x8, addend: 0x0, symName: '___23-[MyScriptTask dequeue]_block_invoke', symObjAddr: 0xC10, symBinAddr: 0x15BA8, symSize: 0x280 } + - { offset: 0x12179, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r, symObjAddr: 0xE90, symBinAddr: 0x15E28, symSize: 0x5C } + - { offset: 0x1219D, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r, symObjAddr: 0xEEC, symBinAddr: 0x15E84, symSize: 0x44 } + - { offset: 0x121B9, size: 0x8, addend: 0x0, symName: '-[MyScriptTask reset]', symObjAddr: 0xF30, symBinAddr: 0x15EC8, symSize: 0x44 } + - { offset: 0x121EB, size: 0x8, addend: 0x0, symName: '-[MyScriptTask isRun]', symObjAddr: 0xF74, symBinAddr: 0x15F0C, symSize: 0x24 } + - { offset: 0x12221, size: 0x8, addend: 0x0, symName: '-[MyScriptTask run]', symObjAddr: 0xF98, symBinAddr: 0x15F30, symSize: 0xE4 } + - { offset: 0x12261, size: 0x8, addend: 0x0, symName: '___19-[MyScriptTask run]_block_invoke', symObjAddr: 0x107C, symBinAddr: 0x16014, symSize: 0x13C } + - { offset: 0x1229E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask completeTask]', symObjAddr: 0x1224, symBinAddr: 0x16150, symSize: 0x54 } + - { offset: 0x122D0, size: 0x8, addend: 0x0, symName: '-[MyScriptTask adClosed:]', symObjAddr: 0x1278, symBinAddr: 0x161A4, symSize: 0x90 } + - { offset: 0x12310, size: 0x8, addend: 0x0, symName: '-[MyScriptTask loadIncrCount]', symObjAddr: 0x1308, symBinAddr: 0x16234, symSize: 0x28 } + - { offset: 0x12342, size: 0x8, addend: 0x0, symName: '-[MyScriptTask restart]', symObjAddr: 0x1330, symBinAddr: 0x1625C, symSize: 0xD4 } + - { offset: 0x12374, size: 0x8, addend: 0x0, symName: '___23-[MyScriptTask restart]_block_invoke', symObjAddr: 0x1404, symBinAddr: 0x16330, symSize: 0x10C } + - { offset: 0x123B1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask killApp:]', symObjAddr: 0x1510, symBinAddr: 0x1643C, symSize: 0x58 } + - { offset: 0x123F1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStartApp]', symObjAddr: 0x1568, symBinAddr: 0x16494, symSize: 0xD8 } + - { offset: 0x1243B, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke', symObjAddr: 0x1640, symBinAddr: 0x1656C, symSize: 0x644 } + - { offset: 0x1251F, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_2', symObjAddr: 0x1C84, symBinAddr: 0x16BB0, symSize: 0x38 } + - { offset: 0x12547, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_3', symObjAddr: 0x1CBC, symBinAddr: 0x16BE8, symSize: 0x15C } + - { offset: 0x125C8, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke_4', symObjAddr: 0x1E18, symBinAddr: 0x16D44, symSize: 0x1F8 } + - { offset: 0x1262B, size: 0x8, addend: 0x0, symName: '___27-[MyScriptTask runStartApp]_block_invoke.103', symObjAddr: 0x2010, symBinAddr: 0x16F3C, symSize: 0x50 } + - { offset: 0x12664, size: 0x8, addend: 0x0, symName: '-[MyScriptTask proc]', symObjAddr: 0x2060, symBinAddr: 0x16F8C, symSize: 0xB0 } + - { offset: 0x126AC, size: 0x8, addend: 0x0, symName: '-[MyScriptTask _proc]', symObjAddr: 0x2110, symBinAddr: 0x1703C, symSize: 0xA98 } + - { offset: 0x127A5, size: 0x8, addend: 0x0, symName: ___destructor_8_s0_s8_s16_s24_s32_s40_s48_s56_s64, symObjAddr: 0x2BA8, symBinAddr: 0x17AD4, symSize: 0xB4 } + - { offset: 0x127C5, size: 0x8, addend: 0x0, symName: ___destructor_8_s16_s24_s40, symObjAddr: 0x2C5C, symBinAddr: 0x17B88, symSize: 0x58 } + - { offset: 0x127E5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask replaceScript:scriptName:callback:]', symObjAddr: 0x2CB4, symBinAddr: 0x17BE0, symSize: 0x1A8 } + - { offset: 0x12868, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runAdShowScript:]', symObjAddr: 0x2E5C, symBinAddr: 0x17D88, symSize: 0x118 } + - { offset: 0x128E6, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStopScript:]', symObjAddr: 0x2F74, symBinAddr: 0x17EA0, symSize: 0x100 } + - { offset: 0x1294C, size: 0x8, addend: 0x0, symName: '___30-[MyScriptTask runStopScript:]_block_invoke', symObjAddr: 0x3074, symBinAddr: 0x17FA0, symSize: 0x78 } + - { offset: 0x12997, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runAdTouchScript:]', symObjAddr: 0x30EC, symBinAddr: 0x18018, symSize: 0x1DC } + - { offset: 0x12A01, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runStartScript:]', symObjAddr: 0x32C8, symBinAddr: 0x181F4, symSize: 0x128 } + - { offset: 0x12A67, size: 0x8, addend: 0x0, symName: '___31-[MyScriptTask runStartScript:]_block_invoke', symObjAddr: 0x33F0, symBinAddr: 0x1831C, symSize: 0x78 } + - { offset: 0x12AB2, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runSystemRestartScript]', symObjAddr: 0x3468, symBinAddr: 0x18394, symSize: 0x6C } + - { offset: 0x12AF4, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runScript:]', symObjAddr: 0x34D4, symBinAddr: 0x18400, symSize: 0x54 } + - { offset: 0x12B3A, size: 0x8, addend: 0x0, symName: '-[MyScriptTask stopScript:]', symObjAddr: 0x3528, symBinAddr: 0x18454, symSize: 0x54 } + - { offset: 0x12B80, size: 0x8, addend: 0x0, symName: '-[MyScriptTask readScript:]', symObjAddr: 0x357C, symBinAddr: 0x184A8, symSize: 0xB8 } + - { offset: 0x12BD5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask saveScript:name:]', symObjAddr: 0x3634, symBinAddr: 0x18560, symSize: 0xC8 } + - { offset: 0x12C39, size: 0x8, addend: 0x0, symName: '-[MyScriptTask getScriptPath:]', symObjAddr: 0x36FC, symBinAddr: 0x18628, symSize: 0x98 } + - { offset: 0x12C7F, size: 0x8, addend: 0x0, symName: '-[MyScriptTask getCurTime]', symObjAddr: 0x3794, symBinAddr: 0x186C0, symSize: 0x68 } + - { offset: 0x12CC5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask logServer:title:]', symObjAddr: 0x37FC, symBinAddr: 0x18728, symSize: 0x74 } + - { offset: 0x12D16, size: 0x8, addend: 0x0, symName: '-[MyScriptTask saveAdTaskLog:]', symObjAddr: 0x3870, symBinAddr: 0x1879C, symSize: 0xF0 } + - { offset: 0x12D58, size: 0x8, addend: 0x0, symName: '-[MyScriptTask statusStr]', symObjAddr: 0x3960, symBinAddr: 0x1888C, symSize: 0xB4 } + - { offset: 0x12D9E, size: 0x8, addend: 0x0, symName: '-[MyScriptTask appid]', symObjAddr: 0x3A14, symBinAddr: 0x18940, symSize: 0x1C } + - { offset: 0x12DD5, size: 0x8, addend: 0x0, symName: '-[MyScriptTask runTouchAdJs:]', symObjAddr: 0x3A30, symBinAddr: 0x1895C, symSize: 0x18 } + - { offset: 0x12EA7, size: 0x8, addend: 0x0, symName: '___30+[MyScriptTask sharedInstance]_block_invoke', symObjAddr: 0x3AD8, symBinAddr: 0x18A04, symSize: 0x50 } + - { offset: 0x12ED1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask currentId]', symObjAddr: 0x3B28, symBinAddr: 0x18A54, symSize: 0x1C } + - { offset: 0x12F07, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setCurrentId:]', symObjAddr: 0x3B44, symBinAddr: 0x18A70, symSize: 0x24 } + - { offset: 0x12F45, size: 0x8, addend: 0x0, symName: '-[MyScriptTask timer]', symObjAddr: 0x3B68, symBinAddr: 0x18A94, symSize: 0x1C } + - { offset: 0x12F7B, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setTimer:]', symObjAddr: 0x3B84, symBinAddr: 0x18AB0, symSize: 0x38 } + - { offset: 0x12FB9, size: 0x8, addend: 0x0, symName: '-[MyScriptTask inStack]', symObjAddr: 0x3BBC, symBinAddr: 0x18AE8, symSize: 0x1C } + - { offset: 0x12FEF, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setInStack:]', symObjAddr: 0x3BD8, symBinAddr: 0x18B04, symSize: 0x38 } + - { offset: 0x1302D, size: 0x8, addend: 0x0, symName: '-[MyScriptTask outStack]', symObjAddr: 0x3C10, symBinAddr: 0x18B3C, symSize: 0x1C } + - { offset: 0x13063, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setOutStack:]', symObjAddr: 0x3C2C, symBinAddr: 0x18B58, symSize: 0x38 } + - { offset: 0x130A1, size: 0x8, addend: 0x0, symName: '-[MyScriptTask concurrentQueue]', symObjAddr: 0x3C64, symBinAddr: 0x18B90, symSize: 0x1C } + - { offset: 0x130D7, size: 0x8, addend: 0x0, symName: '-[MyScriptTask setConcurrentQueue:]', symObjAddr: 0x3C80, symBinAddr: 0x18BAC, symSize: 0x38 } + - { offset: 0x13115, size: 0x8, addend: 0x0, symName: '-[MyScriptTask .cxx_destruct]', symObjAddr: 0x3CB8, symBinAddr: 0x18BE4, symSize: 0xAC } + - { offset: 0x14328, size: 0x8, addend: 0x0, symName: _startSimpleServer, symObjAddr: 0x0, symBinAddr: 0x18C90, symSize: 0x70 } + - { offset: 0x14335, size: 0x8, addend: 0x0, symName: _startSimpleServer, symObjAddr: 0x0, symBinAddr: 0x18C90, symSize: 0x70 } + - { offset: 0x14356, size: 0x8, addend: 0x0, symName: _startSimpleServer.onceToken, symObjAddr: 0x1220, symBinAddr: 0x69690, symSize: 0x0 } + - { offset: 0x144A1, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke, symObjAddr: 0x70, symBinAddr: 0x18D00, symSize: 0xB0 } + - { offset: 0x144F9, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke_2, symObjAddr: 0x120, symBinAddr: 0x18DB0, symSize: 0x8C } + - { offset: 0x14521, size: 0x8, addend: 0x0, symName: ___startSimpleServer_block_invoke_3, symObjAddr: 0x1AC, symBinAddr: 0x18E3C, symSize: 0x120 } + - { offset: 0x14737, size: 0x8, addend: 0x0, symName: '+[UDPHandler sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x18F5C, symSize: 0x90 } + - { offset: 0x14744, size: 0x8, addend: 0x0, symName: '+[UDPHandler sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x18F5C, symSize: 0x90 } + - { offset: 0x1476D, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x1EE0, symBinAddr: 0x69698, symSize: 0x0 } + - { offset: 0x14782, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x1EE8, symBinAddr: 0x696A0, symSize: 0x0 } + - { offset: 0x148CF, size: 0x8, addend: 0x0, symName: '___28+[UDPHandler sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x18FEC, symSize: 0x50 } + - { offset: 0x148F7, size: 0x8, addend: 0x0, symName: '-[UDPHandler init]', symObjAddr: 0xE0, symBinAddr: 0x1903C, symSize: 0xB4 } + - { offset: 0x1494A, size: 0x8, addend: 0x0, symName: '-[UDPHandler handle:]', symObjAddr: 0x194, symBinAddr: 0x190F0, symSize: 0x580 } + - { offset: 0x14A52, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke', symObjAddr: 0x714, symBinAddr: 0x19670, symSize: 0x2C } + - { offset: 0x14A7A, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke_2', symObjAddr: 0x740, symBinAddr: 0x1969C, symSize: 0x60 } + - { offset: 0x14ABE, size: 0x8, addend: 0x0, symName: '___21-[UDPHandler handle:]_block_invoke_3', symObjAddr: 0x7A0, symBinAddr: 0x196FC, symSize: 0x60 } + - { offset: 0x14D40, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:]', symObjAddr: 0x0, symBinAddr: 0x1975C, symSize: 0xC0 } + - { offset: 0x14D59, size: 0x8, addend: 0x0, symName: _CSToastPositionTop, symObjAddr: 0x4A70, symBinAddr: 0x694B8, symSize: 0x0 } + - { offset: 0x14DCC, size: 0x8, addend: 0x0, symName: _CSToastPositionCenter, symObjAddr: 0x4A78, symBinAddr: 0x694C0, symSize: 0x0 } + - { offset: 0x14DE1, size: 0x8, addend: 0x0, symName: _CSToastPositionBottom, symObjAddr: 0x4A80, symBinAddr: 0x694C8, symSize: 0x0 } + - { offset: 0x14DF6, size: 0x8, addend: 0x0, symName: _CSToastTimerKey, symObjAddr: 0x4A88, symBinAddr: 0x694D0, symSize: 0x0 } + - { offset: 0x14E15, size: 0x8, addend: 0x0, symName: _CSToastDurationKey, symObjAddr: 0x4A90, symBinAddr: 0x694D8, symSize: 0x0 } + - { offset: 0x14E2A, size: 0x8, addend: 0x0, symName: _CSToastPositionKey, symObjAddr: 0x4A98, symBinAddr: 0x694E0, symSize: 0x0 } + - { offset: 0x14E3F, size: 0x8, addend: 0x0, symName: _CSToastCompletionKey, symObjAddr: 0x4AA0, symBinAddr: 0x694E8, symSize: 0x0 } + - { offset: 0x14E54, size: 0x8, addend: 0x0, symName: _CSToastActiveKey, symObjAddr: 0x4AA8, symBinAddr: 0x694F0, symSize: 0x0 } + - { offset: 0x14E69, size: 0x8, addend: 0x0, symName: _CSToastActivityViewKey, symObjAddr: 0x4AB0, symBinAddr: 0x694F8, symSize: 0x0 } + - { offset: 0x14E7E, size: 0x8, addend: 0x0, symName: _CSToastQueueKey, symObjAddr: 0x4AB8, symBinAddr: 0x69500, symSize: 0x0 } + - { offset: 0x14E87, size: 0x8, addend: 0x0, symName: '+[CSToastManager sharedManager]', symObjAddr: 0x3FB0, symBinAddr: 0x1D5FC, symSize: 0xDC } + - { offset: 0x14EB2, size: 0x8, addend: 0x0, symName: _sharedManager._sharedManager, symObjAddr: 0x132A0, symBinAddr: 0x696A8, symSize: 0x0 } + - { offset: 0x14EC8, size: 0x8, addend: 0x0, symName: _sharedManager.oncePredicate, symObjAddr: 0x132A8, symBinAddr: 0x696B0, symSize: 0x0 } + - { offset: 0x1633C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:]', symObjAddr: 0x0, symBinAddr: 0x1975C, symSize: 0xC0 } + - { offset: 0x1637C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:]', symObjAddr: 0xC0, symBinAddr: 0x1981C, symSize: 0x9C } + - { offset: 0x163D8, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:style:]', symObjAddr: 0x15C, symBinAddr: 0x198B8, symSize: 0xFC } + - { offset: 0x16450, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToast:duration:position:title:image:style:completion:]', symObjAddr: 0x258, symBinAddr: 0x199B4, symSize: 0x168 } + - { offset: 0x164F4, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) showToast:]', symObjAddr: 0x3C0, symBinAddr: 0x19B1C, symSize: 0xC0 } + - { offset: 0x16534, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) showToast:duration:position:completion:]', symObjAddr: 0x480, symBinAddr: 0x19BDC, symSize: 0x258 } + - { offset: 0x1659E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToast]', symObjAddr: 0x6D8, symBinAddr: 0x19E34, symSize: 0x88 } + - { offset: 0x165D0, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToast:]', symObjAddr: 0x760, symBinAddr: 0x19EBC, symSize: 0x10C } + - { offset: 0x16610, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideAllToasts]', symObjAddr: 0x86C, symBinAddr: 0x19FC8, symSize: 0x40 } + - { offset: 0x16642, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideAllToasts:clearQueue:]', symObjAddr: 0x8AC, symBinAddr: 0x1A008, symSize: 0x1C4 } + - { offset: 0x166A9, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) clearToastQueue]', symObjAddr: 0xA70, symBinAddr: 0x1A1CC, symSize: 0x54 } + - { offset: 0x166DB, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_showToast:duration:position:]', symObjAddr: 0xAC4, symBinAddr: 0x1A220, symSize: 0x334 } + - { offset: 0x1674C, size: 0x8, addend: 0x0, symName: '___48-[UIView(Toast) cs_showToast:duration:position:]_block_invoke', symObjAddr: 0xDF8, symBinAddr: 0x1A554, symSize: 0x38 } + - { offset: 0x16785, size: 0x8, addend: 0x0, symName: '___48-[UIView(Toast) cs_showToast:duration:position:]_block_invoke.32', symObjAddr: 0xE9C, symBinAddr: 0x1A58C, symSize: 0xE4 } + - { offset: 0x1680E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_hideToast:]', symObjAddr: 0x1024, symBinAddr: 0x1A670, symSize: 0x68 } + - { offset: 0x1684E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_hideToast:fromTap:]', symObjAddr: 0x108C, symBinAddr: 0x1A6D8, symSize: 0x23C } + - { offset: 0x168AA, size: 0x8, addend: 0x0, symName: '___38-[UIView(Toast) cs_hideToast:fromTap:]_block_invoke', symObjAddr: 0x12C8, symBinAddr: 0x1A914, symSize: 0x38 } + - { offset: 0x168E3, size: 0x8, addend: 0x0, symName: '___38-[UIView(Toast) cs_hideToast:fromTap:]_block_invoke_2', symObjAddr: 0x1300, symBinAddr: 0x1A94C, symSize: 0x244 } + - { offset: 0x1699C, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) toastViewForMessage:title:image:style:]', symObjAddr: 0x1544, symBinAddr: 0x1AB90, symSize: 0xF5C } + - { offset: 0x16C82, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x24A0, symBinAddr: 0x1BAEC, symSize: 0x4C } + - { offset: 0x16CE8, size: 0x8, addend: 0x0, symName: _CGSizeMake, symObjAddr: 0x24EC, symBinAddr: 0x1BB38, symSize: 0x2C } + - { offset: 0x16D30, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_activeToasts]', symObjAddr: 0x2518, symBinAddr: 0x1BB64, symSize: 0xCC } + - { offset: 0x16D76, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_toastQueue]', symObjAddr: 0x25E4, symBinAddr: 0x1BC30, symSize: 0xCC } + - { offset: 0x16DBC, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_toastTimerDidFinish:]', symObjAddr: 0x26B0, symBinAddr: 0x1BCFC, symSize: 0x90 } + - { offset: 0x16DFE, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_handleToastTapped:]', symObjAddr: 0x2740, symBinAddr: 0x1BD8C, symSize: 0xD0 } + - { offset: 0x16E5E, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) makeToastActivity:]', symObjAddr: 0x2810, symBinAddr: 0x1BE5C, symSize: 0x570 } + - { offset: 0x16EDE, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x2D80, symBinAddr: 0x1C3CC, symSize: 0x2C } + - { offset: 0x16F26, size: 0x8, addend: 0x0, symName: '___35-[UIView(Toast) makeToastActivity:]_block_invoke', symObjAddr: 0x2DAC, symBinAddr: 0x1C3F8, symSize: 0x38 } + - { offset: 0x16F62, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) hideToastActivity]', symObjAddr: 0x2DE4, symBinAddr: 0x1C430, symSize: 0x1EC } + - { offset: 0x16FA4, size: 0x8, addend: 0x0, symName: '___34-[UIView(Toast) hideToastActivity]_block_invoke', symObjAddr: 0x2FD0, symBinAddr: 0x1C61C, symSize: 0x38 } + - { offset: 0x16FE0, size: 0x8, addend: 0x0, symName: '___34-[UIView(Toast) hideToastActivity]_block_invoke_2', symObjAddr: 0x3008, symBinAddr: 0x1C654, symSize: 0x5C } + - { offset: 0x17041, size: 0x8, addend: 0x0, symName: '-[UIView(Toast) cs_centerPointForPosition:withToast:]', symObjAddr: 0x3064, symBinAddr: 0x1C6B0, symSize: 0x3A8 } + - { offset: 0x170D6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle initWithDefaultStyle]', symObjAddr: 0x340C, symBinAddr: 0x1CA58, symSize: 0x39C } + - { offset: 0x1710D, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMaxWidthPercentage:]', symObjAddr: 0x37A8, symBinAddr: 0x1CDF4, symSize: 0xAC } + - { offset: 0x171AB, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMaxHeightPercentage:]', symObjAddr: 0x3854, symBinAddr: 0x1CEA0, symSize: 0xAC } + - { offset: 0x17249, size: 0x8, addend: 0x0, symName: '-[CSToastStyle init]', symObjAddr: 0x3900, symBinAddr: 0x1CF4C, symSize: 0x3C } + - { offset: 0x17280, size: 0x8, addend: 0x0, symName: '-[CSToastStyle backgroundColor]', symObjAddr: 0x393C, symBinAddr: 0x1CF88, symSize: 0x1C } + - { offset: 0x172B6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setBackgroundColor:]', symObjAddr: 0x3958, symBinAddr: 0x1CFA4, symSize: 0x38 } + - { offset: 0x172F4, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleColor]', symObjAddr: 0x3990, symBinAddr: 0x1CFDC, symSize: 0x1C } + - { offset: 0x1732A, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleColor:]', symObjAddr: 0x39AC, symBinAddr: 0x1CFF8, symSize: 0x38 } + - { offset: 0x17368, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageColor]', symObjAddr: 0x39E4, symBinAddr: 0x1D030, symSize: 0x1C } + - { offset: 0x1739E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageColor:]', symObjAddr: 0x3A00, symBinAddr: 0x1D04C, symSize: 0x38 } + - { offset: 0x173DC, size: 0x8, addend: 0x0, symName: '-[CSToastStyle maxWidthPercentage]', symObjAddr: 0x3A38, symBinAddr: 0x1D084, symSize: 0x1C } + - { offset: 0x17412, size: 0x8, addend: 0x0, symName: '-[CSToastStyle maxHeightPercentage]', symObjAddr: 0x3A54, symBinAddr: 0x1D0A0, symSize: 0x1C } + - { offset: 0x17448, size: 0x8, addend: 0x0, symName: '-[CSToastStyle horizontalPadding]', symObjAddr: 0x3A70, symBinAddr: 0x1D0BC, symSize: 0x1C } + - { offset: 0x1747E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setHorizontalPadding:]', symObjAddr: 0x3A8C, symBinAddr: 0x1D0D8, symSize: 0x24 } + - { offset: 0x174BC, size: 0x8, addend: 0x0, symName: '-[CSToastStyle verticalPadding]', symObjAddr: 0x3AB0, symBinAddr: 0x1D0FC, symSize: 0x1C } + - { offset: 0x174F3, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setVerticalPadding:]', symObjAddr: 0x3ACC, symBinAddr: 0x1D118, symSize: 0x24 } + - { offset: 0x17532, size: 0x8, addend: 0x0, symName: '-[CSToastStyle cornerRadius]', symObjAddr: 0x3AF0, symBinAddr: 0x1D13C, symSize: 0x1C } + - { offset: 0x17569, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setCornerRadius:]', symObjAddr: 0x3B0C, symBinAddr: 0x1D158, symSize: 0x24 } + - { offset: 0x175A8, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleFont]', symObjAddr: 0x3B30, symBinAddr: 0x1D17C, symSize: 0x1C } + - { offset: 0x175DF, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleFont:]', symObjAddr: 0x3B4C, symBinAddr: 0x1D198, symSize: 0x38 } + - { offset: 0x1761E, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageFont]', symObjAddr: 0x3B84, symBinAddr: 0x1D1D0, symSize: 0x1C } + - { offset: 0x17655, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageFont:]', symObjAddr: 0x3BA0, symBinAddr: 0x1D1EC, symSize: 0x38 } + - { offset: 0x17694, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleAlignment]', symObjAddr: 0x3BD8, symBinAddr: 0x1D224, symSize: 0x1C } + - { offset: 0x176CB, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleAlignment:]', symObjAddr: 0x3BF4, symBinAddr: 0x1D240, symSize: 0x24 } + - { offset: 0x1770A, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageAlignment]', symObjAddr: 0x3C18, symBinAddr: 0x1D264, symSize: 0x1C } + - { offset: 0x17741, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageAlignment:]', symObjAddr: 0x3C34, symBinAddr: 0x1D280, symSize: 0x24 } + - { offset: 0x17780, size: 0x8, addend: 0x0, symName: '-[CSToastStyle titleNumberOfLines]', symObjAddr: 0x3C58, symBinAddr: 0x1D2A4, symSize: 0x1C } + - { offset: 0x177B7, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setTitleNumberOfLines:]', symObjAddr: 0x3C74, symBinAddr: 0x1D2C0, symSize: 0x24 } + - { offset: 0x177F6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle messageNumberOfLines]', symObjAddr: 0x3C98, symBinAddr: 0x1D2E4, symSize: 0x1C } + - { offset: 0x1782D, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setMessageNumberOfLines:]', symObjAddr: 0x3CB4, symBinAddr: 0x1D300, symSize: 0x24 } + - { offset: 0x1786C, size: 0x8, addend: 0x0, symName: '-[CSToastStyle displayShadow]', symObjAddr: 0x3CD8, symBinAddr: 0x1D324, symSize: 0x20 } + - { offset: 0x178A3, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setDisplayShadow:]', symObjAddr: 0x3CF8, symBinAddr: 0x1D344, symSize: 0x28 } + - { offset: 0x178E2, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowColor]', symObjAddr: 0x3D20, symBinAddr: 0x1D36C, symSize: 0x1C } + - { offset: 0x17919, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowColor:]', symObjAddr: 0x3D3C, symBinAddr: 0x1D388, symSize: 0x38 } + - { offset: 0x17958, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowOpacity]', symObjAddr: 0x3D74, symBinAddr: 0x1D3C0, symSize: 0x1C } + - { offset: 0x1798F, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowOpacity:]', symObjAddr: 0x3D90, symBinAddr: 0x1D3DC, symSize: 0x24 } + - { offset: 0x179CE, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowRadius]', symObjAddr: 0x3DB4, symBinAddr: 0x1D400, symSize: 0x1C } + - { offset: 0x17A05, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowRadius:]', symObjAddr: 0x3DD0, symBinAddr: 0x1D41C, symSize: 0x24 } + - { offset: 0x17A44, size: 0x8, addend: 0x0, symName: '-[CSToastStyle shadowOffset]', symObjAddr: 0x3DF4, symBinAddr: 0x1D440, symSize: 0x28 } + - { offset: 0x17A7B, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setShadowOffset:]', symObjAddr: 0x3E1C, symBinAddr: 0x1D468, symSize: 0x28 } + - { offset: 0x17ABA, size: 0x8, addend: 0x0, symName: '-[CSToastStyle imageSize]', symObjAddr: 0x3E44, symBinAddr: 0x1D490, symSize: 0x28 } + - { offset: 0x17AF1, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setImageSize:]', symObjAddr: 0x3E6C, symBinAddr: 0x1D4B8, symSize: 0x28 } + - { offset: 0x17B30, size: 0x8, addend: 0x0, symName: '-[CSToastStyle activitySize]', symObjAddr: 0x3E94, symBinAddr: 0x1D4E0, symSize: 0x28 } + - { offset: 0x17B67, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setActivitySize:]', symObjAddr: 0x3EBC, symBinAddr: 0x1D508, symSize: 0x28 } + - { offset: 0x17BA6, size: 0x8, addend: 0x0, symName: '-[CSToastStyle fadeDuration]', symObjAddr: 0x3EE4, symBinAddr: 0x1D530, symSize: 0x1C } + - { offset: 0x17BDD, size: 0x8, addend: 0x0, symName: '-[CSToastStyle setFadeDuration:]', symObjAddr: 0x3F00, symBinAddr: 0x1D54C, symSize: 0x24 } + - { offset: 0x17C1C, size: 0x8, addend: 0x0, symName: '-[CSToastStyle .cxx_destruct]', symObjAddr: 0x3F24, symBinAddr: 0x1D570, symSize: 0x8C } + - { offset: 0x17CE6, size: 0x8, addend: 0x0, symName: '___31+[CSToastManager sharedManager]_block_invoke', symObjAddr: 0x408C, symBinAddr: 0x1D6D8, symSize: 0x50 } + - { offset: 0x17D26, size: 0x8, addend: 0x0, symName: '-[CSToastManager init]', symObjAddr: 0x40DC, symBinAddr: 0x1D728, symSize: 0x12C } + - { offset: 0x17D5D, size: 0x8, addend: 0x0, symName: '+[CSToastManager setSharedStyle:]', symObjAddr: 0x4208, symBinAddr: 0x1D854, symSize: 0x84 } + - { offset: 0x17D9F, size: 0x8, addend: 0x0, symName: '+[CSToastManager sharedStyle]', symObjAddr: 0x428C, symBinAddr: 0x1D8D8, symSize: 0x78 } + - { offset: 0x17DD6, size: 0x8, addend: 0x0, symName: '+[CSToastManager setTapToDismissEnabled:]', symObjAddr: 0x4304, symBinAddr: 0x1D950, symSize: 0x60 } + - { offset: 0x17E18, size: 0x8, addend: 0x0, symName: '+[CSToastManager isTapToDismissEnabled]', symObjAddr: 0x4364, symBinAddr: 0x1D9B0, symSize: 0x60 } + - { offset: 0x17E4F, size: 0x8, addend: 0x0, symName: '+[CSToastManager setQueueEnabled:]', symObjAddr: 0x43C4, symBinAddr: 0x1DA10, symSize: 0x60 } + - { offset: 0x17E91, size: 0x8, addend: 0x0, symName: '+[CSToastManager isQueueEnabled]', symObjAddr: 0x4424, symBinAddr: 0x1DA70, symSize: 0x60 } + - { offset: 0x17EC8, size: 0x8, addend: 0x0, symName: '+[CSToastManager setDefaultDuration:]', symObjAddr: 0x4484, symBinAddr: 0x1DAD0, symSize: 0x5C } + - { offset: 0x17F0A, size: 0x8, addend: 0x0, symName: '+[CSToastManager defaultDuration]', symObjAddr: 0x44E0, symBinAddr: 0x1DB2C, symSize: 0x5C } + - { offset: 0x17F41, size: 0x8, addend: 0x0, symName: '+[CSToastManager setDefaultPosition:]', symObjAddr: 0x453C, symBinAddr: 0x1DB88, symSize: 0xCC } + - { offset: 0x17F83, size: 0x8, addend: 0x0, symName: '+[CSToastManager defaultPosition]', symObjAddr: 0x4608, symBinAddr: 0x1DC54, symSize: 0x78 } + - { offset: 0x17FBA, size: 0x8, addend: 0x0, symName: '-[CSToastManager sharedStyle]', symObjAddr: 0x4680, symBinAddr: 0x1DCCC, symSize: 0x1C } + - { offset: 0x17FF1, size: 0x8, addend: 0x0, symName: '-[CSToastManager setSharedStyle:]', symObjAddr: 0x469C, symBinAddr: 0x1DCE8, symSize: 0x38 } + - { offset: 0x18030, size: 0x8, addend: 0x0, symName: '-[CSToastManager isTapToDismissEnabled]', symObjAddr: 0x46D4, symBinAddr: 0x1DD20, symSize: 0x20 } + - { offset: 0x18067, size: 0x8, addend: 0x0, symName: '-[CSToastManager setTapToDismissEnabled:]', symObjAddr: 0x46F4, symBinAddr: 0x1DD40, symSize: 0x28 } + - { offset: 0x180A6, size: 0x8, addend: 0x0, symName: '-[CSToastManager isQueueEnabled]', symObjAddr: 0x471C, symBinAddr: 0x1DD68, symSize: 0x20 } + - { offset: 0x180DD, size: 0x8, addend: 0x0, symName: '-[CSToastManager setQueueEnabled:]', symObjAddr: 0x473C, symBinAddr: 0x1DD88, symSize: 0x28 } + - { offset: 0x1811C, size: 0x8, addend: 0x0, symName: '-[CSToastManager defaultDuration]', symObjAddr: 0x4764, symBinAddr: 0x1DDB0, symSize: 0x1C } + - { offset: 0x18153, size: 0x8, addend: 0x0, symName: '-[CSToastManager setDefaultDuration:]', symObjAddr: 0x4780, symBinAddr: 0x1DDCC, symSize: 0x24 } + - { offset: 0x18192, size: 0x8, addend: 0x0, symName: '-[CSToastManager defaultPosition]', symObjAddr: 0x47A4, symBinAddr: 0x1DDF0, symSize: 0x1C } + - { offset: 0x181C9, size: 0x8, addend: 0x0, symName: '-[CSToastManager setDefaultPosition:]', symObjAddr: 0x47C0, symBinAddr: 0x1DE0C, symSize: 0x38 } + - { offset: 0x18208, size: 0x8, addend: 0x0, symName: '-[CSToastManager .cxx_destruct]', symObjAddr: 0x47F8, symBinAddr: 0x1DE44, symSize: 0x4C } + - { offset: 0x1952A, size: 0x8, addend: 0x0, symName: _XSGetFrontMostApplication, symObjAddr: 0x0, symBinAddr: 0x1DE90, symSize: 0x22C } + - { offset: 0x19571, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions, symObjAddr: 0x54D4, symBinAddr: 0x232C4, symSize: 0x164 } + - { offset: 0x19594, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.security, symObjAddr: 0x1D2D8, symBinAddr: 0x696B8, symSize: 0x0 } + - { offset: 0x195AA, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.SetEntitlements, symObjAddr: 0x1D2E0, symBinAddr: 0x696C0, symSize: 0x0 } + - { offset: 0x195C0, size: 0x8, addend: 0x0, symName: _injectNetworkPermissions.onceToken, symObjAddr: 0x1D2E8, symBinAddr: 0x696C8, symSize: 0x0 } + - { offset: 0x196BE, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions, symObjAddr: 0x56A4, symBinAddr: 0x23494, symSize: 0x474 } + - { offset: 0x196E5, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.security, symObjAddr: 0x1D2F0, symBinAddr: 0x696D0, symSize: 0x0 } + - { offset: 0x196FB, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.SetEntitlements, symObjAddr: 0x1D2F8, symBinAddr: 0x696D8, symSize: 0x0 } + - { offset: 0x19711, size: 0x8, addend: 0x0, symName: _injectEntitlementsWithOptions.onceToken, symObjAddr: 0x1D300, symBinAddr: 0x696E0, symSize: 0x0 } + - { offset: 0x197AE, size: 0x8, addend: 0x0, symName: __XSOpenApp, symBinAddr: 0x69768, symSize: 0x0 } + - { offset: 0x1A48F, size: 0x8, addend: 0x0, symName: _XSGetFrontMostApplication, symObjAddr: 0x0, symBinAddr: 0x1DE90, symSize: 0x22C } + - { offset: 0x1A4FD, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x22C, symBinAddr: 0x1E0BC, symSize: 0x58 } + - { offset: 0x1A521, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x284, symBinAddr: 0x1E114, symSize: 0x30 } + - { offset: 0x1A53D, size: 0x8, addend: 0x0, symName: ___XSGetFrontMostApplication_block_invoke, symObjAddr: 0x2B4, symBinAddr: 0x1E144, symSize: 0x1BC } + - { offset: 0x1A5B5, size: 0x8, addend: 0x0, symName: _XSFrontMostAppId, symObjAddr: 0x510, symBinAddr: 0x1E300, symSize: 0x13C } + - { offset: 0x1A5DD, size: 0x8, addend: 0x0, symName: _XSRuncmd, symObjAddr: 0x64C, symBinAddr: 0x1E43C, symSize: 0x120 } + - { offset: 0x1A659, size: 0x8, addend: 0x0, symName: _unlink_cb, symObjAddr: 0x76C, symBinAddr: 0x1E55C, symSize: 0x54 } + - { offset: 0x1A6B9, size: 0x8, addend: 0x0, symName: _XSSystem, symObjAddr: 0x7C0, symBinAddr: 0x1E5B0, symSize: 0x5C } + - { offset: 0x1A745, size: 0x8, addend: 0x0, symName: _XSGetAppExecutable, symObjAddr: 0x81C, symBinAddr: 0x1E60C, symSize: 0x4D4 } + - { offset: 0x1A866, size: 0x8, addend: 0x0, symName: _XSReboot, symObjAddr: 0xCF0, symBinAddr: 0x1EAE0, symSize: 0x74 } + - { offset: 0x1A89C, size: 0x8, addend: 0x0, symName: _XSKillApp, symObjAddr: 0xD64, symBinAddr: 0x1EB54, symSize: 0x104 } + - { offset: 0x1A90A, size: 0x8, addend: 0x0, symName: _kill2, symObjAddr: 0xE68, symBinAddr: 0x1EC58, symSize: 0xD8 } + - { offset: 0x1A96A, size: 0x8, addend: 0x0, symName: _system2, symObjAddr: 0xF40, symBinAddr: 0x1ED30, symSize: 0x24C } + - { offset: 0x1A9FC, size: 0x8, addend: 0x0, symName: _XSKillAppByName, symObjAddr: 0x118C, symBinAddr: 0x1EF7C, symSize: 0x80 } + - { offset: 0x1AA32, size: 0x8, addend: 0x0, symName: _XSBringAppForeground, symObjAddr: 0x120C, symBinAddr: 0x1EFFC, symSize: 0xE4 } + - { offset: 0x1AA76, size: 0x8, addend: 0x0, symName: _bringAppToForeground, symObjAddr: 0x12F0, symBinAddr: 0x1F0E0, symSize: 0x198 } + - { offset: 0x1AAD9, size: 0x8, addend: 0x0, symName: ___bringAppToForeground_block_invoke, symObjAddr: 0x1488, symBinAddr: 0x1F278, symSize: 0x6C } + - { offset: 0x1AB0F, size: 0x8, addend: 0x0, symName: _activateApp, symObjAddr: 0x14F4, symBinAddr: 0x1F2E4, symSize: 0xD0 } + - { offset: 0x1AB63, size: 0x8, addend: 0x0, symName: _XSRemoteUnlock, symObjAddr: 0x15C4, symBinAddr: 0x1F3B4, symSize: 0x4A4 } + - { offset: 0x1AC15, size: 0x8, addend: 0x0, symName: _CGPointMake, symObjAddr: 0x1A68, symBinAddr: 0x1F858, symSize: 0x2C } + - { offset: 0x1AC5D, size: 0x8, addend: 0x0, symName: _getDeviceName, symObjAddr: 0x1A94, symBinAddr: 0x1F884, symSize: 0x84 } + - { offset: 0x1AC87, size: 0x8, addend: 0x0, symName: _roundUp, symObjAddr: 0x1B18, symBinAddr: 0x1F908, symSize: 0x7C } + - { offset: 0x1ACCF, size: 0x8, addend: 0x0, symName: _createScreenShotCGImageRef, symObjAddr: 0x1B94, symBinAddr: 0x1F984, symSize: 0x624 } + - { offset: 0x1AECF, size: 0x8, addend: 0x0, symName: _CGRectMake, symObjAddr: 0x21B8, symBinAddr: 0x1FFA8, symSize: 0x4C } + - { offset: 0x1AF35, size: 0x8, addend: 0x0, symName: _XSCcaptureScreen2, symObjAddr: 0x2204, symBinAddr: 0x1FFF4, symSize: 0xA4 } + - { offset: 0x1AF6E, size: 0x8, addend: 0x0, symName: _XSCaptureScreen, symObjAddr: 0x22A8, symBinAddr: 0x20098, symSize: 0x174 } + - { offset: 0x1AF98, size: 0x8, addend: 0x0, symName: _defaultIconWithSize, symObjAddr: 0x241C, symBinAddr: 0x2020C, symSize: 0x36C } + - { offset: 0x1B063, size: 0x8, addend: 0x0, symName: _XSGetApps, symObjAddr: 0x2788, symBinAddr: 0x20578, symSize: 0xB04 } + - { offset: 0x1B26D, size: 0x8, addend: 0x0, symName: _CGSizeMake, symObjAddr: 0x328C, symBinAddr: 0x2107C, symSize: 0x2C } + - { offset: 0x1B2B5, size: 0x8, addend: 0x0, symName: _XSCleanSafariHistory, symObjAddr: 0x32B8, symBinAddr: 0x210A8, symSize: 0xE4 } + - { offset: 0x1B316, size: 0x8, addend: 0x0, symName: _XSCleanSafari, symObjAddr: 0x339C, symBinAddr: 0x2118C, symSize: 0x4D8 } + - { offset: 0x1B44F, size: 0x8, addend: 0x0, symName: _XSCleanKeychain, symObjAddr: 0x3874, symBinAddr: 0x21664, symSize: 0x15C } + - { offset: 0x1B4A1, size: 0x8, addend: 0x0, symName: _XSCleanPastboard, symObjAddr: 0x39D0, symBinAddr: 0x217C0, symSize: 0x34C } + - { offset: 0x1B54D, size: 0x8, addend: 0x0, symName: _getAppExecutable, symObjAddr: 0x3D1C, symBinAddr: 0x21B0C, symSize: 0x530 } + - { offset: 0x1B693, size: 0x8, addend: 0x0, symName: _getAppSandboxPath, symObjAddr: 0x424C, symBinAddr: 0x2203C, symSize: 0x3A4 } + - { offset: 0x1B754, size: 0x8, addend: 0x0, symName: _XSGetAppInfoPath, symObjAddr: 0x45F0, symBinAddr: 0x223E0, symSize: 0x1EC } + - { offset: 0x1B7C8, size: 0x8, addend: 0x0, symName: _XSGetAppInfo, symObjAddr: 0x47DC, symBinAddr: 0x225CC, symSize: 0xBC } + - { offset: 0x1B80F, size: 0x8, addend: 0x0, symName: _XSSaveAppInfo, symObjAddr: 0x4898, symBinAddr: 0x22688, symSize: 0x400 } + - { offset: 0x1B90D, size: 0x8, addend: 0x0, symName: _cleanBundleContainer, symObjAddr: 0x4C98, symBinAddr: 0x22A88, symSize: 0x35C } + - { offset: 0x1B9B2, size: 0x8, addend: 0x0, symName: _clearAppStringInfo, symObjAddr: 0x4FF4, symBinAddr: 0x22DE4, symSize: 0x258 } + - { offset: 0x1BA29, size: 0x8, addend: 0x0, symName: _XSClearAppData, symObjAddr: 0x524C, symBinAddr: 0x2303C, symSize: 0x7C } + - { offset: 0x1BA5E, size: 0x8, addend: 0x0, symName: _screenIsLocked, symObjAddr: 0x52C8, symBinAddr: 0x230B8, symSize: 0xCC } + - { offset: 0x1BAB4, size: 0x8, addend: 0x0, symName: _XSClearAll, symObjAddr: 0x5394, symBinAddr: 0x23184, symSize: 0x58 } + - { offset: 0x1BADA, size: 0x8, addend: 0x0, symName: _getCPUTemperature, symObjAddr: 0x53EC, symBinAddr: 0x231DC, symSize: 0xE8 } + - { offset: 0x1BC09, size: 0x8, addend: 0x0, symName: ___injectNetworkPermissions_block_invoke, symObjAddr: 0x5638, symBinAddr: 0x23428, symSize: 0x6C } + - { offset: 0x1BC33, size: 0x8, addend: 0x0, symName: ___injectEntitlementsWithOptions_block_invoke, symObjAddr: 0x5B18, symBinAddr: 0x23908, symSize: 0x6C } + - { offset: 0x1BC5D, size: 0x8, addend: 0x0, symName: _verifyEntitlement, symObjAddr: 0x5B84, symBinAddr: 0x23974, symSize: 0x110 } + - { offset: 0x1BCC3, size: 0x8, addend: 0x0, symName: _printInfo, symObjAddr: 0x5C94, symBinAddr: 0x23A84, symSize: 0x4AC } + - { offset: 0x1BF10, size: 0x8, addend: 0x0, symName: _printClassHierarchy, symObjAddr: 0x6140, symBinAddr: 0x23F30, symSize: 0x84 } + - { offset: 0x1BF36, size: 0x8, addend: 0x0, symName: _printMethodInfo, symObjAddr: 0x61C4, symBinAddr: 0x23FB4, symSize: 0x220 } + - { offset: 0x1BFF1, size: 0x8, addend: 0x0, symName: _printPropertyInfo, symObjAddr: 0x63E4, symBinAddr: 0x241D4, symSize: 0x244 } + - { offset: 0x1C0A4, size: 0x8, addend: 0x0, symName: _parsePropertyAttributes, symObjAddr: 0x6628, symBinAddr: 0x24418, symSize: 0x4B4 } + - { offset: 0x1C11D, size: 0x8, addend: 0x0, symName: _getFrontAppWindows, symObjAddr: 0x6ADC, symBinAddr: 0x248CC, symSize: 0x178 } + - { offset: 0x1C194, size: 0x8, addend: 0x0, symName: _findButtonsInView, symObjAddr: 0x6C54, symBinAddr: 0x24A44, symSize: 0x2D8 } + - { offset: 0x1C207, size: 0x8, addend: 0x0, symName: _getKeyWindow, symObjAddr: 0x6F2C, symBinAddr: 0x24D1C, symSize: 0x41C } + - { offset: 0x1C292, size: 0x8, addend: 0x0, symName: _getAllButtons, symObjAddr: 0x7348, symBinAddr: 0x25138, symSize: 0x58 } + - { offset: 0x1C2BE, size: 0x8, addend: 0x0, symName: ___getAllButtons_block_invoke, symObjAddr: 0x73A0, symBinAddr: 0x25190, symSize: 0x54 } + - { offset: 0x1FFFF, size: 0x8, addend: 0x0, symName: _XSErrorFromException, symObjAddr: 0x0, symBinAddr: 0x251E4, symSize: 0x1BC } + - { offset: 0x2000C, size: 0x8, addend: 0x0, symName: _XSCalculateElapsedTime, symObjAddr: 0x1BC, symBinAddr: 0x253A0, symSize: 0x94 } + - { offset: 0x20031, size: 0x8, addend: 0x0, symName: _XSCalculateElapsedTime.timebaseInfo, symObjAddr: 0xC09C, symBinAddr: 0x696E8, symSize: 0x0 } + - { offset: 0x20507, size: 0x8, addend: 0x0, symName: _XSErrorFromException, symObjAddr: 0x0, symBinAddr: 0x251E4, symSize: 0x1BC } + - { offset: 0x2053D, size: 0x8, addend: 0x0, symName: _XSRoundToDecimal, symObjAddr: 0x250, symBinAddr: 0x25434, symSize: 0x50 } + - { offset: 0x20581, size: 0x8, addend: 0x0, symName: _XSAfterNext, symObjAddr: 0x2A0, symBinAddr: 0x25484, symSize: 0x15C } + - { offset: 0x205C1, size: 0x8, addend: 0x0, symName: ___XSAfterNext_block_invoke, symObjAddr: 0x3FC, symBinAddr: 0x255E0, symSize: 0x3C } + - { offset: 0x205FA, size: 0x8, addend: 0x0, symName: '+[XSHelper random:and:]', symObjAddr: 0x4A4, symBinAddr: 0x2561C, symSize: 0x50 } + - { offset: 0x2064C, size: 0x8, addend: 0x0, symName: '+[XSHelper str2Data:]', symObjAddr: 0x4F4, symBinAddr: 0x2566C, symSize: 0x84 } + - { offset: 0x20690, size: 0x8, addend: 0x0, symName: '+[XSHelper data2str:]', symObjAddr: 0x578, symBinAddr: 0x256F0, symSize: 0x88 } + - { offset: 0x206D4, size: 0x8, addend: 0x0, symName: '+[XSHelper strIsEmpty:]', symObjAddr: 0x600, symBinAddr: 0x25778, symSize: 0x12C } + - { offset: 0x20772, size: 0x8, addend: 0x0, symName: '+[XSHelper isMatch:test:]', symObjAddr: 0x72C, symBinAddr: 0x258A4, symSize: 0x134 } + - { offset: 0x2080F, size: 0x8, addend: 0x0, symName: '+[XSHelper json2Dictionary:]', symObjAddr: 0x860, symBinAddr: 0x259D8, symSize: 0x1B0 } + - { offset: 0x20853, size: 0x8, addend: 0x0, symName: '+[XSHelper jsonData2Dictionary:]', symObjAddr: 0xA10, symBinAddr: 0x25B88, symSize: 0x110 } + - { offset: 0x208B3, size: 0x8, addend: 0x0, symName: '+[XSHelper obj2JsonData:]', symObjAddr: 0xB20, symBinAddr: 0x25C98, symSize: 0xF0 } + - { offset: 0x20913, size: 0x8, addend: 0x0, symName: '+[XSHelper dic2Json:]', symObjAddr: 0xC10, symBinAddr: 0x25D88, symSize: 0xBC } + - { offset: 0x20965, size: 0x8, addend: 0x0, symName: '+[XSHelper readFileText:]', symObjAddr: 0xCCC, symBinAddr: 0x25E44, symSize: 0x140 } + - { offset: 0x209C5, size: 0x8, addend: 0x0, symName: '+[XSHelper saveFile:data:]', symObjAddr: 0xE0C, symBinAddr: 0x25F84, symSize: 0x98 } + - { offset: 0x20A17, size: 0x8, addend: 0x0, symName: '+[XSHelper saveFile:text:]', symObjAddr: 0xEA4, symBinAddr: 0x2601C, symSize: 0xD0 } + - { offset: 0x20A77, size: 0x8, addend: 0x0, symName: '+[XSHelper rmFiles:]', symObjAddr: 0xF74, symBinAddr: 0x260EC, symSize: 0x300 } + - { offset: 0x20B1F, size: 0x8, addend: 0x0, symName: '+[XSHelper str2num:]', symObjAddr: 0x1274, symBinAddr: 0x263EC, symSize: 0xE0 } + - { offset: 0x20B7F, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceStr:oldStr:newStr:]', symObjAddr: 0x1354, symBinAddr: 0x264CC, symSize: 0xD0 } + - { offset: 0x20BDF, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceMulStr:oldStr:newStr:]', symObjAddr: 0x1424, symBinAddr: 0x2659C, symSize: 0x108 } + - { offset: 0x20C69, size: 0x8, addend: 0x0, symName: '+[XSHelper replaceStr:regex:newStr:]', symObjAddr: 0x152C, symBinAddr: 0x266A4, symSize: 0x1FC } + - { offset: 0x20D33, size: 0x8, addend: 0x0, symName: '+[XSHelper base64Encode:]', symObjAddr: 0x1728, symBinAddr: 0x268A0, symSize: 0xB4 } + - { offset: 0x20D85, size: 0x8, addend: 0x0, symName: '+[XSHelper base64Decode:]', symObjAddr: 0x17DC, symBinAddr: 0x26954, symSize: 0xBC } + - { offset: 0x20DD7, size: 0x8, addend: 0x0, symName: '+[XSHelper imageFromFile:]', symObjAddr: 0x1898, symBinAddr: 0x26A10, symSize: 0x88 } + - { offset: 0x20E1B, size: 0x8, addend: 0x0, symName: '+[XSHelper base64StringFromJpgImage:]', symObjAddr: 0x1920, symBinAddr: 0x26A98, symSize: 0xDC } + - { offset: 0x20E7B, size: 0x8, addend: 0x0, symName: '+[XSHelper imageFromBase64String:]', symObjAddr: 0x19FC, symBinAddr: 0x26B74, symSize: 0xBC } + - { offset: 0x20ECD, size: 0x8, addend: 0x0, symName: '+[XSHelper png2jpg:]', symObjAddr: 0x1AB8, symBinAddr: 0x26C30, symSize: 0xB8 } + - { offset: 0x20F1F, size: 0x8, addend: 0x0, symName: '+[XSHelper getCurTime]', symObjAddr: 0x1B70, symBinAddr: 0x26CE8, symSize: 0x68 } + - { offset: 0x20F63, size: 0x8, addend: 0x0, symName: '+[XSHelper performOCROnImage:callback:]', symObjAddr: 0x1BD8, symBinAddr: 0x26D50, symSize: 0x198 } + - { offset: 0x20FCE, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke', symObjAddr: 0x1D70, symBinAddr: 0x26EE8, symSize: 0x39C } + - { offset: 0x21065, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_2', symObjAddr: 0x210C, symBinAddr: 0x27284, symSize: 0x4B4 } + - { offset: 0x21136, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_3', symObjAddr: 0x25C0, symBinAddr: 0x27738, symSize: 0x44 } + - { offset: 0x21171, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke_4', symObjAddr: 0x2604, symBinAddr: 0x2777C, symSize: 0x44 } + - { offset: 0x211BE, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40b, symObjAddr: 0x2648, symBinAddr: 0x277C0, symSize: 0x5C } + - { offset: 0x211E2, size: 0x8, addend: 0x0, symName: '___39+[XSHelper performOCROnImage:callback:]_block_invoke.69', symObjAddr: 0x26EC, symBinAddr: 0x2781C, symSize: 0x44 } + - { offset: 0x2121D, size: 0x8, addend: 0x0, symName: '-[NSData(AES) aesEncrypt:iv:]', symObjAddr: 0x2730, symBinAddr: 0x27860, symSize: 0xB0 } + - { offset: 0x21272, size: 0x8, addend: 0x0, symName: '-[NSData(AES) aesDecrypt:iv:]', symObjAddr: 0x27E0, symBinAddr: 0x27910, symSize: 0xB0 } + - { offset: 0x212C7, size: 0x8, addend: 0x0, symName: '-[NSData(AES) AES128operation:key:iv:]', symObjAddr: 0x2890, symBinAddr: 0x279C0, symSize: 0x230 } + - { offset: 0x2138F, size: 0x8, addend: 0x0, symName: '-[NSString(AES) aesEncrypt:iv:]', symObjAddr: 0x2AC0, symBinAddr: 0x27BF0, symSize: 0x10C } + - { offset: 0x213F3, size: 0x8, addend: 0x0, symName: '-[NSString(AES) aesDecrypt:iv:]', symObjAddr: 0x2BCC, symBinAddr: 0x27CFC, symSize: 0x114 } + - { offset: 0x22C73, size: 0x8, addend: 0x0, symName: '+[NSURLSession(SSLBypass) sessionWithoutSSLValidation]', symObjAddr: 0x0, symBinAddr: 0x27E10, symSize: 0xC8 } + - { offset: 0x2381B, size: 0x8, addend: 0x0, symName: '+[NSURLSession(SSLBypass) sessionWithoutSSLValidation]', symObjAddr: 0x0, symBinAddr: 0x27E10, symSize: 0xC8 } + - { offset: 0x2385F, size: 0x8, addend: 0x0, symName: '-[SSLBypassDelegate URLSession:didReceiveChallenge:completionHandler:]', symObjAddr: 0xC8, symBinAddr: 0x27ED8, symSize: 0x188 } + - { offset: 0x238CF, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper init]', symObjAddr: 0x250, symBinAddr: 0x28060, symSize: 0x10C } + - { offset: 0x23905, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doGET:withCallback:withError:]', symObjAddr: 0x35C, symBinAddr: 0x2816C, symSize: 0x3F0 } + - { offset: 0x239A9, size: 0x8, addend: 0x0, symName: '___45-[XSHttpHelper doGET:withCallback:withError:]_block_invoke', symObjAddr: 0x74C, symBinAddr: 0x2855C, symSize: 0x148 } + - { offset: 0x23A2E, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40b48b, symObjAddr: 0x894, symBinAddr: 0x286A4, symSize: 0x78 } + - { offset: 0x23A52, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doGET:]', symObjAddr: 0x964, symBinAddr: 0x2871C, symSize: 0x2A4 } + - { offset: 0x23AD6, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xC08, symBinAddr: 0x289C0, symSize: 0x58 } + - { offset: 0x23AFA, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xC60, symBinAddr: 0x28A18, symSize: 0x30 } + - { offset: 0x23B16, size: 0x8, addend: 0x0, symName: '___22-[XSHttpHelper doGET:]_block_invoke', symObjAddr: 0xC90, symBinAddr: 0x28A48, symSize: 0x74 } + - { offset: 0x23B74, size: 0x8, addend: 0x0, symName: '___22-[XSHttpHelper doGET:]_block_invoke.85', symObjAddr: 0xDA4, symBinAddr: 0x28ABC, symSize: 0x5C } + - { offset: 0x23BBB, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doPOST:json:withCallback:withError:]', symObjAddr: 0xE6C, symBinAddr: 0x28B18, symSize: 0x488 } + - { offset: 0x23C7C, size: 0x8, addend: 0x0, symName: '___51-[XSHttpHelper doPOST:json:withCallback:withError:]_block_invoke', symObjAddr: 0x12F4, symBinAddr: 0x28FA0, symSize: 0x13C } + - { offset: 0x23D01, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper doPOST:json:]', symObjAddr: 0x1430, symBinAddr: 0x290DC, symSize: 0x2D0 } + - { offset: 0x23D93, size: 0x8, addend: 0x0, symName: '___28-[XSHttpHelper doPOST:json:]_block_invoke', symObjAddr: 0x1700, symBinAddr: 0x293AC, symSize: 0x74 } + - { offset: 0x23DF1, size: 0x8, addend: 0x0, symName: '___28-[XSHttpHelper doPOST:json:]_block_invoke_2', symObjAddr: 0x1774, symBinAddr: 0x29420, symSize: 0x5C } + - { offset: 0x23E38, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper requestNetworkPermissions]', symObjAddr: 0x17D0, symBinAddr: 0x2947C, symSize: 0x68 } + - { offset: 0x23E78, size: 0x8, addend: 0x0, symName: '___41-[XSHttpHelper requestNetworkPermissions]_block_invoke', symObjAddr: 0x1838, symBinAddr: 0x294E4, symSize: 0x60 } + - { offset: 0x23EAE, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setupNetworkConfiguration]', symObjAddr: 0x1898, symBinAddr: 0x29544, symSize: 0x98 } + - { offset: 0x23EEE, size: 0x8, addend: 0x0, symName: '___41-[XSHttpHelper setupNetworkConfiguration]_block_invoke', symObjAddr: 0x1930, symBinAddr: 0x295DC, symSize: 0x7C } + - { offset: 0x23F24, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper dataTask]', symObjAddr: 0x19AC, symBinAddr: 0x29658, symSize: 0x1C } + - { offset: 0x23F5A, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setDataTask:]', symObjAddr: 0x19C8, symBinAddr: 0x29674, symSize: 0x38 } + - { offset: 0x23F98, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper postDataTask]', symObjAddr: 0x1A00, symBinAddr: 0x296AC, symSize: 0x1C } + - { offset: 0x23FCE, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper setPostDataTask:]', symObjAddr: 0x1A1C, symBinAddr: 0x296C8, symSize: 0x38 } + - { offset: 0x2400C, size: 0x8, addend: 0x0, symName: '-[XSHttpHelper .cxx_destruct]', symObjAddr: 0x1A54, symBinAddr: 0x29700, symSize: 0x5C } + - { offset: 0x24CE5, size: 0x8, addend: 0x0, symName: _XSInitGetSenderId, symObjAddr: 0x0, symBinAddr: 0x2975C, symSize: 0x294 } + - { offset: 0x24CF2, size: 0x8, addend: 0x0, symName: '+[XSIosTouch sharedInstance]', symObjAddr: 0x400, symBinAddr: 0x29B5C, symSize: 0x90 } + - { offset: 0x24D1B, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0xC0E0, symBinAddr: 0x69700, symSize: 0x0 } + - { offset: 0x24D30, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0xC0E8, symBinAddr: 0x69708, symSize: 0x0 } + - { offset: 0x24EA6, size: 0x8, addend: 0x0, symName: '-[XSIosTouch handleEventSystemFailure]', symObjAddr: 0xB30, symBinAddr: 0x2A28C, symSize: 0xB4 } + - { offset: 0x24ECB, size: 0x8, addend: 0x0, symName: _handleEventSystemFailure.failureCount, symObjAddr: 0xC0F0, symBinAddr: 0x69710, symSize: 0x0 } + - { offset: 0x24EF4, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Keyboard:down:]', symObjAddr: 0x1E34, symBinAddr: 0x2B52C, symSize: 0xB8 } + - { offset: 0x24F1B, size: 0x8, addend: 0x0, symName: '_Keyboard:down:.client', symObjAddr: 0xC0F8, symBinAddr: 0x69718, symSize: 0x0 } + - { offset: 0x24F85, size: 0x8, addend: 0x0, symName: __XSSenderID, symObjAddr: 0xC0D0, symBinAddr: 0x696F0, symSize: 0x0 } + - { offset: 0x24FA1, size: 0x8, addend: 0x0, symName: __XSIoHIDEventSystemForSenderID, symObjAddr: 0xC0D8, symBinAddr: 0x696F8, symSize: 0x0 } + - { offset: 0x25452, size: 0x8, addend: 0x0, symName: _XSInitGetSenderId, symObjAddr: 0x0, symBinAddr: 0x2975C, symSize: 0x294 } + - { offset: 0x254C9, size: 0x8, addend: 0x0, symName: _XSStartSetSenderIDCallBack, symObjAddr: 0x294, symBinAddr: 0x299F0, symSize: 0x8C } + - { offset: 0x254DE, size: 0x8, addend: 0x0, symName: ___XSInitGetSenderId_block_invoke, symObjAddr: 0x320, symBinAddr: 0x29A7C, symSize: 0xE0 } + - { offset: 0x255B2, size: 0x8, addend: 0x0, symName: '___28+[XSIosTouch sharedInstance]_block_invoke', symObjAddr: 0x490, symBinAddr: 0x29BEC, symSize: 0x50 } + - { offset: 0x255DA, size: 0x8, addend: 0x0, symName: '-[XSIosTouch init]', symObjAddr: 0x4E0, symBinAddr: 0x29C3C, symSize: 0x334 } + - { offset: 0x25641, size: 0x8, addend: 0x0, symName: '-[XSIosTouch dealloc]', symObjAddr: 0x814, symBinAddr: 0x29F70, symSize: 0xB4 } + - { offset: 0x25673, size: 0x8, addend: 0x0, symName: '-[XSIosTouch cleanupResources]', symObjAddr: 0x8C8, symBinAddr: 0x2A024, symSize: 0xB4 } + - { offset: 0x256A5, size: 0x8, addend: 0x0, symName: '-[XSIosTouch checkSystemStatus]', symObjAddr: 0x97C, symBinAddr: 0x2A0D8, symSize: 0xDC } + - { offset: 0x256E9, size: 0x8, addend: 0x0, symName: '-[XSIosTouch resetEventSystem]', symObjAddr: 0xA58, symBinAddr: 0x2A1B4, symSize: 0xD8 } + - { offset: 0x2571B, size: 0x8, addend: 0x0, symName: '-[XSIosTouch getAbsoluteTime]', symObjAddr: 0xBE4, symBinAddr: 0x2A340, symSize: 0x44 } + - { offset: 0x257C1, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEvent:type:x:y:]', symObjAddr: 0xC28, symBinAddr: 0x2A384, symSize: 0x3EC } + - { offset: 0x25967, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchDown:x:y:]', symObjAddr: 0x1014, symBinAddr: 0x2A770, symSize: 0x4C } + - { offset: 0x259CB, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchMove:x:y:]', symObjAddr: 0x1060, symBinAddr: 0x2A7BC, symSize: 0x4C } + - { offset: 0x25A2F, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateChildEventTouchUp:x:y:]', symObjAddr: 0x10AC, symBinAddr: 0x2A808, symSize: 0x4C } + - { offset: 0x25A93, size: 0x8, addend: 0x0, symName: '-[XSIosTouch generateParentEvent]', symObjAddr: 0x10F8, symBinAddr: 0x2A854, symSize: 0xB4 } + - { offset: 0x25AE8, size: 0x8, addend: 0x0, symName: '-[XSIosTouch getKeyWindow]', symObjAddr: 0x11AC, symBinAddr: 0x2A908, symSize: 0x214 } + - { offset: 0x25B37, size: 0x8, addend: 0x0, symName: '-[XSIosTouch postIOHIDEvent:]', symObjAddr: 0x13C0, symBinAddr: 0x2AB1C, symSize: 0x31C } + - { offset: 0x25B9D, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Down:x:y:]', symObjAddr: 0x16DC, symBinAddr: 0x2AE38, symSize: 0x88 } + - { offset: 0x25C29, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Move:x:y:]', symObjAddr: 0x1764, symBinAddr: 0x2AEC0, symSize: 0x88 } + - { offset: 0x25CB5, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Up:x:y:]', symObjAddr: 0x17EC, symBinAddr: 0x2AF48, symSize: 0x88 } + - { offset: 0x25D41, size: 0x8, addend: 0x0, symName: '-[XSIosTouch Tap:x:y:]', symObjAddr: 0x1874, symBinAddr: 0x2AFD0, symSize: 0x144 } + - { offset: 0x25DB0, size: 0x8, addend: 0x0, symName: '___22-[XSIosTouch Tap:x:y:]_block_invoke', symObjAddr: 0x19B8, symBinAddr: 0x2B114, symSize: 0x2C8 } + - { offset: 0x25E69, size: 0x8, addend: 0x0, symName: '-[XSIosTouch End:]', symObjAddr: 0x1CE4, symBinAddr: 0x2B3DC, symSize: 0x150 } + - { offset: 0x25EC0, size: 0x8, addend: 0x0, symName: '-[XSIosTouch KeyDown:]', symObjAddr: 0x1EEC, symBinAddr: 0x2B5E4, symSize: 0x3C } + - { offset: 0x25F02, size: 0x8, addend: 0x0, symName: '-[XSIosTouch KeyUp:]', symObjAddr: 0x1F28, symBinAddr: 0x2B620, symSize: 0x3C } + - { offset: 0x25F44, size: 0x8, addend: 0x0, symName: '-[XSIosTouch .cxx_destruct]', symObjAddr: 0x1F64, symBinAddr: 0x2B65C, symSize: 0x4C } + - { offset: 0x25F76, size: 0x8, addend: 0x0, symName: _XSSetSenderIdCallback, symObjAddr: 0x1FB0, symBinAddr: 0x2B6A8, symSize: 0x1B4 } + - { offset: 0x27A7A, size: 0x8, addend: 0x0, symName: '+[XSPhoneConfig sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2B85C, symSize: 0x90 } + - { offset: 0x27A93, size: 0x8, addend: 0x0, symName: __configPath, symObjAddr: 0x2880, symBinAddr: 0x695C8, symSize: 0x0 } + - { offset: 0x27AFA, size: 0x8, addend: 0x0, symName: '+[XSPhoneConfig sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2B85C, symSize: 0x90 } + - { offset: 0x27B23, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x6798, symBinAddr: 0x69720, symSize: 0x0 } + - { offset: 0x27B38, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x67A0, symBinAddr: 0x69728, symSize: 0x0 } + - { offset: 0x27CBE, size: 0x8, addend: 0x0, symName: '___31+[XSPhoneConfig sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x2B8EC, symSize: 0x50 } + - { offset: 0x27CE6, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig init]', symObjAddr: 0xE0, symBinAddr: 0x2B93C, symSize: 0xEC } + - { offset: 0x27D1C, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig encryptAndSavePlist:path:]', symObjAddr: 0x1CC, symBinAddr: 0x2BA28, symSize: 0x160 } + - { offset: 0x27D94, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig loadAndDecryptPlistFromFile:]', symObjAddr: 0x32C, symBinAddr: 0x2BB88, symSize: 0x1C0 } + - { offset: 0x27E11, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig MyConfig]', symObjAddr: 0x4EC, symBinAddr: 0x2BD48, symSize: 0xBC } + - { offset: 0x27E51, size: 0x8, addend: 0x0, symName: '___25-[XSPhoneConfig MyConfig]_block_invoke', symObjAddr: 0x5A8, symBinAddr: 0x2BE04, symSize: 0x204 } + - { offset: 0x27EC6, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetConfigItem:Val:]', symObjAddr: 0x810, symBinAddr: 0x2C008, symSize: 0x200 } + - { offset: 0x27F3B, size: 0x8, addend: 0x0, symName: '___35-[XSPhoneConfig SetConfigItem:Val:]_block_invoke', symObjAddr: 0xA10, symBinAddr: 0x2C208, symSize: 0x2C0 } + - { offset: 0x2800C, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48r56w, symObjAddr: 0xCD0, symBinAddr: 0x2C4C8, symSize: 0x88 } + - { offset: 0x28030, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48r56w, symObjAddr: 0xD58, symBinAddr: 0x2C550, symSize: 0x64 } + - { offset: 0x2804C, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetMyConfigStrVal:defVal:]', symObjAddr: 0xDBC, symBinAddr: 0x2C5B4, symSize: 0x234 } + - { offset: 0x280C1, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xFF0, symBinAddr: 0x2C7E8, symSize: 0x58 } + - { offset: 0x280E5, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x1048, symBinAddr: 0x2C840, symSize: 0x30 } + - { offset: 0x28101, size: 0x8, addend: 0x0, symName: '___42-[XSPhoneConfig GetMyConfigStrVal:defVal:]_block_invoke', symObjAddr: 0x1078, symBinAddr: 0x2C870, symSize: 0x218 } + - { offset: 0x2819F, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r48w, symObjAddr: 0x1290, symBinAddr: 0x2CA88, symSize: 0x70 } + - { offset: 0x281C3, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r48w, symObjAddr: 0x1300, symBinAddr: 0x2CAF8, symSize: 0x50 } + - { offset: 0x281DF, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetLongVal:defVal:]', symObjAddr: 0x1350, symBinAddr: 0x2CB48, symSize: 0x174 } + - { offset: 0x28231, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetIPhoneName:]', symObjAddr: 0x14C4, symBinAddr: 0x2CCBC, symSize: 0x74 } + - { offset: 0x28275, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetServerURL:]', symObjAddr: 0x1538, symBinAddr: 0x2CD30, symSize: 0x74 } + - { offset: 0x282B9, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig IPhoneName]', symObjAddr: 0x15AC, symBinAddr: 0x2CDA4, symSize: 0x40 } + - { offset: 0x282EF, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig DeviceId]', symObjAddr: 0x15EC, symBinAddr: 0x2CDE4, symSize: 0x1E0 } + - { offset: 0x2835B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig MainServerURL]', symObjAddr: 0x17CC, symBinAddr: 0x2CFC4, symSize: 0x40 } + - { offset: 0x28391, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig ServerURL]', symObjAddr: 0x180C, symBinAddr: 0x2D004, symSize: 0x40 } + - { offset: 0x283C7, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetFullServerURL:]', symObjAddr: 0x184C, symBinAddr: 0x2D044, symSize: 0xD0 } + - { offset: 0x2840B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetMainServerURL:]', symObjAddr: 0x191C, symBinAddr: 0x2D114, symSize: 0xD0 } + - { offset: 0x2844F, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetRemoteIPURL]', symObjAddr: 0x19EC, symBinAddr: 0x2D1E4, symSize: 0x40 } + - { offset: 0x28485, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig ApiKey]', symObjAddr: 0x1A2C, symBinAddr: 0x2D224, symSize: 0x40 } + - { offset: 0x284BB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetApiKey:]', symObjAddr: 0x1A6C, symBinAddr: 0x2D264, symSize: 0x68 } + - { offset: 0x284FB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig LastReboot]', symObjAddr: 0x1AD4, symBinAddr: 0x2D2CC, symSize: 0x3C } + - { offset: 0x28531, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetLastReboot:]', symObjAddr: 0x1B10, symBinAddr: 0x2D308, symSize: 0x78 } + - { offset: 0x28571, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SenderId]', symObjAddr: 0x1B88, symBinAddr: 0x2D380, symSize: 0x3C } + - { offset: 0x285A7, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetSenderId:]', symObjAddr: 0x1BC4, symBinAddr: 0x2D3BC, symSize: 0x78 } + - { offset: 0x285E9, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig GetLastOverTime]', symObjAddr: 0x1C3C, symBinAddr: 0x2D434, symSize: 0x218 } + - { offset: 0x2867B, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig SetLastOverTime:]', symObjAddr: 0x1E54, symBinAddr: 0x2D64C, symSize: 0x154 } + - { offset: 0x286EB, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig reLoad]', symObjAddr: 0x1FA8, symBinAddr: 0x2D7A0, symSize: 0xB8 } + - { offset: 0x2871E, size: 0x8, addend: 0x0, symName: '___23-[XSPhoneConfig reLoad]_block_invoke', symObjAddr: 0x2060, symBinAddr: 0x2D858, symSize: 0xAC } + - { offset: 0x2875E, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig dealloc]', symObjAddr: 0x2178, symBinAddr: 0x2D904, symSize: 0x6C } + - { offset: 0x28791, size: 0x8, addend: 0x0, symName: '-[XSPhoneConfig .cxx_destruct]', symObjAddr: 0x21E4, symBinAddr: 0x2D970, symSize: 0x4C } + - { offset: 0x28D45, size: 0x8, addend: 0x0, symName: '+[XSPhoneInfo sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2D9BC, symSize: 0x90 } + - { offset: 0x28D52, size: 0x8, addend: 0x0, symName: '+[XSPhoneInfo sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2D9BC, symSize: 0x90 } + - { offset: 0x28D7B, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x98D0, symBinAddr: 0x69730, symSize: 0x0 } + - { offset: 0x28D90, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x98D8, symBinAddr: 0x69738, symSize: 0x0 } + - { offset: 0x293FF, size: 0x8, addend: 0x0, symName: '___29+[XSPhoneInfo sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x2DA4C, symSize: 0x50 } + - { offset: 0x29427, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo init]', symObjAddr: 0xE0, symBinAddr: 0x2DA9C, symSize: 0x100 } + - { offset: 0x2945D, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setupBatteryMonitoring]', symObjAddr: 0x1E0, symBinAddr: 0x2DB9C, symSize: 0x108 } + - { offset: 0x2948F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo startBatteryMonitoring]', symObjAddr: 0x2E8, symBinAddr: 0x2DCA4, symSize: 0xBC } + - { offset: 0x294C1, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateBatteryInfo]', symObjAddr: 0x3A4, symBinAddr: 0x2DD60, symSize: 0x100 } + - { offset: 0x294F3, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateDetailedBatteryInfo]', symObjAddr: 0x4A4, symBinAddr: 0x2DE60, symSize: 0x4A4 } + - { offset: 0x29594, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateBatteryStatus:]', symObjAddr: 0x948, symBinAddr: 0x2E304, symSize: 0x118 } + - { offset: 0x295E2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getBatteryInfo]', symObjAddr: 0xA60, symBinAddr: 0x2E41C, symSize: 0x340 } + - { offset: 0x2961A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo stopBatteryMonitoring]', symObjAddr: 0xDA0, symBinAddr: 0x2E75C, symSize: 0x90 } + - { offset: 0x2964C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryLevelDidChange:]', symObjAddr: 0xE30, symBinAddr: 0x2E7EC, symSize: 0x5C } + - { offset: 0x2968C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryStateDidChange:]', symObjAddr: 0xE8C, symBinAddr: 0x2E848, symSize: 0x5C } + - { offset: 0x296CC, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo updateMemoryInfo]', symObjAddr: 0xEE8, symBinAddr: 0x2E8A4, symSize: 0x14C } + - { offset: 0x29736, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getMemoryUsageForPid:]', symObjAddr: 0x1034, symBinAddr: 0x2E9F0, symSize: 0x94 } + - { offset: 0x297A4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo handleCriticalMemoryPressure]', symObjAddr: 0x10C8, symBinAddr: 0x2EA84, symSize: 0x12C } + - { offset: 0x297D6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo handleWarningMemoryPressure]', symObjAddr: 0x11F4, symBinAddr: 0x2EBB0, symSize: 0x12C } + - { offset: 0x29809, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo startMemoryMonitoring]', symObjAddr: 0x1320, symBinAddr: 0x2ECDC, symSize: 0x7C } + - { offset: 0x2983C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo stopMemoryMonitoring]', symObjAddr: 0x139C, symBinAddr: 0x2ED58, symSize: 0x64 } + - { offset: 0x2986F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo checkMemoryStatus]', symObjAddr: 0x1400, symBinAddr: 0x2EDBC, symSize: 0x30 } + - { offset: 0x298A2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo dealloc]', symObjAddr: 0x1430, symBinAddr: 0x2EDEC, symSize: 0xF4 } + - { offset: 0x298D5, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo IPAddress]', symObjAddr: 0x1524, symBinAddr: 0x2EEE0, symSize: 0x194 } + - { offset: 0x29930, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x16B8, symBinAddr: 0x2F074, symSize: 0x58 } + - { offset: 0x29954, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x1710, symBinAddr: 0x2F0CC, symSize: 0x30 } + - { offset: 0x29970, size: 0x8, addend: 0x0, symName: '___24-[XSPhoneInfo IPAddress]_block_invoke', symObjAddr: 0x1740, symBinAddr: 0x2F0FC, symSize: 0xB4 } + - { offset: 0x299DF, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32r, symObjAddr: 0x17F4, symBinAddr: 0x2F1B0, symSize: 0x3C } + - { offset: 0x29A03, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32r, symObjAddr: 0x1830, symBinAddr: 0x2F1EC, symSize: 0x30 } + - { offset: 0x29A1F, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo getIPAddresses]', symObjAddr: 0x1860, symBinAddr: 0x2F21C, symSize: 0x2F8 } + - { offset: 0x29B2B, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo CurrentThermalState]', symObjAddr: 0x1B58, symBinAddr: 0x2F514, symSize: 0x148 } + - { offset: 0x29B71, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo DiskSize]', symObjAddr: 0x1CA0, symBinAddr: 0x2F65C, symSize: 0x2E8 } + - { offset: 0x29C1B, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo IPhoneStatus]', symObjAddr: 0x1F88, symBinAddr: 0x2F944, symSize: 0x224 } + - { offset: 0x29C8E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryLevel]', symObjAddr: 0x21AC, symBinAddr: 0x2FB68, symSize: 0x1C } + - { offset: 0x29CC4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isFullyCharged]', symObjAddr: 0x21C8, symBinAddr: 0x2FB84, symSize: 0x20 } + - { offset: 0x29CFA, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryVoltage]', symObjAddr: 0x21E8, symBinAddr: 0x2FBA4, symSize: 0x1C } + - { offset: 0x29D30, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo maxCapacity]', symObjAddr: 0x2204, symBinAddr: 0x2FBC0, symSize: 0x1C } + - { offset: 0x29D66, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo currentCapacity]', symObjAddr: 0x2220, symBinAddr: 0x2FBDC, symSize: 0x1C } + - { offset: 0x29D9C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo designCapacity]', symObjAddr: 0x223C, symBinAddr: 0x2FBF8, symSize: 0x1C } + - { offset: 0x29DD2, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo cycleCount]', symObjAddr: 0x2258, symBinAddr: 0x2FC14, symSize: 0x1C } + - { offset: 0x29E08, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryHealth]', symObjAddr: 0x2274, symBinAddr: 0x2FC30, symSize: 0x1C } + - { offset: 0x29E3E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isCharging]', symObjAddr: 0x2290, symBinAddr: 0x2FC4C, symSize: 0x20 } + - { offset: 0x29E74, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo batteryStatus]', symObjAddr: 0x22B0, symBinAddr: 0x2FC6C, symSize: 0x1C } + - { offset: 0x29EAA, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setBatteryStatus:]', symObjAddr: 0x22CC, symBinAddr: 0x2FC88, symSize: 0x3C } + - { offset: 0x29EE8, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo temperature]', symObjAddr: 0x2308, symBinAddr: 0x2FCC4, symSize: 0x1C } + - { offset: 0x29F1E, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo voltage]', symObjAddr: 0x2324, symBinAddr: 0x2FCE0, symSize: 0x1C } + - { offset: 0x29F54, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo totalMemory]', symObjAddr: 0x2340, symBinAddr: 0x2FCFC, symSize: 0x1C } + - { offset: 0x29F8A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo availableMemory]', symObjAddr: 0x235C, symBinAddr: 0x2FD18, symSize: 0x1C } + - { offset: 0x29FC0, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo usedMemory]', symObjAddr: 0x2378, symBinAddr: 0x2FD34, symSize: 0x1C } + - { offset: 0x29FF6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo memoryUsage]', symObjAddr: 0x2394, symBinAddr: 0x2FD50, symSize: 0x1C } + - { offset: 0x2A02C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo pageSize]', symObjAddr: 0x23B0, symBinAddr: 0x2FD6C, symSize: 0x1C } + - { offset: 0x2A062, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo remoteIp]', symObjAddr: 0x23CC, symBinAddr: 0x2FD88, symSize: 0x1C } + - { offset: 0x2A098, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setRemoteIp:]', symObjAddr: 0x23E8, symBinAddr: 0x2FDA4, symSize: 0x3C } + - { offset: 0x2A0D6, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo monitorTimer]', symObjAddr: 0x2424, symBinAddr: 0x2FDE0, symSize: 0x1C } + - { offset: 0x2A10C, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setMonitorTimer:]', symObjAddr: 0x2440, symBinAddr: 0x2FDFC, symSize: 0x38 } + - { offset: 0x2A14A, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo isMonitoring]', symObjAddr: 0x2478, symBinAddr: 0x2FE34, symSize: 0x20 } + - { offset: 0x2A180, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setIsMonitoring:]', symObjAddr: 0x2498, symBinAddr: 0x2FE54, symSize: 0x28 } + - { offset: 0x2A1BE, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo memoryWarningHandler]', symObjAddr: 0x24C0, symBinAddr: 0x2FE7C, symSize: 0x1C } + - { offset: 0x2A1F4, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo setMemoryWarningHandler:]', symObjAddr: 0x24DC, symBinAddr: 0x2FE98, symSize: 0x3C } + - { offset: 0x2A232, size: 0x8, addend: 0x0, symName: '-[XSPhoneInfo .cxx_destruct]', symObjAddr: 0x2518, symBinAddr: 0x2FED4, symSize: 0x7C } + - { offset: 0x2AA21, size: 0x8, addend: 0x0, symName: '+[XUDPServer sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2FF50, symSize: 0x90 } + - { offset: 0x2AA2E, size: 0x8, addend: 0x0, symName: '+[XUDPServer sharedInstance]', symObjAddr: 0x0, symBinAddr: 0x2FF50, symSize: 0x90 } + - { offset: 0x2AA57, size: 0x8, addend: 0x0, symName: _sharedInstance._sharedInstance, symObjAddr: 0x2EC8, symBinAddr: 0x69740, symSize: 0x0 } + - { offset: 0x2AA6C, size: 0x8, addend: 0x0, symName: _sharedInstance.oncePredicate, symObjAddr: 0x2ED0, symBinAddr: 0x69748, symSize: 0x0 } + - { offset: 0x2ABE6, size: 0x8, addend: 0x0, symName: '___28+[XUDPServer sharedInstance]_block_invoke', symObjAddr: 0x90, symBinAddr: 0x2FFE0, symSize: 0x50 } + - { offset: 0x2AC0E, size: 0x8, addend: 0x0, symName: '-[XUDPServer init]', symObjAddr: 0xE0, symBinAddr: 0x30030, symSize: 0xB4 } + - { offset: 0x2AC44, size: 0x8, addend: 0x0, symName: '-[XUDPServer start]', symObjAddr: 0x194, symBinAddr: 0x300E4, symSize: 0x18C } + - { offset: 0x2AC92, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didConnectToAddress:]', symObjAddr: 0x320, symBinAddr: 0x30270, symSize: 0xB8 } + - { offset: 0x2ACE0, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didReceiveData:fromAddress:withFilterContext:]', symObjAddr: 0x3D8, symBinAddr: 0x30328, symSize: 0x214 } + - { offset: 0x2AD83, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didNotConnect:]', symObjAddr: 0x5EC, symBinAddr: 0x3053C, symSize: 0x8C } + - { offset: 0x2ADD1, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didSendDataWithTag:]', symObjAddr: 0x678, symBinAddr: 0x305C8, symSize: 0x74 } + - { offset: 0x2AE1F, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocket:didNotSendDataWithTag:dueToError:]', symObjAddr: 0x6EC, symBinAddr: 0x3063C, symSize: 0x98 } + - { offset: 0x2AE7B, size: 0x8, addend: 0x0, symName: '-[XUDPServer udpSocketDidClose:withError:]', symObjAddr: 0x784, symBinAddr: 0x306D4, symSize: 0x8C } + - { offset: 0x2AEC9, size: 0x8, addend: 0x0, symName: '-[XUDPServer .cxx_destruct]', symObjAddr: 0x810, symBinAddr: 0x30760, symSize: 0x34 } + - { offset: 0x2B135, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket init]', symObjAddr: 0x0, symBinAddr: 0x30794, symSize: 0x94 } + - { offset: 0x2B14E, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketException, symObjAddr: 0x19808, symBinAddr: 0x5D468, symSize: 0x0 } + - { offset: 0x2B1C6, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketErrorDomain, symObjAddr: 0x19810, symBinAddr: 0x5D470, symSize: 0x0 } + - { offset: 0x2B1DB, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketQueueName, symObjAddr: 0x19818, symBinAddr: 0x5D478, symSize: 0x0 } + - { offset: 0x2B1F0, size: 0x8, addend: 0x0, symName: _GCDAsyncUdpSocketThreadName, symObjAddr: 0x19820, symBinAddr: 0x5D480, symSize: 0x0 } + - { offset: 0x2B1F9, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket startListenerThreadIfNeeded]', symObjAddr: 0x153B4, symBinAddr: 0x457C8, symSize: 0xC4 } + - { offset: 0x2B220, size: 0x8, addend: 0x0, symName: _startListenerThreadIfNeeded.predicate, symObjAddr: 0x39EE0, symBinAddr: 0x69750, symSize: 0x0 } + - { offset: 0x2B29D, size: 0x8, addend: 0x0, symName: _listenerThread, symObjAddr: 0x39EE8, symBinAddr: 0x69758, symSize: 0x0 } + - { offset: 0x2BCCE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket init]', symObjAddr: 0x0, symBinAddr: 0x30794, symSize: 0x94 } + - { offset: 0x2BD05, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket initWithData:timeout:tag:]', symObjAddr: 0x94, symBinAddr: 0x30828, symSize: 0x110 } + - { offset: 0x2BD69, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSendPacket .cxx_destruct]', symObjAddr: 0x1A4, symBinAddr: 0x30938, symSize: 0x6C } + - { offset: 0x2BD9C, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSpecialPacket init]', symObjAddr: 0x210, symBinAddr: 0x309A4, symSize: 0x98 } + - { offset: 0x2BDD3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSpecialPacket .cxx_destruct]', symObjAddr: 0x2A8, symBinAddr: 0x30A3C, symSize: 0x4C } + - { offset: 0x2BE06, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket init]', symObjAddr: 0x2F4, symBinAddr: 0x30A88, symSize: 0x78 } + - { offset: 0x2BE3D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithSocketQueue:]', symObjAddr: 0x36C, symBinAddr: 0x30B00, symSize: 0xA0 } + - { offset: 0x2BE83, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithDelegate:delegateQueue:]', symObjAddr: 0x40C, symBinAddr: 0x30BA0, symSize: 0xC4 } + - { offset: 0x2BED8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket initWithDelegate:delegateQueue:socketQueue:]', symObjAddr: 0x4D0, symBinAddr: 0x30C64, symSize: 0x47C } + - { offset: 0x2BF59, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket dealloc]', symObjAddr: 0x94C, symBinAddr: 0x310E0, symSize: 0x174 } + - { offset: 0x2BF8C, size: 0x8, addend: 0x0, symName: '___28-[GCDAsyncUdpSocket dealloc]_block_invoke', symObjAddr: 0xAC0, symBinAddr: 0x31254, symSize: 0x38 } + - { offset: 0x2BFCC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket delegate]', symObjAddr: 0xB64, symBinAddr: 0x3128C, symSize: 0x190 } + - { offset: 0x2C026, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0xCF4, symBinAddr: 0x3141C, symSize: 0x58 } + - { offset: 0x2C04A, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0xD4C, symBinAddr: 0x31474, symSize: 0x30 } + - { offset: 0x2C066, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket delegate]_block_invoke', symObjAddr: 0xD7C, symBinAddr: 0x314A4, symSize: 0x60 } + - { offset: 0x2C0BE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:synchronously:]', symObjAddr: 0xE7C, symBinAddr: 0x31504, symSize: 0x16C } + - { offset: 0x2C11E, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket setDelegate:synchronously:]_block_invoke', symObjAddr: 0xFE8, symBinAddr: 0x31670, symSize: 0x3C } + - { offset: 0x2C170, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:]', symObjAddr: 0x10C8, symBinAddr: 0x316AC, symSize: 0x68 } + - { offset: 0x2C1B2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegate:]', symObjAddr: 0x1130, symBinAddr: 0x31714, symSize: 0x68 } + - { offset: 0x2C1F4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket delegateQueue]', symObjAddr: 0x1198, symBinAddr: 0x3177C, symSize: 0x198 } + - { offset: 0x2C24E, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket delegateQueue]_block_invoke', symObjAddr: 0x1330, symBinAddr: 0x31914, symSize: 0x44 } + - { offset: 0x2C2A6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegateQueue:synchronously:]', symObjAddr: 0x1374, symBinAddr: 0x31958, symSize: 0x16C } + - { offset: 0x2C306, size: 0x8, addend: 0x0, symName: '___52-[GCDAsyncUdpSocket setDelegateQueue:synchronously:]_block_invoke', symObjAddr: 0x14E0, symBinAddr: 0x31AC4, symSize: 0x3C } + - { offset: 0x2C358, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegateQueue:]', symObjAddr: 0x151C, symBinAddr: 0x31B00, symSize: 0x68 } + - { offset: 0x2C39A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegateQueue:]', symObjAddr: 0x1584, symBinAddr: 0x31B68, symSize: 0x68 } + - { offset: 0x2C3DC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getDelegate:delegateQueue:]', symObjAddr: 0x15EC, symBinAddr: 0x31BD0, symSize: 0x280 } + - { offset: 0x2C465, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket getDelegate:delegateQueue:]_block_invoke', symObjAddr: 0x186C, symBinAddr: 0x31E50, symSize: 0x7C } + - { offset: 0x2C4D5, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40r48r, symObjAddr: 0x18E8, symBinAddr: 0x31ECC, symSize: 0x78 } + - { offset: 0x2C4F9, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40r48r, symObjAddr: 0x1960, symBinAddr: 0x31F44, symSize: 0x58 } + - { offset: 0x2C515, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:delegateQueue:synchronously:]', symObjAddr: 0x19B8, symBinAddr: 0x31F9C, symSize: 0x1B0 } + - { offset: 0x2C584, size: 0x8, addend: 0x0, symName: '___61-[GCDAsyncUdpSocket setDelegate:delegateQueue:synchronously:]_block_invoke', symObjAddr: 0x1B68, symBinAddr: 0x3214C, symSize: 0x54 } + - { offset: 0x2C5E8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setDelegate:delegateQueue:]', symObjAddr: 0x1C88, symBinAddr: 0x321A0, symSize: 0x90 } + - { offset: 0x2C639, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket synchronouslySetDelegate:delegateQueue:]', symObjAddr: 0x1D18, symBinAddr: 0x32230, symSize: 0x90 } + - { offset: 0x2C68A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4Enabled]', symObjAddr: 0x1DA8, symBinAddr: 0x322C0, symSize: 0x16C } + - { offset: 0x2C6E4, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket isIPv4Enabled]_block_invoke', symObjAddr: 0x1F14, symBinAddr: 0x3242C, symSize: 0x38 } + - { offset: 0x2C73C, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPv4Enabled:]', symObjAddr: 0x1F4C, symBinAddr: 0x32464, symSize: 0x104 } + - { offset: 0x2C78D, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket setIPv4Enabled:]_block_invoke', symObjAddr: 0x2050, symBinAddr: 0x32568, symSize: 0x5C } + - { offset: 0x2C7DF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6Enabled]', symObjAddr: 0x20AC, symBinAddr: 0x325C4, symSize: 0x16C } + - { offset: 0x2C839, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket isIPv6Enabled]_block_invoke', symObjAddr: 0x2218, symBinAddr: 0x32730, symSize: 0x38 } + - { offset: 0x2C891, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPv6Enabled:]', symObjAddr: 0x2250, symBinAddr: 0x32768, symSize: 0x104 } + - { offset: 0x2C8E2, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket setIPv6Enabled:]_block_invoke', symObjAddr: 0x2354, symBinAddr: 0x3286C, symSize: 0x5C } + - { offset: 0x2C934, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4Preferred]', symObjAddr: 0x23B0, symBinAddr: 0x328C8, symSize: 0x16C } + - { offset: 0x2C98E, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket isIPv4Preferred]_block_invoke', symObjAddr: 0x251C, symBinAddr: 0x32A34, symSize: 0x44 } + - { offset: 0x2C9E6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6Preferred]', symObjAddr: 0x2560, symBinAddr: 0x32A78, symSize: 0x16C } + - { offset: 0x2CA40, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket isIPv6Preferred]_block_invoke', symObjAddr: 0x26CC, symBinAddr: 0x32BE4, symSize: 0x44 } + - { offset: 0x2CA98, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPVersionNeutral]', symObjAddr: 0x2710, symBinAddr: 0x32C28, symSize: 0x16C } + - { offset: 0x2CAF2, size: 0x8, addend: 0x0, symName: '___39-[GCDAsyncUdpSocket isIPVersionNeutral]_block_invoke', symObjAddr: 0x287C, symBinAddr: 0x32D94, symSize: 0x38 } + - { offset: 0x2CB4A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setPreferIPv4]', symObjAddr: 0x28B4, symBinAddr: 0x32DCC, symSize: 0xF4 } + - { offset: 0x2CB8C, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket setPreferIPv4]_block_invoke', symObjAddr: 0x29A8, symBinAddr: 0x32EC0, symSize: 0x3C } + - { offset: 0x2CBCC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setPreferIPv6]', symObjAddr: 0x29E4, symBinAddr: 0x32EFC, symSize: 0xF4 } + - { offset: 0x2CC0E, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket setPreferIPv6]_block_invoke', symObjAddr: 0x2AD8, symBinAddr: 0x32FF0, symSize: 0x3C } + - { offset: 0x2CC4E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setIPVersionNeutral]', symObjAddr: 0x2B14, symBinAddr: 0x3302C, symSize: 0xF4 } + - { offset: 0x2CC90, size: 0x8, addend: 0x0, symName: '___40-[GCDAsyncUdpSocket setIPVersionNeutral]_block_invoke', symObjAddr: 0x2C08, symBinAddr: 0x33120, symSize: 0x3C } + - { offset: 0x2CCD0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxReceiveIPv4BufferSize]', symObjAddr: 0x2C44, symBinAddr: 0x3315C, symSize: 0x168 } + - { offset: 0x2CD2A, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket maxReceiveIPv4BufferSize]_block_invoke', symObjAddr: 0x2DAC, symBinAddr: 0x332C4, symSize: 0x30 } + - { offset: 0x2CD82, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxReceiveIPv4BufferSize:]', symObjAddr: 0x2DDC, symBinAddr: 0x332F4, symSize: 0x100 } + - { offset: 0x2CDD3, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket setMaxReceiveIPv4BufferSize:]_block_invoke', symObjAddr: 0x2EDC, symBinAddr: 0x333F4, symSize: 0x28 } + - { offset: 0x2CE25, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxReceiveIPv6BufferSize]', symObjAddr: 0x2F04, symBinAddr: 0x3341C, symSize: 0x168 } + - { offset: 0x2CE7F, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket maxReceiveIPv6BufferSize]_block_invoke', symObjAddr: 0x306C, symBinAddr: 0x33584, symSize: 0x30 } + - { offset: 0x2CED7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxReceiveIPv6BufferSize:]', symObjAddr: 0x309C, symBinAddr: 0x335B4, symSize: 0x100 } + - { offset: 0x2CF28, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket setMaxReceiveIPv6BufferSize:]_block_invoke', symObjAddr: 0x319C, symBinAddr: 0x336B4, symSize: 0x28 } + - { offset: 0x2CF7A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setMaxSendBufferSize:]', symObjAddr: 0x31C4, symBinAddr: 0x336DC, symSize: 0x100 } + - { offset: 0x2CFCB, size: 0x8, addend: 0x0, symName: '___42-[GCDAsyncUdpSocket setMaxSendBufferSize:]_block_invoke', symObjAddr: 0x32C4, symBinAddr: 0x337DC, symSize: 0x28 } + - { offset: 0x2D01D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maxSendBufferSize]', symObjAddr: 0x32EC, symBinAddr: 0x33804, symSize: 0x168 } + - { offset: 0x2D077, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket maxSendBufferSize]_block_invoke', symObjAddr: 0x3454, symBinAddr: 0x3396C, symSize: 0x30 } + - { offset: 0x2D0CF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket userData]', symObjAddr: 0x3484, symBinAddr: 0x3399C, symSize: 0x1BC } + - { offset: 0x2D12A, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket userData]_block_invoke', symObjAddr: 0x3640, symBinAddr: 0x33B58, symSize: 0x44 } + - { offset: 0x2D182, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setUserData:]', symObjAddr: 0x3684, symBinAddr: 0x33B9C, symSize: 0x13C } + - { offset: 0x2D1D3, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket setUserData:]_block_invoke', symObjAddr: 0x37C0, symBinAddr: 0x33CD8, symSize: 0x60 } + - { offset: 0x2D225, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidConnectToAddress:]', symObjAddr: 0x3820, symBinAddr: 0x33D38, symSize: 0x1A4 } + - { offset: 0x2D28B, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket notifyDidConnectToAddress:]_block_invoke', symObjAddr: 0x39C4, symBinAddr: 0x33EDC, symSize: 0x54 } + - { offset: 0x2D2EF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidNotConnect:]', symObjAddr: 0x3A18, symBinAddr: 0x33F30, symSize: 0x180 } + - { offset: 0x2D340, size: 0x8, addend: 0x0, symName: '___41-[GCDAsyncUdpSocket notifyDidNotConnect:]_block_invoke', symObjAddr: 0x3B98, symBinAddr: 0x340B0, symSize: 0x54 } + - { offset: 0x2D3A4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidSendDataWithTag:]', symObjAddr: 0x3BEC, symBinAddr: 0x34104, symSize: 0x13C } + - { offset: 0x2D3F5, size: 0x8, addend: 0x0, symName: '___46-[GCDAsyncUdpSocket notifyDidSendDataWithTag:]_block_invoke', symObjAddr: 0x3D28, symBinAddr: 0x34240, symSize: 0x54 } + - { offset: 0x2D459, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidNotSendDataWithTag:dueToError:]', symObjAddr: 0x3D7C, symBinAddr: 0x34294, symSize: 0x18C } + - { offset: 0x2D4B9, size: 0x8, addend: 0x0, symName: '___60-[GCDAsyncUdpSocket notifyDidNotSendDataWithTag:dueToError:]_block_invoke', symObjAddr: 0x3F08, symBinAddr: 0x34420, symSize: 0x58 } + - { offset: 0x2D52F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidReceiveData:fromAddress:withFilterContext:]', symObjAddr: 0x3F60, symBinAddr: 0x34478, symSize: 0x220 } + - { offset: 0x2D5AD, size: 0x8, addend: 0x0, symName: '___72-[GCDAsyncUdpSocket notifyDidReceiveData:fromAddress:withFilterContext:]_block_invoke', symObjAddr: 0x4180, symBinAddr: 0x34698, symSize: 0x5C } + - { offset: 0x2D635, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56s64s, symObjAddr: 0x41DC, symBinAddr: 0x346F4, symSize: 0xA4 } + - { offset: 0x2D659, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56s64s, symObjAddr: 0x4280, symBinAddr: 0x34798, symSize: 0x78 } + - { offset: 0x2D675, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket notifyDidCloseWithError:]', symObjAddr: 0x42F8, symBinAddr: 0x34810, symSize: 0x180 } + - { offset: 0x2D6C6, size: 0x8, addend: 0x0, symName: '___45-[GCDAsyncUdpSocket notifyDidCloseWithError:]_block_invoke', symObjAddr: 0x4478, symBinAddr: 0x34990, symSize: 0x54 } + - { offset: 0x2D72A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket badConfigError:]', symObjAddr: 0x44CC, symBinAddr: 0x349E4, symSize: 0x11C } + - { offset: 0x2D77F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket badParamError:]', symObjAddr: 0x45E8, symBinAddr: 0x34B00, symSize: 0x118 } + - { offset: 0x2D7D4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket gaiError:]', symObjAddr: 0x4700, symBinAddr: 0x34C18, symSize: 0x140 } + - { offset: 0x2D839, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket errnoErrorWithReason:]', symObjAddr: 0x4840, symBinAddr: 0x34D58, symSize: 0x204 } + - { offset: 0x2D8A1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket errnoError]', symObjAddr: 0x4A44, symBinAddr: 0x34F5C, symSize: 0x34 } + - { offset: 0x2D8D8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendTimeoutError]', symObjAddr: 0x4A78, symBinAddr: 0x34F90, symSize: 0x160 } + - { offset: 0x2D92D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socketClosedError]', symObjAddr: 0x4BD8, symBinAddr: 0x350F0, symSize: 0x160 } + - { offset: 0x2D982, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket otherError:]', symObjAddr: 0x4D38, symBinAddr: 0x35250, symSize: 0x118 } + - { offset: 0x2D9D7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preOp:]', symObjAddr: 0x4E50, symBinAddr: 0x35368, symSize: 0x1EC } + - { offset: 0x2DA47, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]', symObjAddr: 0x503C, symBinAddr: 0x35554, symSize: 0x300 } + - { offset: 0x2DAF4, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke', symObjAddr: 0x533C, symBinAddr: 0x35854, symSize: 0x58 } + - { offset: 0x2DB42, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke.111', symObjAddr: 0x53F0, symBinAddr: 0x358AC, symSize: 0x5FC } + - { offset: 0x2DC9E, size: 0x8, addend: 0x0, symName: __OSSwapInt16, symObjAddr: 0x59EC, symBinAddr: 0x35EA8, symSize: 0x24 } + - { offset: 0x2DCC6, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket asyncResolveHost:port:withCompletionBlock:]_block_invoke_2', symObjAddr: 0x5A10, symBinAddr: 0x35ECC, symSize: 0x58 } + - { offset: 0x2DD26, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48b, symObjAddr: 0x5A68, symBinAddr: 0x35F24, symSize: 0x74 } + - { offset: 0x2DD4A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getAddress:error:fromAddresses:]', symObjAddr: 0x5ADC, symBinAddr: 0x35F98, symSize: 0xBC4 } + - { offset: 0x2DF85, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket convertIntefaceDescription:port:intoAddress4:address6:]', symObjAddr: 0x66A0, symBinAddr: 0x36B5C, symSize: 0x694 } + - { offset: 0x2E1C2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket convertNumericHost:port:intoAddress4:address6:]', symObjAddr: 0x6D34, symBinAddr: 0x371F0, symSize: 0x2C0 } + - { offset: 0x2E297, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnectedToAddress4:]', symObjAddr: 0x6FF4, symBinAddr: 0x374B0, symSize: 0x2A8 } + - { offset: 0x2E2FB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnectedToAddress6:]', symObjAddr: 0x729C, symBinAddr: 0x37758, symSize: 0x2A8 } + - { offset: 0x2E35F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket indexOfInterfaceAddr4:]', symObjAddr: 0x7544, symBinAddr: 0x37A00, symSize: 0x160 } + - { offset: 0x2E3FE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket indexOfInterfaceAddr6:]', symObjAddr: 0x76A4, symBinAddr: 0x37B60, symSize: 0x160 } + - { offset: 0x2E49D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]', symObjAddr: 0x7804, symBinAddr: 0x37CC0, symSize: 0x3A0 } + - { offset: 0x2E4F5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke', symObjAddr: 0x7BA4, symBinAddr: 0x38060, symSize: 0xEC } + - { offset: 0x2E535, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke_2', symObjAddr: 0x7C90, symBinAddr: 0x3814C, symSize: 0x9C } + - { offset: 0x2E575, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke_3', symObjAddr: 0x7D2C, symBinAddr: 0x381E8, symSize: 0x5C } + - { offset: 0x2E5C9, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket4]_block_invoke.155', symObjAddr: 0x7DF4, symBinAddr: 0x38244, symSize: 0x5C } + - { offset: 0x2E61D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]', symObjAddr: 0x7E50, symBinAddr: 0x382A0, symSize: 0x3A0 } + - { offset: 0x2E675, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke', symObjAddr: 0x81F0, symBinAddr: 0x38640, symSize: 0xEC } + - { offset: 0x2E6B5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_2', symObjAddr: 0x82DC, symBinAddr: 0x3872C, symSize: 0x9C } + - { offset: 0x2E6F5, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_3', symObjAddr: 0x8378, symBinAddr: 0x387C8, symSize: 0x5C } + - { offset: 0x2E749, size: 0x8, addend: 0x0, symName: '___57-[GCDAsyncUdpSocket setupSendAndReceiveSourcesForSocket6]_block_invoke_4', symObjAddr: 0x83D4, symBinAddr: 0x38824, symSize: 0x5C } + - { offset: 0x2E79D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createSocket4:socket6:error:]', symObjAddr: 0x8430, symBinAddr: 0x38880, symSize: 0x30C } + - { offset: 0x2E810, size: 0x8, addend: 0x0, symName: '___49-[GCDAsyncUdpSocket createSocket4:socket6:error:]_block_invoke', symObjAddr: 0x873C, symBinAddr: 0x38B8C, symSize: 0x398 } + - { offset: 0x2E8BF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createSockets:]', symObjAddr: 0x8AD4, symBinAddr: 0x38F24, symSize: 0x68 } + - { offset: 0x2E923, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendSend4Source]', symObjAddr: 0x8B3C, symBinAddr: 0x38F8C, symSize: 0x64 } + - { offset: 0x2E956, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendSend6Source]', symObjAddr: 0x8BA0, symBinAddr: 0x38FF0, symSize: 0x64 } + - { offset: 0x2E989, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeSend4Source]', symObjAddr: 0x8C04, symBinAddr: 0x39054, symSize: 0x64 } + - { offset: 0x2E9BC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeSend6Source]', symObjAddr: 0x8C68, symBinAddr: 0x390B8, symSize: 0x64 } + - { offset: 0x2E9EF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendReceive4Source]', symObjAddr: 0x8CCC, symBinAddr: 0x3911C, symSize: 0x64 } + - { offset: 0x2EA22, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket suspendReceive6Source]', symObjAddr: 0x8D30, symBinAddr: 0x39180, symSize: 0x64 } + - { offset: 0x2EA55, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeReceive4Source]', symObjAddr: 0x8D94, symBinAddr: 0x391E4, symSize: 0x64 } + - { offset: 0x2EA88, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket resumeReceive6Source]', symObjAddr: 0x8DF8, symBinAddr: 0x39248, symSize: 0x64 } + - { offset: 0x2EABB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSocket4]', symObjAddr: 0x8E5C, symBinAddr: 0x392AC, symSize: 0xDC } + - { offset: 0x2EAEE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSocket6]', symObjAddr: 0x8F38, symBinAddr: 0x39388, symSize: 0xDC } + - { offset: 0x2EB21, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeSockets]', symObjAddr: 0x9014, symBinAddr: 0x39464, symSize: 0x4C } + - { offset: 0x2EB54, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket getLocalAddress:host:port:forSocket:withFamily:]', symObjAddr: 0x9060, symBinAddr: 0x394B0, symSize: 0x2AC } + - { offset: 0x2EC63, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedLocalAddress4Info]', symObjAddr: 0x930C, symBinAddr: 0x3975C, symSize: 0x1A0 } + - { offset: 0x2ECC3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedLocalAddress6Info]', symObjAddr: 0x94AC, symBinAddr: 0x398FC, symSize: 0x1A0 } + - { offset: 0x2ED23, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress]', symObjAddr: 0x964C, symBinAddr: 0x39A9C, symSize: 0x250 } + - { offset: 0x2ED7F, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket localAddress]_block_invoke', symObjAddr: 0x989C, symBinAddr: 0x39CEC, symSize: 0xA4 } + - { offset: 0x2EDD7, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket localAddress]_block_invoke_2', symObjAddr: 0x9940, symBinAddr: 0x39D90, symSize: 0x54 } + - { offset: 0x2EE13, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost]', symObjAddr: 0x99D0, symBinAddr: 0x39DE4, symSize: 0x250 } + - { offset: 0x2EE6F, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localHost]_block_invoke', symObjAddr: 0x9C20, symBinAddr: 0x3A034, symSize: 0xA4 } + - { offset: 0x2EEC7, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localHost]_block_invoke_2', symObjAddr: 0x9CC4, symBinAddr: 0x3A0D8, symSize: 0x54 } + - { offset: 0x2EF03, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort]', symObjAddr: 0x9D18, symBinAddr: 0x3A12C, symSize: 0x1F0 } + - { offset: 0x2EF5D, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localPort]_block_invoke', symObjAddr: 0x9F08, symBinAddr: 0x3A31C, symSize: 0x9C } + - { offset: 0x2EFB5, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket localPort]_block_invoke_2', symObjAddr: 0x9FA4, symBinAddr: 0x3A3B8, symSize: 0x54 } + - { offset: 0x2EFF1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress_IPv4]', symObjAddr: 0x9FF8, symBinAddr: 0x3A40C, symSize: 0x250 } + - { offset: 0x2F04D, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv4]_block_invoke', symObjAddr: 0xA248, symBinAddr: 0x3A65C, symSize: 0x54 } + - { offset: 0x2F0A5, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv4]_block_invoke_2', symObjAddr: 0xA29C, symBinAddr: 0x3A6B0, symSize: 0x54 } + - { offset: 0x2F0E1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost_IPv4]', symObjAddr: 0xA2F0, symBinAddr: 0x3A704, symSize: 0x250 } + - { offset: 0x2F13D, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv4]_block_invoke', symObjAddr: 0xA540, symBinAddr: 0x3A954, symSize: 0x54 } + - { offset: 0x2F195, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv4]_block_invoke_2', symObjAddr: 0xA594, symBinAddr: 0x3A9A8, symSize: 0x54 } + - { offset: 0x2F1D1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort_IPv4]', symObjAddr: 0xA5E8, symBinAddr: 0x3A9FC, symSize: 0x1F0 } + - { offset: 0x2F22B, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv4]_block_invoke', symObjAddr: 0xA7D8, symBinAddr: 0x3ABEC, symSize: 0x50 } + - { offset: 0x2F283, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv4]_block_invoke_2', symObjAddr: 0xA828, symBinAddr: 0x3AC3C, symSize: 0x54 } + - { offset: 0x2F2BF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localAddress_IPv6]', symObjAddr: 0xA87C, symBinAddr: 0x3AC90, symSize: 0x250 } + - { offset: 0x2F31B, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv6]_block_invoke', symObjAddr: 0xAACC, symBinAddr: 0x3AEE0, symSize: 0x54 } + - { offset: 0x2F373, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket localAddress_IPv6]_block_invoke_2', symObjAddr: 0xAB20, symBinAddr: 0x3AF34, symSize: 0x54 } + - { offset: 0x2F3AF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localHost_IPv6]', symObjAddr: 0xAB74, symBinAddr: 0x3AF88, symSize: 0x250 } + - { offset: 0x2F40B, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv6]_block_invoke', symObjAddr: 0xADC4, symBinAddr: 0x3B1D8, symSize: 0x54 } + - { offset: 0x2F463, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localHost_IPv6]_block_invoke_2', symObjAddr: 0xAE18, symBinAddr: 0x3B22C, symSize: 0x54 } + - { offset: 0x2F49F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket localPort_IPv6]', symObjAddr: 0xAE6C, symBinAddr: 0x3B280, symSize: 0x1F0 } + - { offset: 0x2F4F9, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv6]_block_invoke', symObjAddr: 0xB05C, symBinAddr: 0x3B470, symSize: 0x50 } + - { offset: 0x2F551, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket localPort_IPv6]_block_invoke_2', symObjAddr: 0xB0AC, symBinAddr: 0x3B4C0, symSize: 0x54 } + - { offset: 0x2F58D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeUpdateCachedConnectedAddressInfo]', symObjAddr: 0xB100, symBinAddr: 0x3B514, symSize: 0x31C } + - { offset: 0x2F656, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedAddress]', symObjAddr: 0xB41C, symBinAddr: 0x3B830, symSize: 0x250 } + - { offset: 0x2F6B2, size: 0x8, addend: 0x0, symName: '___37-[GCDAsyncUdpSocket connectedAddress]_block_invoke', symObjAddr: 0xB66C, symBinAddr: 0x3BA80, symSize: 0x54 } + - { offset: 0x2F70A, size: 0x8, addend: 0x0, symName: '___37-[GCDAsyncUdpSocket connectedAddress]_block_invoke_2', symObjAddr: 0xB6C0, symBinAddr: 0x3BAD4, symSize: 0x54 } + - { offset: 0x2F746, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedHost]', symObjAddr: 0xB714, symBinAddr: 0x3BB28, symSize: 0x250 } + - { offset: 0x2F7A2, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedHost]_block_invoke', symObjAddr: 0xB964, symBinAddr: 0x3BD78, symSize: 0x54 } + - { offset: 0x2F7FA, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedHost]_block_invoke_2', symObjAddr: 0xB9B8, symBinAddr: 0x3BDCC, symSize: 0x54 } + - { offset: 0x2F836, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectedPort]', symObjAddr: 0xBA0C, symBinAddr: 0x3BE20, symSize: 0x1F0 } + - { offset: 0x2F890, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedPort]_block_invoke', symObjAddr: 0xBBFC, symBinAddr: 0x3C010, symSize: 0x50 } + - { offset: 0x2F8E8, size: 0x8, addend: 0x0, symName: '___34-[GCDAsyncUdpSocket connectedPort]_block_invoke_2', symObjAddr: 0xBC4C, symBinAddr: 0x3C060, symSize: 0x54 } + - { offset: 0x2F924, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isConnected]', symObjAddr: 0xBCA0, symBinAddr: 0x3C0B4, symSize: 0x16C } + - { offset: 0x2F97E, size: 0x8, addend: 0x0, symName: '___32-[GCDAsyncUdpSocket isConnected]_block_invoke', symObjAddr: 0xBE0C, symBinAddr: 0x3C220, symSize: 0x44 } + - { offset: 0x2F9D6, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isClosed]', symObjAddr: 0xBE50, symBinAddr: 0x3C264, symSize: 0x170 } + - { offset: 0x2FA30, size: 0x8, addend: 0x0, symName: '___29-[GCDAsyncUdpSocket isClosed]_block_invoke', symObjAddr: 0xBFC0, symBinAddr: 0x3C3D4, symSize: 0x40 } + - { offset: 0x2FA88, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv4]', symObjAddr: 0xC000, symBinAddr: 0x3C414, symSize: 0x170 } + - { offset: 0x2FAE2, size: 0x8, addend: 0x0, symName: '___27-[GCDAsyncUdpSocket isIPv4]_block_invoke', symObjAddr: 0xC170, symBinAddr: 0x3C584, symSize: 0x88 } + - { offset: 0x2FB3A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket isIPv6]', symObjAddr: 0xC1F8, symBinAddr: 0x3C60C, symSize: 0x170 } + - { offset: 0x2FB94, size: 0x8, addend: 0x0, symName: '___27-[GCDAsyncUdpSocket isIPv6]_block_invoke', symObjAddr: 0xC368, symBinAddr: 0x3C77C, symSize: 0x88 } + - { offset: 0x2FBEC, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preBind:]', symObjAddr: 0xC3F0, symBinAddr: 0x3C804, symSize: 0x268 } + - { offset: 0x2FC90, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToPort:error:]', symObjAddr: 0xC658, symBinAddr: 0x3CA6C, symSize: 0x44 } + - { offset: 0x2FCE5, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToPort:interface:error:]', symObjAddr: 0xC69C, symBinAddr: 0x3CAB0, symSize: 0x2C8 } + - { offset: 0x2FD83, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket bindToPort:interface:error:]_block_invoke', symObjAddr: 0xC964, symBinAddr: 0x3CD78, symSize: 0x664 } + - { offset: 0x2FF55, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48r56r, symObjAddr: 0xCFC8, symBinAddr: 0x3D3DC, symSize: 0x90 } + - { offset: 0x2FF79, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48r56r, symObjAddr: 0xD058, symBinAddr: 0x3D46C, symSize: 0x6C } + - { offset: 0x2FF95, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket bindToAddress:error:]', symObjAddr: 0xD0C4, symBinAddr: 0x3D4D8, symSize: 0x2BC } + - { offset: 0x30024, size: 0x8, addend: 0x0, symName: '___41-[GCDAsyncUdpSocket bindToAddress:error:]_block_invoke', symObjAddr: 0xD380, symBinAddr: 0x3D794, symSize: 0x68C } + - { offset: 0x301F3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preConnect:]', symObjAddr: 0xDA0C, symBinAddr: 0x3DE20, symSize: 0x1DC } + - { offset: 0x30281, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectToHost:onPort:error:]', symObjAddr: 0xDBE8, symBinAddr: 0x3DFFC, symSize: 0x2D0 } + - { offset: 0x3031F, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket connectToHost:onPort:error:]_block_invoke', symObjAddr: 0xDEB8, symBinAddr: 0x3E2CC, symSize: 0x300 } + - { offset: 0x303EE, size: 0x8, addend: 0x0, symName: '___48-[GCDAsyncUdpSocket connectToHost:onPort:error:]_block_invoke_2', symObjAddr: 0xE1B8, symBinAddr: 0x3E5CC, symSize: 0xB4 } + - { offset: 0x3045E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectToAddress:error:]', symObjAddr: 0xE26C, symBinAddr: 0x3E680, symSize: 0x2BC } + - { offset: 0x304ED, size: 0x8, addend: 0x0, symName: '___44-[GCDAsyncUdpSocket connectToAddress:error:]_block_invoke', symObjAddr: 0xE528, symBinAddr: 0x3E93C, symSize: 0x274 } + - { offset: 0x305C8, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeConnect]', symObjAddr: 0xE79C, symBinAddr: 0x3EBB0, symSize: 0x368 } + - { offset: 0x3066A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectWithAddress4:error:]', symObjAddr: 0xEB04, symBinAddr: 0x3EF18, symSize: 0x1BC } + - { offset: 0x306CE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket connectWithAddress6:error:]', symObjAddr: 0xECC0, symBinAddr: 0x3F0D4, symSize: 0x1BC } + - { offset: 0x30732, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket preJoin:]', symObjAddr: 0xEE7C, symBinAddr: 0x3F290, symSize: 0x198 } + - { offset: 0x307A2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket joinMulticastGroup:error:]', symObjAddr: 0xF014, symBinAddr: 0x3F428, symSize: 0x80 } + - { offset: 0x307F7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket joinMulticastGroup:onInterface:error:]', symObjAddr: 0xF094, symBinAddr: 0x3F4A8, symSize: 0xA8 } + - { offset: 0x3085B, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket leaveMulticastGroup:error:]', symObjAddr: 0xF13C, symBinAddr: 0x3F550, symSize: 0x80 } + - { offset: 0x308B0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket leaveMulticastGroup:onInterface:error:]', symObjAddr: 0xF1BC, symBinAddr: 0x3F5D0, symSize: 0xA8 } + - { offset: 0x30914, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket performMulticastRequest:forGroup:onInterface:error:]', symObjAddr: 0xF264, symBinAddr: 0x3F678, symSize: 0x300 } + - { offset: 0x309C1, size: 0x8, addend: 0x0, symName: '___72-[GCDAsyncUdpSocket performMulticastRequest:forGroup:onInterface:error:]_block_invoke', symObjAddr: 0xF564, symBinAddr: 0x3F978, symSize: 0x588 } + - { offset: 0x30B99, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s40s48s56r64r, symObjAddr: 0xFAEC, symBinAddr: 0x3FF00, symSize: 0xA8 } + - { offset: 0x30BBD, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s40s48s56r64r, symObjAddr: 0xFB94, symBinAddr: 0x3FFA8, symSize: 0x7C } + - { offset: 0x30BD9, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendIPv4MulticastOnInterface:error:]', symObjAddr: 0xFC10, symBinAddr: 0x40024, symSize: 0x2A8 } + - { offset: 0x30C68, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendIPv4MulticastOnInterface:error:]_block_invoke', symObjAddr: 0xFEB8, symBinAddr: 0x402CC, symSize: 0x2E8 } + - { offset: 0x30D72, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendIPv6MulticastOnInterface:error:]', symObjAddr: 0x101A0, symBinAddr: 0x405B4, symSize: 0x2A8 } + - { offset: 0x30E01, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendIPv6MulticastOnInterface:error:]_block_invoke', symObjAddr: 0x10448, symBinAddr: 0x4085C, symSize: 0x2D8 } + - { offset: 0x30EFB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableReusePort:error:]', symObjAddr: 0x10720, symBinAddr: 0x40B34, symSize: 0x260 } + - { offset: 0x30F8A, size: 0x8, addend: 0x0, symName: '___43-[GCDAsyncUdpSocket enableReusePort:error:]_block_invoke', symObjAddr: 0x10980, symBinAddr: 0x40D94, symSize: 0x284 } + - { offset: 0x31063, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableBroadcast:error:]', symObjAddr: 0x10C04, symBinAddr: 0x41018, symSize: 0x260 } + - { offset: 0x310F2, size: 0x8, addend: 0x0, symName: '___43-[GCDAsyncUdpSocket enableBroadcast:error:]_block_invoke', symObjAddr: 0x10E64, symBinAddr: 0x41278, symSize: 0x1D4 } + - { offset: 0x311A0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:withTag:]', symObjAddr: 0x11038, symBinAddr: 0x4144C, symSize: 0x74 } + - { offset: 0x311F1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:withTimeout:tag:]', symObjAddr: 0x110AC, symBinAddr: 0x414C0, symSize: 0x180 } + - { offset: 0x31260, size: 0x8, addend: 0x0, symName: '___46-[GCDAsyncUdpSocket sendData:withTimeout:tag:]_block_invoke', symObjAddr: 0x1122C, symBinAddr: 0x41640, symSize: 0x64 } + - { offset: 0x312B2, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]', symObjAddr: 0x11290, symBinAddr: 0x416A4, symSize: 0x2A0 } + - { offset: 0x31341, size: 0x8, addend: 0x0, symName: '___58-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]_block_invoke', symObjAddr: 0x11530, symBinAddr: 0x41944, symSize: 0xC8 } + - { offset: 0x313B1, size: 0x8, addend: 0x0, symName: '___58-[GCDAsyncUdpSocket sendData:toHost:port:withTimeout:tag:]_block_invoke_2', symObjAddr: 0x115F8, symBinAddr: 0x41A0C, symSize: 0x64 } + - { offset: 0x31403, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket sendData:toAddress:withTimeout:tag:]', symObjAddr: 0x1165C, symBinAddr: 0x41A70, symSize: 0x1D0 } + - { offset: 0x31481, size: 0x8, addend: 0x0, symName: '___56-[GCDAsyncUdpSocket sendData:toAddress:withTimeout:tag:]_block_invoke', symObjAddr: 0x1182C, symBinAddr: 0x41C40, symSize: 0x64 } + - { offset: 0x314D3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setSendFilter:withQueue:]', symObjAddr: 0x11890, symBinAddr: 0x41CA4, symSize: 0x90 } + - { offset: 0x31524, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setSendFilter:withQueue:isAsynchronous:]', symObjAddr: 0x11920, symBinAddr: 0x41D34, symSize: 0x27C } + - { offset: 0x315B1, size: 0x8, addend: 0x0, symName: '___60-[GCDAsyncUdpSocket setSendFilter:withQueue:isAsynchronous:]_block_invoke', symObjAddr: 0x11B9C, symBinAddr: 0x41FB0, symSize: 0x80 } + - { offset: 0x31627, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket maybeDequeueSend]', symObjAddr: 0x11C1C, symBinAddr: 0x42030, symSize: 0x284 } + - { offset: 0x3166F, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doPreSend]', symObjAddr: 0x11EA0, symBinAddr: 0x422B4, symSize: 0x6A4 } + - { offset: 0x31749, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke', symObjAddr: 0x12544, symBinAddr: 0x42958, symSize: 0x150 } + - { offset: 0x317B8, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke_2', symObjAddr: 0x12694, symBinAddr: 0x42AA8, symSize: 0xCC } + - { offset: 0x3181C, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doPreSend]_block_invoke.265', symObjAddr: 0x12760, symBinAddr: 0x42B74, symSize: 0x8C } + - { offset: 0x31874, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doSend]', symObjAddr: 0x127EC, symBinAddr: 0x42C00, symSize: 0x3B0 } + - { offset: 0x3194A, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket endCurrentSend]', symObjAddr: 0x12B9C, symBinAddr: 0x42FB0, symSize: 0x64 } + - { offset: 0x3197D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doSendTimeout]', symObjAddr: 0x12C00, symBinAddr: 0x43014, symSize: 0x90 } + - { offset: 0x319B0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setupSendTimerWithTimeout:]', symObjAddr: 0x12C90, symBinAddr: 0x430A4, symSize: 0x224 } + - { offset: 0x31A01, size: 0x8, addend: 0x0, symName: '___47-[GCDAsyncUdpSocket setupSendTimerWithTimeout:]_block_invoke', symObjAddr: 0x12EB4, symBinAddr: 0x432C8, symSize: 0x50 } + - { offset: 0x31A41, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket receiveOnce:]', symObjAddr: 0x12F04, symBinAddr: 0x43318, symSize: 0x264 } + - { offset: 0x31AC1, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket receiveOnce:]_block_invoke', symObjAddr: 0x13168, symBinAddr: 0x4357C, symSize: 0x198 } + - { offset: 0x31B4E, size: 0x8, addend: 0x0, symName: '___33-[GCDAsyncUdpSocket receiveOnce:]_block_invoke_2', symObjAddr: 0x13300, symBinAddr: 0x43714, symSize: 0x50 } + - { offset: 0x31B8E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket beginReceiving:]', symObjAddr: 0x13350, symBinAddr: 0x43764, symSize: 0x264 } + - { offset: 0x31C0E, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket beginReceiving:]_block_invoke', symObjAddr: 0x135B4, symBinAddr: 0x439C8, symSize: 0x198 } + - { offset: 0x31C9B, size: 0x8, addend: 0x0, symName: '___36-[GCDAsyncUdpSocket beginReceiving:]_block_invoke_2', symObjAddr: 0x1374C, symBinAddr: 0x43B60, symSize: 0x50 } + - { offset: 0x31CDB, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket pauseReceiving]', symObjAddr: 0x1379C, symBinAddr: 0x43BB0, symSize: 0xF4 } + - { offset: 0x31D1D, size: 0x8, addend: 0x0, symName: '___35-[GCDAsyncUdpSocket pauseReceiving]_block_invoke', symObjAddr: 0x13890, symBinAddr: 0x43CA4, symSize: 0xA4 } + - { offset: 0x31D5D, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setReceiveFilter:withQueue:]', symObjAddr: 0x13934, symBinAddr: 0x43D48, symSize: 0x90 } + - { offset: 0x31DAE, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket setReceiveFilter:withQueue:isAsynchronous:]', symObjAddr: 0x139C4, symBinAddr: 0x43DD8, symSize: 0x27C } + - { offset: 0x31E3B, size: 0x8, addend: 0x0, symName: '___63-[GCDAsyncUdpSocket setReceiveFilter:withQueue:isAsynchronous:]_block_invoke', symObjAddr: 0x13C40, symBinAddr: 0x44054, symSize: 0x80 } + - { offset: 0x31EB1, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doReceive]', symObjAddr: 0x13CC0, symBinAddr: 0x440D4, symSize: 0xEB4 } + - { offset: 0x32054, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke', symObjAddr: 0x14B74, symBinAddr: 0x44F88, symSize: 0x1B4 } + - { offset: 0x320E8, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke_2', symObjAddr: 0x14D28, symBinAddr: 0x4513C, symSize: 0x108 } + - { offset: 0x3217C, size: 0x8, addend: 0x0, symName: '___30-[GCDAsyncUdpSocket doReceive]_block_invoke.277', symObjAddr: 0x14E30, symBinAddr: 0x45244, symSize: 0xA0 } + - { offset: 0x32210, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket doReceiveEOF]', symObjAddr: 0x14ED0, symBinAddr: 0x452E4, symSize: 0x64 } + - { offset: 0x32243, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeWithError:]', symObjAddr: 0x14F34, symBinAddr: 0x45348, symSize: 0x15C } + - { offset: 0x32294, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket close]', symObjAddr: 0x15090, symBinAddr: 0x454A4, symSize: 0xF4 } + - { offset: 0x322D6, size: 0x8, addend: 0x0, symName: '___26-[GCDAsyncUdpSocket close]_block_invoke', symObjAddr: 0x15184, symBinAddr: 0x45598, symSize: 0x54 } + - { offset: 0x32316, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeAfterSending]', symObjAddr: 0x151D8, symBinAddr: 0x455EC, symSize: 0xF4 } + - { offset: 0x32358, size: 0x8, addend: 0x0, symName: '___38-[GCDAsyncUdpSocket closeAfterSending]_block_invoke', symObjAddr: 0x152CC, symBinAddr: 0x456E0, symSize: 0x98 } + - { offset: 0x32398, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket ignore:]', symObjAddr: 0x15364, symBinAddr: 0x45778, symSize: 0x50 } + - { offset: 0x3244A, size: 0x8, addend: 0x0, symName: '___48+[GCDAsyncUdpSocket startListenerThreadIfNeeded]_block_invoke', symObjAddr: 0x15478, symBinAddr: 0x4588C, symSize: 0x84 } + - { offset: 0x3248A, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket listenerThread:]', symObjAddr: 0x154FC, symBinAddr: 0x45910, symSize: 0x13C } + - { offset: 0x324CC, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket addStreamListener:]', symObjAddr: 0x15638, symBinAddr: 0x45A4C, symSize: 0x1B0 } + - { offset: 0x3251D, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket removeStreamListener:]', symObjAddr: 0x157E8, symBinAddr: 0x45BFC, symSize: 0x1B0 } + - { offset: 0x3256E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket createReadAndWriteStreams:]', symObjAddr: 0x15998, symBinAddr: 0x45DAC, symSize: 0x43C } + - { offset: 0x325D3, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket registerForStreamCallbacks:]', symObjAddr: 0x15DD4, symBinAddr: 0x461E8, symSize: 0x504 } + - { offset: 0x326AE, size: 0x8, addend: 0x0, symName: _CFReadStreamCallback, symObjAddr: 0x162D8, symBinAddr: 0x466EC, symSize: 0x1E4 } + - { offset: 0x3272C, size: 0x8, addend: 0x0, symName: _CFWriteStreamCallback, symObjAddr: 0x164BC, symBinAddr: 0x468D0, symSize: 0x1E4 } + - { offset: 0x327AA, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket addStreamsToRunLoop:]', symObjAddr: 0x166A0, symBinAddr: 0x46AB4, symSize: 0x1D0 } + - { offset: 0x327F0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket openStreams:]', symObjAddr: 0x16870, symBinAddr: 0x46C84, symSize: 0x30C } + - { offset: 0x328AD, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket removeStreamsFromRunLoop]', symObjAddr: 0x16B7C, symBinAddr: 0x46F90, symSize: 0xEC } + - { offset: 0x328E0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket closeReadAndWriteStreams]', symObjAddr: 0x16C68, symBinAddr: 0x4707C, symSize: 0x154 } + - { offset: 0x32913, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket applicationWillEnterForeground:]', symObjAddr: 0x16DBC, symBinAddr: 0x471D0, symSize: 0x114 } + - { offset: 0x32964, size: 0x8, addend: 0x0, symName: '___52-[GCDAsyncUdpSocket applicationWillEnterForeground:]_block_invoke', symObjAddr: 0x16ED0, symBinAddr: 0x472E4, symSize: 0x60 } + - { offset: 0x329A4, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket markSocketQueueTargetQueue:]', symObjAddr: 0x16F30, symBinAddr: 0x47344, symSize: 0x70 } + - { offset: 0x329F5, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket unmarkSocketQueueTargetQueue:]', symObjAddr: 0x16FA0, symBinAddr: 0x473B4, symSize: 0x68 } + - { offset: 0x32A37, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket performBlock:]', symObjAddr: 0x17008, symBinAddr: 0x4741C, symSize: 0x80 } + - { offset: 0x32A79, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socketFD]', symObjAddr: 0x17088, symBinAddr: 0x4749C, symSize: 0x7C } + - { offset: 0x32AB0, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socket4FD]', symObjAddr: 0x17104, symBinAddr: 0x47518, symSize: 0x58 } + - { offset: 0x32AE7, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket socket6FD]', symObjAddr: 0x1715C, symBinAddr: 0x47570, symSize: 0x58 } + - { offset: 0x32B1E, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket readStream]', symObjAddr: 0x171B4, symBinAddr: 0x475C8, symSize: 0xE8 } + - { offset: 0x32B64, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket writeStream]', symObjAddr: 0x1729C, symBinAddr: 0x476B0, symSize: 0xE8 } + - { offset: 0x32BAA, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket enableBackgroundingOnSockets]', symObjAddr: 0x17384, symBinAddr: 0x47798, symSize: 0x68 } + - { offset: 0x32BE1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromSockaddr4:]', symObjAddr: 0x173EC, symBinAddr: 0x47800, symSize: 0xA0 } + - { offset: 0x32C36, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromSockaddr6:]', symObjAddr: 0x1748C, symBinAddr: 0x478A0, symSize: 0xA0 } + - { offset: 0x32C8B, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromSockaddr4:]', symObjAddr: 0x1752C, symBinAddr: 0x47940, symSize: 0x44 } + - { offset: 0x32CD1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromSockaddr6:]', symObjAddr: 0x17570, symBinAddr: 0x47984, symSize: 0x44 } + - { offset: 0x32D17, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket hostFromAddress:]', symObjAddr: 0x175B4, symBinAddr: 0x479C8, symSize: 0xC4 } + - { offset: 0x32D6C, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket portFromAddress:]', symObjAddr: 0x17678, symBinAddr: 0x47A8C, symSize: 0x7C } + - { offset: 0x32DC1, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket familyFromAddress:]', symObjAddr: 0x176F4, symBinAddr: 0x47B08, symSize: 0x7C } + - { offset: 0x32E16, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket isIPv4Address:]', symObjAddr: 0x17770, symBinAddr: 0x47B84, symSize: 0x84 } + - { offset: 0x32E6B, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket isIPv6Address:]', symObjAddr: 0x177F4, symBinAddr: 0x47C08, symSize: 0x84 } + - { offset: 0x32EC0, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket getHost:port:fromAddress:]', symObjAddr: 0x17878, symBinAddr: 0x47C8C, symSize: 0x80 } + - { offset: 0x32F24, size: 0x8, addend: 0x0, symName: '+[GCDAsyncUdpSocket getHost:port:family:fromAddress:]', symObjAddr: 0x178F8, symBinAddr: 0x47D0C, symSize: 0x298 } + - { offset: 0x32FEF, size: 0x8, addend: 0x0, symName: '-[GCDAsyncUdpSocket .cxx_destruct]', symObjAddr: 0x17B90, symBinAddr: 0x47FA4, symSize: 0x178 } + - { offset: 0x33022, size: 0x8, addend: 0x0, symName: ___CFReadStreamCallback_block_invoke, symObjAddr: 0x17D08, symBinAddr: 0x4811C, symSize: 0xA0 } + - { offset: 0x33082, size: 0x8, addend: 0x0, symName: ___CFWriteStreamCallback_block_invoke, symObjAddr: 0x17DA8, symBinAddr: 0x481BC, symSize: 0xA0 } +... diff --git a/.theos/obj/debug/arm64e/OhNo.dylib b/.theos/obj/debug/arm64e/OhNo.dylib new file mode 100755 index 0000000..77f4e9d Binary files /dev/null and b/.theos/obj/debug/arm64e/OhNo.dylib differ diff --git a/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Info.plist b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Info.plist new file mode 100644 index 0000000..cba9de5 --- /dev/null +++ b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.OhNo.dylib + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib new file mode 100644 index 0000000..4f084cb Binary files /dev/null and b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/DWARF/OhNo.dylib differ diff --git a/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/Relocations/arm64e/OhNo.dylib.yml b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/Relocations/arm64e/OhNo.dylib.yml new file mode 100644 index 0000000..81c4eeb --- /dev/null +++ b/.theos/obj/debug/arm64e/OhNo.dylib.dSYM/Contents/Resources/Relocations/arm64e/OhNo.dylib.yml @@ -0,0 +1,180 @@ +--- +triple: 'arm64e-apple-darwin' +binary-path: '/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/OhNo.dylib' +relocations: + - { offset: 0x7D, size: 0x8, addend: 0x0, symName: _settings, symBinAddr: 0x145F0, symSize: 0x0 } + - { offset: 0xF0, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$ATTrackingManager$trackingAuthorizationStatus', symObjAddr: 0x25D68, symBinAddr: 0x14450, symSize: 0x0 } + - { offset: 0x132, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$ASIdentifierManager$advertisingIdentifier', symObjAddr: 0x25D70, symBinAddr: 0x14458, symSize: 0x0 } + - { offset: 0x1B0, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled', symObjAddr: 0x25D78, symBinAddr: 0x14460, symSize: 0x0 } + - { offset: 0x1EC, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$identifierForVendor', symObjAddr: 0x25D80, symBinAddr: 0x14468, symSize: 0x0 } + - { offset: 0x3C4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$name', symObjAddr: 0x25D88, symBinAddr: 0x14470, symSize: 0x0 } + - { offset: 0x3EE, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$model', symObjAddr: 0x25D90, symBinAddr: 0x14478, symSize: 0x0 } + - { offset: 0x403, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$localizedModel', symObjAddr: 0x25D98, symBinAddr: 0x14480, symSize: 0x0 } + - { offset: 0x418, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$systemName', symObjAddr: 0x25DA0, symBinAddr: 0x14488, symSize: 0x0 } + - { offset: 0x42D, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$systemVersion', symObjAddr: 0x25DA8, symBinAddr: 0x14490, symSize: 0x0 } + - { offset: 0x442, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$batteryState', symObjAddr: 0x25DB0, symBinAddr: 0x14498, symSize: 0x0 } + - { offset: 0x46C, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$batteryLevel', symObjAddr: 0x25DB8, symBinAddr: 0x144A0, symSize: 0x0 } + - { offset: 0x496, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIDevice$orientation', symObjAddr: 0x25DC0, symBinAddr: 0x144A8, symSize: 0x0 } + - { offset: 0x4C0, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$systemUptime', symObjAddr: 0x25DC8, symBinAddr: 0x144B0, symSize: 0x0 } + - { offset: 0x671, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$physicalMemory', symObjAddr: 0x25DD0, symBinAddr: 0x144B8, symSize: 0x0 } + - { offset: 0x69B, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$processorCount', symObjAddr: 0x25DD8, symBinAddr: 0x144C0, symSize: 0x0 } + - { offset: 0x6C5, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSProcessInfo$operatingSystemVersion', symObjAddr: 0x25DE0, symBinAddr: 0x144C8, symSize: 0x0 } + - { offset: 0x6EF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIWindow$safeAreaInsets', symObjAddr: 0x25DE8, symBinAddr: 0x144D0, symSize: 0x0 } + - { offset: 0x2261, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$brightness', symObjAddr: 0x25DF0, symBinAddr: 0x144D8, symSize: 0x0 } + - { offset: 0x2290, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$bounds', symObjAddr: 0x25DF8, symBinAddr: 0x144E0, symSize: 0x0 } + - { offset: 0x22BA, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$scale', symObjAddr: 0x25E00, symBinAddr: 0x144E8, symSize: 0x0 } + - { offset: 0x22CF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$nativeBounds', symObjAddr: 0x25E08, symBinAddr: 0x144F0, symSize: 0x0 } + - { offset: 0x22E4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$isCaptured', symObjAddr: 0x25E10, symBinAddr: 0x144F8, symSize: 0x0 } + - { offset: 0x230E, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreen$mirroredScreen', symObjAddr: 0x25E18, symBinAddr: 0x14500, symSize: 0x0 } + - { offset: 0x2338, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$AVAudioSession$outputVolume', symObjAddr: 0x25E20, symBinAddr: 0x14508, symSize: 0x0 } + - { offset: 0x2372, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIScreenMode$size', symObjAddr: 0x25E28, symBinAddr: 0x14510, symSize: 0x0 } + - { offset: 0x23A1, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSFileManager$attributesOfFileSystemForPath$error$', symObjAddr: 0x25E30, symBinAddr: 0x14518, symSize: 0x0 } + - { offset: 0x24CB, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSFileManager$fileExistsAtPath$', symObjAddr: 0x25E38, symBinAddr: 0x14520, symSize: 0x0 } + - { offset: 0x24FA, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$preferredLanguages', symObjAddr: 0x25E40, symBinAddr: 0x14528, symSize: 0x0 } + - { offset: 0x2524, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$currentLocale', symObjAddr: 0x25E48, symBinAddr: 0x14530, symSize: 0x0 } + - { offset: 0x2563, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSLocale$systemLocale', symObjAddr: 0x25E50, symBinAddr: 0x14538, symSize: 0x0 } + - { offset: 0x2578, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$localTimeZone', symObjAddr: 0x25E58, symBinAddr: 0x14540, symSize: 0x0 } + - { offset: 0x25D1, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$systemTimeZone', symObjAddr: 0x25E60, symBinAddr: 0x14548, symSize: 0x0 } + - { offset: 0x25E6, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSTimeZone$defaultTimeZone', symObjAddr: 0x25E68, symBinAddr: 0x14550, symSize: 0x0 } + - { offset: 0x25FB, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIStatusBarManager$statusBarFrame', symObjAddr: 0x25E70, symBinAddr: 0x14558, symSize: 0x0 } + - { offset: 0x2667, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSMutableURLRequest$initWithURL$', symObjAddr: 0x25E78, symBinAddr: 0x14560, symSize: 0x0 } + - { offset: 0x2901, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$', symObjAddr: 0x25E80, symBinAddr: 0x14568, symSize: 0x0 } + - { offset: 0x2936, size: 0x8, addend: 0x0, symName: '__logos_meta_orig$ohno$NSURLSession$sessionWithConfiguration$', symObjAddr: 0x25E88, symBinAddr: 0x14570, symSize: 0x0 } + - { offset: 0x3057, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$NSURLSession$dataTaskWithRequest$completionHandler$', symObjAddr: 0x25E90, symBinAddr: 0x14578, symSize: 0x0 } + - { offset: 0x32C8, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$evaluateJavaScript$completionHandler$', symObjAddr: 0x25E98, symBinAddr: 0x14580, symSize: 0x0 } + - { offset: 0x4DCF, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$setCustomUserAgent$', symObjAddr: 0x25EA0, symBinAddr: 0x14588, symSize: 0x0 } + - { offset: 0x4DFA, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$WKWebView$customUserAgent', symObjAddr: 0x25EA8, symBinAddr: 0x14590, symSize: 0x0 } + - { offset: 0x4E24, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology', symObjAddr: 0x25EB0, symBinAddr: 0x14598, symSize: 0x0 } + - { offset: 0x4FD4, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders', symObjAddr: 0x25EB8, symBinAddr: 0x145A0, symSize: 0x0 } + - { offset: 0x4FE9, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$', symObjAddr: 0x25EC0, symBinAddr: 0x145A8, symSize: 0x0 } + - { offset: 0x5533, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$uname', symObjAddr: 0x25EC8, symBinAddr: 0x145B0, symSize: 0x0 } + - { offset: 0x55B5, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$sysctl', symObjAddr: 0x25ED0, symBinAddr: 0x145B8, symSize: 0x0 } + - { offset: 0x560E, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$sysctlbyname', symObjAddr: 0x25ED8, symBinAddr: 0x145C0, symSize: 0x0 } + - { offset: 0x5648, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$clock_gettime', symObjAddr: 0x25EE0, symBinAddr: 0x145C8, symSize: 0x0 } + - { offset: 0x56E8, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$getifaddrs', symObjAddr: 0x25EE8, symBinAddr: 0x145D0, symSize: 0x0 } + - { offset: 0x57C6, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$SCNetworkReachabilityGetFlags', symObjAddr: 0x25EF0, symBinAddr: 0x145D8, symSize: 0x0 } + - { offset: 0x5876, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIAccessibilityIsClosedCaptioningEnabled', symObjAddr: 0x25EF8, symBinAddr: 0x145E0, symSize: 0x0 } + - { offset: 0x5898, size: 0x8, addend: 0x0, symName: '__logos_orig$ohno$UIAccessibilityIsMonoAudioEnabled', symObjAddr: 0x25F00, symBinAddr: 0x145E8, symSize: 0x0 } + - { offset: 0x5A66, size: 0x8, addend: 0x0, symName: _reloadConfig, symObjAddr: 0x0, symBinAddr: 0x4000, symSize: 0x1E4 } + - { offset: 0x5AB2, size: 0x8, addend: 0x0, symName: _str2uuid, symObjAddr: 0x1E4, symBinAddr: 0x41E4, symSize: 0x78 } + - { offset: 0x5ADA, size: 0x8, addend: 0x0, symName: _str2int, symObjAddr: 0x25C, symBinAddr: 0x425C, symSize: 0x5C } + - { offset: 0x5B02, size: 0x8, addend: 0x0, symName: _str2float, symObjAddr: 0x2B8, symBinAddr: 0x42B8, symSize: 0x58 } + - { offset: 0x5B2A, size: 0x8, addend: 0x0, symName: _str2double, symObjAddr: 0x310, symBinAddr: 0x4310, symSize: 0x58 } + - { offset: 0x5B52, size: 0x8, addend: 0x0, symName: _str2ull, symObjAddr: 0x368, symBinAddr: 0x4368, symSize: 0x5C } + - { offset: 0x5B7A, size: 0x8, addend: 0x0, symName: _tryGetVal, symObjAddr: 0x3C4, symBinAddr: 0x43C4, symSize: 0x198 } + - { offset: 0x5BD4, size: 0x8, addend: 0x0, symName: _str2chars, symObjAddr: 0x55C, symBinAddr: 0x455C, symSize: 0x70 } + - { offset: 0x5C0A, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData rotationRate]', symObjAddr: 0x5CC, symBinAddr: 0x45CC, symSize: 0x48 } + - { offset: 0x5C41, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData customRotationRate]', symObjAddr: 0x614, symBinAddr: 0x4614, symSize: 0x40 } + - { offset: 0x5C78, size: 0x8, addend: 0x0, symName: '-[CustomCMGyroData setCustomRotationRate:]', symObjAddr: 0x654, symBinAddr: 0x4654, symSize: 0x40 } + - { offset: 0x5CB7, size: 0x8, addend: 0x0, symName: __logosLocalCtor_d7de9a12, symObjAddr: 0x694, symBinAddr: 0x4694, symSize: 0xFBC } + - { offset: 0x5F5A, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$ATTrackingManager$trackingAuthorizationStatus', symObjAddr: 0x1650, symBinAddr: 0x5650, symSize: 0x12C } + - { offset: 0x5FA3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$ASIdentifierManager$advertisingIdentifier', symObjAddr: 0x177C, symBinAddr: 0x577C, symSize: 0x198 } + - { offset: 0x5FEC, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled', symObjAddr: 0x1914, symBinAddr: 0x5914, symSize: 0x104 } + - { offset: 0x6035, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$identifierForVendor', symObjAddr: 0x1A18, symBinAddr: 0x5A18, symSize: 0x198 } + - { offset: 0x607E, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$name', symObjAddr: 0x1BB0, symBinAddr: 0x5BB0, symSize: 0x198 } + - { offset: 0x60C7, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$model', symObjAddr: 0x1D48, symBinAddr: 0x5D48, symSize: 0x38 } + - { offset: 0x60FD, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$localizedModel', symObjAddr: 0x1D80, symBinAddr: 0x5D80, symSize: 0x38 } + - { offset: 0x6133, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$systemName', symObjAddr: 0x1DB8, symBinAddr: 0x5DB8, symSize: 0x38 } + - { offset: 0x6169, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$systemVersion', symObjAddr: 0x1DF0, symBinAddr: 0x5DF0, symSize: 0x198 } + - { offset: 0x61B2, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$batteryState', symObjAddr: 0x1F88, symBinAddr: 0x5F88, symSize: 0x10C } + - { offset: 0x61FB, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$batteryLevel', symObjAddr: 0x2094, symBinAddr: 0x6094, symSize: 0x10C } + - { offset: 0x6244, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIDevice$orientation', symObjAddr: 0x21A0, symBinAddr: 0x61A0, symSize: 0x18 } + - { offset: 0x627A, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$systemUptime', symObjAddr: 0x21B8, symBinAddr: 0x61B8, symSize: 0x10C } + - { offset: 0x62C3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$physicalMemory', symObjAddr: 0x22C4, symBinAddr: 0x62C4, symSize: 0x12C } + - { offset: 0x630C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$processorCount', symObjAddr: 0x23F0, symBinAddr: 0x63F0, symSize: 0x10C } + - { offset: 0x6355, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSProcessInfo$operatingSystemVersion', symObjAddr: 0x24FC, symBinAddr: 0x64FC, symSize: 0x644 } + - { offset: 0x63DE, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIWindow$safeAreaInsets', symObjAddr: 0x2B40, symBinAddr: 0x6B40, symSize: 0x230 } + - { offset: 0x642C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$brightness', symObjAddr: 0x2D70, symBinAddr: 0x6D70, symSize: 0x10C } + - { offset: 0x6479, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$bounds', symObjAddr: 0x2E7C, symBinAddr: 0x6E7C, symSize: 0x148 } + - { offset: 0x64C7, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$scale', symObjAddr: 0x2FC4, symBinAddr: 0x6FC4, symSize: 0x10C } + - { offset: 0x6514, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$nativeBounds', symObjAddr: 0x30D0, symBinAddr: 0x70D0, symSize: 0x148 } + - { offset: 0x6562, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$isCaptured', symObjAddr: 0x3218, symBinAddr: 0x7218, symSize: 0x1C } + - { offset: 0x659B, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreen$mirroredScreen', symObjAddr: 0x3234, symBinAddr: 0x7234, symSize: 0x18 } + - { offset: 0x65D4, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$AVAudioSession$outputVolume', symObjAddr: 0x324C, symBinAddr: 0x724C, symSize: 0x10C } + - { offset: 0x6621, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIScreenMode$size', symObjAddr: 0x3358, symBinAddr: 0x7358, symSize: 0x120 } + - { offset: 0x666F, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$', symObjAddr: 0x3478, symBinAddr: 0x7478, symSize: 0x28C } + - { offset: 0x66F3, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSFileManager$fileExistsAtPath$', symObjAddr: 0x3704, symBinAddr: 0x7704, symSize: 0x3BC } + - { offset: 0x675E, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$preferredLanguages', symObjAddr: 0x3AC0, symBinAddr: 0x7AC0, symSize: 0x8C } + - { offset: 0x6797, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$currentLocale', symObjAddr: 0x3B4C, symBinAddr: 0x7B4C, symSize: 0x178 } + - { offset: 0x67E4, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSLocale$systemLocale', symObjAddr: 0x3CC4, symBinAddr: 0x7CC4, symSize: 0x178 } + - { offset: 0x6831, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$localTimeZone', symObjAddr: 0x3E3C, symBinAddr: 0x7E3C, symSize: 0x178 } + - { offset: 0x687E, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$systemTimeZone', symObjAddr: 0x3FB4, symBinAddr: 0x7FB4, symSize: 0x178 } + - { offset: 0x68CB, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSTimeZone$defaultTimeZone', symObjAddr: 0x412C, symBinAddr: 0x812C, symSize: 0x178 } + - { offset: 0x6918, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$UIStatusBarManager$statusBarFrame', symObjAddr: 0x42A4, symBinAddr: 0x82A4, symSize: 0x148 } + - { offset: 0x6966, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSMutableURLRequest$initWithURL$', symObjAddr: 0x43EC, symBinAddr: 0x83EC, symSize: 0x150 } + - { offset: 0x69AE, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$', symObjAddr: 0x453C, symBinAddr: 0x853C, symSize: 0x1BC } + - { offset: 0x6A16, size: 0x8, addend: 0x0, symName: '__logos_meta_method$ohno$NSURLSession$sessionWithConfiguration$', symObjAddr: 0x46F8, symBinAddr: 0x86F8, symSize: 0x120 } + - { offset: 0x6A5E, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$NSURLSession$dataTaskWithRequest$completionHandler$', symObjAddr: 0x4818, symBinAddr: 0x8818, symSize: 0x160 } + - { offset: 0x6AC4, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$evaluateJavaScript$completionHandler$', symObjAddr: 0x4978, symBinAddr: 0x8978, symSize: 0x21C } + - { offset: 0x6B2C, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$setCustomUserAgent$', symObjAddr: 0x4B94, symBinAddr: 0x8B94, symSize: 0x170 } + - { offset: 0x6B85, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$WKWebView$customUserAgent', symObjAddr: 0x4D04, symBinAddr: 0x8D04, symSize: 0x16C } + - { offset: 0x6BD2, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology', symObjAddr: 0x4E70, symBinAddr: 0x8E70, symSize: 0x194 } + - { offset: 0x6C29, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders', symObjAddr: 0x5004, symBinAddr: 0x9004, symSize: 0x194 } + - { offset: 0x6C80, size: 0x8, addend: 0x0, symName: '__logos_method$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$', symObjAddr: 0x5198, symBinAddr: 0x9198, symSize: 0x16C } + - { offset: 0x6CE2, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$uname', symObjAddr: 0x5304, symBinAddr: 0x9304, symSize: 0xA4 } + - { offset: 0x6D1B, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$sysctl', symObjAddr: 0x53A8, symBinAddr: 0x93A8, symSize: 0x120 } + - { offset: 0x6DBC, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$sysctlbyname', symObjAddr: 0x54C8, symBinAddr: 0x94C8, symSize: 0x43C } + - { offset: 0x6EA4, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$clock_gettime', symObjAddr: 0x5904, symBinAddr: 0x9904, symSize: 0x60 } + - { offset: 0x6EEC, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$getifaddrs', symObjAddr: 0x5964, symBinAddr: 0x9964, symSize: 0x6C4 } + - { offset: 0x7072, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$SCNetworkReachabilityGetFlags', symObjAddr: 0x6028, symBinAddr: 0xA028, symSize: 0x88 } + - { offset: 0x70BA, size: 0x8, addend: 0x0, symName: __logosLocalDtor_444f8b65, symObjAddr: 0x60B0, symBinAddr: 0xA0B0, symSize: 0x2C } + - { offset: 0x70FE, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$ATTrackingManager$trackingAuthorizationStatus_block_invoke', symObjAddr: 0x60DC, symBinAddr: 0xA0DC, symSize: 0x6C } + - { offset: 0x714B, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32r, symObjAddr: 0x6148, symBinAddr: 0xA148, symSize: 0x3C } + - { offset: 0x716F, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32r, symObjAddr: 0x6184, symBinAddr: 0xA184, symSize: 0x30 } + - { offset: 0x718B, size: 0x8, addend: 0x0, symName: ___Block_byref_object_copy_, symObjAddr: 0x61B4, symBinAddr: 0xA1B4, symSize: 0x58 } + - { offset: 0x71AF, size: 0x8, addend: 0x0, symName: ___Block_byref_object_dispose_, symObjAddr: 0x620C, symBinAddr: 0xA20C, symSize: 0x30 } + - { offset: 0x71CB, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$ASIdentifierManager$advertisingIdentifier_block_invoke', symObjAddr: 0x623C, symBinAddr: 0xA23C, symSize: 0x84 } + - { offset: 0x7218, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$ASIdentifierManager$isAdvertisingTrackingEnabled_block_invoke', symObjAddr: 0x62C0, symBinAddr: 0xA2C0, symSize: 0x88 } + - { offset: 0x7281, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$identifierForVendor_block_invoke', symObjAddr: 0x6348, symBinAddr: 0xA348, symSize: 0x84 } + - { offset: 0x72CE, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$name_block_invoke', symObjAddr: 0x63CC, symBinAddr: 0xA3CC, symSize: 0x68 } + - { offset: 0x731B, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$systemVersion_block_invoke', symObjAddr: 0x6434, symBinAddr: 0xA434, symSize: 0x68 } + - { offset: 0x7368, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$batteryState_block_invoke', symObjAddr: 0x649C, symBinAddr: 0xA49C, symSize: 0x74 } + - { offset: 0x73D1, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIDevice$batteryLevel_block_invoke', symObjAddr: 0x6510, symBinAddr: 0xA510, symSize: 0x68 } + - { offset: 0x741E, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$systemUptime_block_invoke', symObjAddr: 0x6578, symBinAddr: 0xA578, symSize: 0x8C } + - { offset: 0x7487, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$physicalMemory_block_invoke', symObjAddr: 0x6604, symBinAddr: 0xA604, symSize: 0x78 } + - { offset: 0x74F0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$processorCount_block_invoke', symObjAddr: 0x667C, symBinAddr: 0xA67C, symSize: 0x78 } + - { offset: 0x7559, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSProcessInfo$operatingSystemVersion_block_invoke', symObjAddr: 0x66F4, symBinAddr: 0xA6F4, symSize: 0x68 } + - { offset: 0x75A6, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIWindow$safeAreaInsets_block_invoke', symObjAddr: 0x675C, symBinAddr: 0xA75C, symSize: 0x164 } + - { offset: 0x7623, size: 0x8, addend: 0x0, symName: _UIEdgeInsetsMake, symObjAddr: 0x68C0, symBinAddr: 0xA8C0, symSize: 0x4C } + - { offset: 0x7683, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$brightness_block_invoke', symObjAddr: 0x690C, symBinAddr: 0xA90C, symSize: 0x7C } + - { offset: 0x76F1, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$bounds_block_invoke', symObjAddr: 0x6988, symBinAddr: 0xA988, symSize: 0x130 } + - { offset: 0x778D, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$scale_block_invoke', symObjAddr: 0x6AB8, symBinAddr: 0xAAB8, symSize: 0x7C } + - { offset: 0x77FB, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreen$nativeBounds_block_invoke', symObjAddr: 0x6B34, symBinAddr: 0xAB34, symSize: 0x130 } + - { offset: 0x7897, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$AVAudioSession$outputVolume_block_invoke', symObjAddr: 0x6C64, symBinAddr: 0xAC64, symSize: 0x7C } + - { offset: 0x7905, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIScreenMode$size_block_invoke', symObjAddr: 0x6CE0, symBinAddr: 0xACE0, symSize: 0x11C } + - { offset: 0x79A0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$_block_invoke', symObjAddr: 0x6DFC, symBinAddr: 0xADFC, symSize: 0xB4 } + - { offset: 0x7A08, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32s, symObjAddr: 0x6EB0, symBinAddr: 0xAEB0, symSize: 0x3C } + - { offset: 0x7A2C, size: 0x8, addend: 0x0, symName: ___destroy_helper_block_e8_32s, symObjAddr: 0x6EEC, symBinAddr: 0xAEEC, symSize: 0x30 } + - { offset: 0x7A48, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$attributesOfFileSystemForPath$error$_block_invoke.303', symObjAddr: 0x6F1C, symBinAddr: 0xAF1C, symSize: 0xB4 } + - { offset: 0x7AB0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSFileManager$fileExistsAtPath$_block_invoke', symObjAddr: 0x6FD0, symBinAddr: 0xAFD0, symSize: 0xA0 } + - { offset: 0x7B3A, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSLocale$currentLocale_block_invoke', symObjAddr: 0x7070, symBinAddr: 0xB070, symSize: 0xB4 } + - { offset: 0x7BA8, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSLocale$systemLocale_block_invoke', symObjAddr: 0x7124, symBinAddr: 0xB124, symSize: 0xB4 } + - { offset: 0x7C16, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$localTimeZone_block_invoke', symObjAddr: 0x71D8, symBinAddr: 0xB1D8, symSize: 0xB8 } + - { offset: 0x7C84, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$systemTimeZone_block_invoke', symObjAddr: 0x7290, symBinAddr: 0xB290, symSize: 0xB8 } + - { offset: 0x7CF2, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSTimeZone$defaultTimeZone_block_invoke', symObjAddr: 0x7348, symBinAddr: 0xB348, symSize: 0xB8 } + - { offset: 0x7D60, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$UIStatusBarManager$statusBarFrame_block_invoke', symObjAddr: 0x7400, symBinAddr: 0xB400, symSize: 0xE4 } + - { offset: 0x7DEC, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSMutableURLRequest$initWithURL$_block_invoke', symObjAddr: 0x74E4, symBinAddr: 0xB4E4, symSize: 0x6C } + - { offset: 0x7E37, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSMutableURLRequest$setValue$forHTTPHeaderField$_block_invoke', symObjAddr: 0x7550, symBinAddr: 0xB550, symSize: 0x68 } + - { offset: 0x7E88, size: 0x8, addend: 0x0, symName: '____logos_meta_method$ohno$NSURLSession$sessionWithConfiguration$_block_invoke', symObjAddr: 0x75B8, symBinAddr: 0xB5B8, symSize: 0xE0 } + - { offset: 0x7ED3, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$NSURLSession$dataTaskWithRequest$completionHandler$_block_invoke', symObjAddr: 0x7698, symBinAddr: 0xB698, symSize: 0x6C } + - { offset: 0x7F1E, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$evaluateJavaScript$completionHandler$_block_invoke', symObjAddr: 0x7704, symBinAddr: 0xB704, symSize: 0x68 } + - { offset: 0x7F6F, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$setCustomUserAgent$_block_invoke', symObjAddr: 0x776C, symBinAddr: 0xB76C, symSize: 0x68 } + - { offset: 0x7FC0, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$WKWebView$customUserAgent_block_invoke', symObjAddr: 0x77D4, symBinAddr: 0xB7D4, symSize: 0x68 } + - { offset: 0x8011, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CTTelephonyNetworkInfo$serviceCurrentRadioAccessTechnology_block_invoke', symObjAddr: 0x783C, symBinAddr: 0xB83C, symSize: 0x26C } + - { offset: 0x80B9, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CTTelephonyNetworkInfo$serviceSubscriberCellularProviders_block_invoke', symObjAddr: 0x7AA8, symBinAddr: 0xBAA8, symSize: 0x368 } + - { offset: 0x8161, size: 0x8, addend: 0x0, symName: '____logos_method$ohno$CMMotionManager$startGyroUpdatesToQueue$withHandler$_block_invoke', symObjAddr: 0x7E10, symBinAddr: 0xBE10, symSize: 0x164 } + - { offset: 0x8206, size: 0x8, addend: 0x0, symName: ___copy_helper_block_e8_32b, symObjAddr: 0x7F74, symBinAddr: 0xBF74, symSize: 0x3C } + - { offset: 0x822A, size: 0x8, addend: 0x0, symName: _randomRadiansPerSecond, symObjAddr: 0x7FB0, symBinAddr: 0xBFB0, symSize: 0x48 } + - { offset: 0x8254, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$uname_block_invoke', symObjAddr: 0x7FF8, symBinAddr: 0xBFF8, symSize: 0xB4 } + - { offset: 0x82BD, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctl_block_invoke', symObjAddr: 0x80AC, symBinAddr: 0xC0AC, symSize: 0x7C } + - { offset: 0x8325, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctlbyname_block_invoke', symObjAddr: 0x8128, symBinAddr: 0xC128, symSize: 0xC8 } + - { offset: 0x838B, size: 0x8, addend: 0x0, symName: _safe_copy_string, symObjAddr: 0x81F0, symBinAddr: 0xC1F0, symSize: 0xF0 } + - { offset: 0x83F1, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$sysctlbyname_block_invoke_2', symObjAddr: 0x82E0, symBinAddr: 0xC2E0, symSize: 0xC8 } + - { offset: 0x8457, size: 0x8, addend: 0x0, symName: '____logos_function$ohno$getifaddrs_block_invoke', symObjAddr: 0x83A8, symBinAddr: 0xC3A8, symSize: 0x88 } + - { offset: 0x84A8, size: 0x8, addend: 0x0, symName: _modifyInterfaceIP, symObjAddr: 0x8430, symBinAddr: 0xC430, symSize: 0x170 } + - { offset: 0x853B, size: 0x8, addend: 0x0, symName: _createInterface, symObjAddr: 0x85A0, symBinAddr: 0xC5A0, symSize: 0x3F8 } + - { offset: 0x85E4, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$UIAccessibilityIsClosedCaptioningEnabled', symObjAddr: 0x8998, symBinAddr: 0xC998, symSize: 0xC } + - { offset: 0x85FE, size: 0x8, addend: 0x0, symName: '__logos_function$ohno$UIAccessibilityIsMonoAudioEnabled', symObjAddr: 0x89A4, symBinAddr: 0xC9A4, symSize: 0xC } + - { offset: 0x8618, size: 0x8, addend: 0x0, symName: _cleanup, symObjAddr: 0x89B0, symBinAddr: 0xC9B0, symSize: 0x3C } + - { offset: 0x862E, size: 0x8, addend: 0x0, symName: ___GLOBAL_init_65535, symObjAddr: 0x8FD4, symBinAddr: 0xC9EC, symSize: 0x34 } +... diff --git a/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.Td b/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.Td new file mode 100644 index 0000000..1d97618 --- /dev/null +++ b/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.Td @@ -0,0 +1,38 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.o: \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/Tweak.x.m \ + /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBAlertItemsController.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBUserNotificationAlert.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/module.modulemap \ + /Users/mac/theos/vendor/include/SpringBoardUI/SpringBoardUI.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/SBAlertItem.h \ + /Users/mac/theos/vendor/include/SpringBoardUI/_SBAlertController.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBApplication.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBActivationSettings.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBWorkspace.h \ + /Users/mac/theos/vendor/include/SpringBoard/SBApplicationController.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/MySimpleServer.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/FloatingWindow.h \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/XSHttpHelper.h \ + /Users/mac/theos/vendor/include/substrate.h \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h: +/Users/mac/theos/vendor/include/SpringBoard/SBAlertItemsController.h: +/Users/mac/theos/vendor/include/SpringBoard/SBUserNotificationAlert.h: +/Users/mac/theos/vendor/include/SpringBoardUI/module.modulemap: +/Users/mac/theos/vendor/include/SpringBoardUI/SpringBoardUI.h: +/Users/mac/theos/vendor/include/SpringBoardUI/SBAlertItem.h: +/Users/mac/theos/vendor/include/SpringBoardUI/_SBAlertController.h: +/Users/mac/theos/vendor/include/SpringBoard/SBApplication.h: +/Users/mac/theos/vendor/include/SpringBoard/SBActivationSettings.h: +/Users/mac/theos/vendor/include/SpringBoard/SBWorkspace.h: +/Users/mac/theos/vendor/include/SpringBoard/SBApplicationController.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/MySimpleServer.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/FloatingWindow.h: +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/AppRunMan/server/XSHttpHelper.h: +/Users/mac/theos/vendor/include/substrate.h: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h: diff --git a/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.o b/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.o new file mode 100644 index 0000000..64e3b17 Binary files /dev/null and b/.theos/obj/debug/arm64e/Tweak.x.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.Td b/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.Td new file mode 100644 index 0000000..c6b59cf --- /dev/null +++ b/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.Td @@ -0,0 +1,12 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.o: \ + /Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/Tweak.x.m \ + /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h \ + /Users/mac/theos/vendor/include/substrate.h \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap \ + /Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SpringBoard.h: +/Users/mac/theos/vendor/include/substrate.h: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Modules/module.modulemap: +/Users/mac/theos/vendor/lib/CydiaSubstrate.framework/Headers/CydiaSubstrate.h: diff --git a/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.o b/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.o new file mode 100644 index 0000000..da8e104 Binary files /dev/null and b/.theos/obj/debug/arm64e/Tweak.x.b35aa8c2.o differ diff --git a/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.Td new file mode 100644 index 0000000..863b5cc --- /dev/null +++ b/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.Td @@ -0,0 +1,15 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.o: \ + server/FloatingWindow.m /Users/mac/theos/Prefix.pch \ + server/FloatingWindow.h server/XSHttpHelper.h server/XSPhoneConfig.h \ + server/XSPhoneInfo.h server/UIView+Toast.h server/MyEventBus.h \ + server/XSHelper.h server/MyAdTask2.h server/IPhoneHertbeat.h +/Users/mac/theos/Prefix.pch: +server/FloatingWindow.h: +server/XSHttpHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/UIView+Toast.h: +server/MyEventBus.h: +server/XSHelper.h: +server/MyAdTask2.h: +server/IPhoneHertbeat.h: diff --git a/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.o new file mode 100644 index 0000000..1a17b38 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/FloatingWindow.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.Td new file mode 100644 index 0000000..c6c2fb3 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.Td @@ -0,0 +1,5 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.o: \ + server/GCD/GCDAsyncUdpSocket.m /Users/mac/theos/Prefix.pch \ + server/GCD/GCDAsyncUdpSocket.h +/Users/mac/theos/Prefix.pch: +server/GCD/GCDAsyncUdpSocket.h: diff --git a/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.o new file mode 100644 index 0000000..9c1dc88 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/GCD/GCDAsyncUdpSocket.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.Td new file mode 100644 index 0000000..e127c47 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.Td @@ -0,0 +1,47 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.o: \ + server/IPhoneHertbeat.m /Users/mac/theos/Prefix.pch \ + server/IPhoneHertbeat.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSHttpHelper.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/MyAdServer.h server/MyAdTask2.h +/Users/mac/theos/Prefix.pch: +server/IPhoneHertbeat.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSHttpHelper.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/MyAdServer.h: +server/MyAdTask2.h: diff --git a/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.o new file mode 100644 index 0000000..29f1a39 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/IPhoneHertbeat.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.Td new file mode 100644 index 0000000..478311b --- /dev/null +++ b/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.Td @@ -0,0 +1,50 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.o: \ + server/IosSystemCmd.m /Users/mac/theos/Prefix.pch \ + server/IosSystemCmd.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/MyEventBus.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/MyAdTask2.h +/Users/mac/theos/Prefix.pch: +server/IosSystemCmd.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/MyEventBus.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/MyAdTask2.h: diff --git a/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.o new file mode 100644 index 0000000..e38e3b9 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/IosSystemCmd.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.Td new file mode 100644 index 0000000..17088ce --- /dev/null +++ b/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.Td @@ -0,0 +1,10 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.o: \ + server/MyAdServer.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/MyAdServer.h server/XSHttpHelper.h server/XSPhoneConfig.h \ + server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.o new file mode 100644 index 0000000..db2b0e1 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/MyAdServer.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.Td new file mode 100644 index 0000000..4ff4468 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.Td @@ -0,0 +1,48 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.o: \ + server/MyAdTask2.m /Users/mac/theos/Prefix.pch server/IPhoneHertbeat.h \ + server/XSHackIos.h /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSHelper.h server/XSPhoneInfo.h \ + server/XSPhoneConfig.h server/MyAdServer.h server/XSHttpHelper.h \ + server/MyAdTask2.h server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/IPhoneHertbeat.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSHelper.h: +server/XSPhoneInfo.h: +server/XSPhoneConfig.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/MyAdTask2.h: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.o new file mode 100644 index 0000000..ba67d63 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/MyAdTask2.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.Td new file mode 100644 index 0000000..271b69a --- /dev/null +++ b/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.Td @@ -0,0 +1,4 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.o: \ + server/MyEventBus.m /Users/mac/theos/Prefix.pch server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.o new file mode 100644 index 0000000..ab865ab Binary files /dev/null and b/.theos/obj/debug/arm64e/server/MyEventBus.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.Td new file mode 100644 index 0000000..ae54a81 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.Td @@ -0,0 +1,48 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.o: \ + server/MyScriptTask.m /Users/mac/theos/Prefix.pch \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/XSHelper.h server/XSPhoneConfig.h server/XSPhoneInfo.h \ + server/MyEventBus.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h +/Users/mac/theos/Prefix.pch: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSHelper.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: +server/MyEventBus.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: diff --git a/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.o new file mode 100644 index 0000000..e0054c5 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/MyScriptTask.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.Td new file mode 100644 index 0000000..5d4e4bc --- /dev/null +++ b/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.Td @@ -0,0 +1,53 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.o: \ + server/MySimpleServer.m /Users/mac/theos/Prefix.pch \ + server/MyScriptTask.h server/MyAdServer.h server/XSHttpHelper.h \ + server/XSHelper.h server/IPhoneHertbeat.h server/MySimpleServer.h \ + server/IosSystemCmd.h server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSHackIos.h server/MyAdTask2.h \ + server/XUDPServer.h server/CocoaAsyncSocket.h \ + server/GCD/GCDAsyncUdpSocket.h +/Users/mac/theos/Prefix.pch: +server/MyScriptTask.h: +server/MyAdServer.h: +server/XSHttpHelper.h: +server/XSHelper.h: +server/IPhoneHertbeat.h: +server/MySimpleServer.h: +server/IosSystemCmd.h: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSHackIos.h: +server/MyAdTask2.h: +server/XUDPServer.h: +server/CocoaAsyncSocket.h: +server/GCD/GCDAsyncUdpSocket.h: diff --git a/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.o new file mode 100644 index 0000000..1f4c186 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/MySimpleServer.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.Td new file mode 100644 index 0000000..5c0f7b4 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.Td @@ -0,0 +1,18 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.o: \ + server/UDPHandler.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/XSHackIos.h /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/MyAdTask2.h server/UDPHandler.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/MyAdTask2.h: +server/UDPHandler.h: diff --git a/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.o new file mode 100644 index 0000000..6a1a95b Binary files /dev/null and b/.theos/obj/debug/arm64e/server/UDPHandler.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.Td new file mode 100644 index 0000000..2808e2e --- /dev/null +++ b/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.Td @@ -0,0 +1,5 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.o: \ + server/UIView+Toast.m /Users/mac/theos/Prefix.pch \ + server/UIView+Toast.h +/Users/mac/theos/Prefix.pch: +server/UIView+Toast.h: diff --git a/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.o new file mode 100644 index 0000000..b38e154 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/UIView+Toast.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.Td new file mode 100644 index 0000000..0b4a9bf --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.Td @@ -0,0 +1,73 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.o: \ + server/XSHackIos.m /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/SpringBoard/SBWindow.h \ + /Users/mac/theos/vendor/include/FrontBoard/module.modulemap \ + /Users/mac/theos/vendor/include/FrontBoard/FrontBoard.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBApplicationInfo.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBBundleInfo.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBApplicationProcess.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcess.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBDisplayManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcessManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBProcessState.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSMutableSceneSettings.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettings.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettingsDiff.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBScene.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneClient.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneClientProvider.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneHostManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneHostWrapperView.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSceneManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemApp.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemGestureManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBSystemService.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWindow.h \ + /Users/mac/theos/vendor/include/UIKit/UIWindow+Private.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWindowContextHostManager.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEvent.h \ + /Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEventQueue.h \ + server/XSHelper.h server/XSHackIos.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + server/XSPhoneConfig.h server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/SpringBoard/SBWindow.h: +/Users/mac/theos/vendor/include/FrontBoard/module.modulemap: +/Users/mac/theos/vendor/include/FrontBoard/FrontBoard.h: +/Users/mac/theos/vendor/include/FrontBoard/FBApplicationInfo.h: +/Users/mac/theos/vendor/include/FrontBoard/FBBundleInfo.h: +/Users/mac/theos/vendor/include/FrontBoard/FBApplicationProcess.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcess.h: +/Users/mac/theos/vendor/include/FrontBoard/FBDisplayManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcessManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBProcessState.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSMutableSceneSettings.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettings.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSSceneSettingsDiff.h: +/Users/mac/theos/vendor/include/FrontBoard/FBScene.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneClient.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneClientProvider.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneHostManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneHostWrapperView.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSceneManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemApp.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemGestureManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBSystemService.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWindow.h: +/Users/mac/theos/vendor/include/UIKit/UIWindow+Private.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWindowContextHostManager.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEvent.h: +/Users/mac/theos/vendor/include/FrontBoard/FBWorkspaceEventQueue.h: +server/XSHelper.h: +server/XSHackIos.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +server/XSPhoneConfig.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.o new file mode 100644 index 0000000..406a424 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSHackIos.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.Td new file mode 100644 index 0000000..72de8bd --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.Td @@ -0,0 +1,4 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.o: \ + server/XSHelper.m /Users/mac/theos/Prefix.pch server/XSHelper.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: diff --git a/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.o new file mode 100644 index 0000000..0b180ec Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSHelper.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.Td new file mode 100644 index 0000000..a696043 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.Td @@ -0,0 +1,7 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.o: \ + server/XSHttpHelper.m /Users/mac/theos/Prefix.pch \ + server/XSHttpHelper.h server/XSHelper.h server/XSPhoneConfig.h +/Users/mac/theos/Prefix.pch: +server/XSHttpHelper.h: +server/XSHelper.h: +server/XSPhoneConfig.h: diff --git a/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.o new file mode 100644 index 0000000..03107ab Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSHttpHelper.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.Td new file mode 100644 index 0000000..a2ad767 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.Td @@ -0,0 +1,38 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.o: \ + server/XSIosTouch.m /Users/mac/theos/Prefix.pch server/XSIosTouch.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h \ + /Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h \ + server/IOHIDUsageTables.h server/XSPhoneConfig.h server/XSHelper.h +/Users/mac/theos/Prefix.pch: +server/XSIosTouch.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEvent.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventTypes.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventData.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystem.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDService.h: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventQueue.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDUserDevice.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDEventSystemClient.h: +/Users/mac/theos/vendor/include/IOKit/hid/IOHIDDisplay.h: +server/IOHIDUsageTables.h: +server/XSPhoneConfig.h: +server/XSHelper.h: diff --git a/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.o new file mode 100644 index 0000000..efda40c Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSIosTouch.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.Td new file mode 100644 index 0000000..bc0ad52 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.Td @@ -0,0 +1,7 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.o: \ + server/XSPhoneConfig.m /Users/mac/theos/Prefix.pch server/XSHelper.h \ + server/XSPhoneConfig.h server/MyEventBus.h +/Users/mac/theos/Prefix.pch: +server/XSHelper.h: +server/XSPhoneConfig.h: +server/MyEventBus.h: diff --git a/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.o new file mode 100644 index 0000000..2d7b5ad Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSPhoneConfig.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.Td new file mode 100644 index 0000000..ea751ae --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.Td @@ -0,0 +1,19 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.o: \ + server/XSPhoneInfo.m /Users/mac/theos/Prefix.pch \ + /Users/mac/theos/vendor/include/IOKit/IOKitLib.h \ + /Users/mac/theos/vendor/include/IOKit/IOTypes.h \ + /Users/mac/theos/vendor/include/IOKit/IOReturn.h \ + /Users/mac/theos/vendor/include/IOKit/IOKitKeys.h \ + /Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h \ + /Users/mac/theos/vendor/include/IOKit/ps/IOPowerSources.h \ + /Users/mac/theos/vendor/include/IOKit/ps/IOPSKeys.h \ + server/XSPhoneInfo.h +/Users/mac/theos/Prefix.pch: +/Users/mac/theos/vendor/include/IOKit/IOKitLib.h: +/Users/mac/theos/vendor/include/IOKit/IOTypes.h: +/Users/mac/theos/vendor/include/IOKit/IOReturn.h: +/Users/mac/theos/vendor/include/IOKit/IOKitKeys.h: +/Users/mac/theos/vendor/include/IOKit/OSMessageNotification.h: +/Users/mac/theos/vendor/include/IOKit/ps/IOPowerSources.h: +/Users/mac/theos/vendor/include/IOKit/ps/IOPSKeys.h: +server/XSPhoneInfo.h: diff --git a/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.o new file mode 100644 index 0000000..756366b Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XSPhoneInfo.m.9bfa848a.o differ diff --git a/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.Td b/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.Td new file mode 100644 index 0000000..2fd7372 --- /dev/null +++ b/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.Td @@ -0,0 +1,9 @@ +/Users/mac/workspaces/projects/ios-change/code/ios-change/main/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.o: \ + server/XUDPServer.m /Users/mac/theos/Prefix.pch server/XUDPServer.h \ + server/CocoaAsyncSocket.h server/GCD/GCDAsyncUdpSocket.h \ + server/UDPHandler.h +/Users/mac/theos/Prefix.pch: +server/XUDPServer.h: +server/CocoaAsyncSocket.h: +server/GCD/GCDAsyncUdpSocket.h: +server/UDPHandler.h: diff --git a/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.o b/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.o new file mode 100644 index 0000000..dcf1f93 Binary files /dev/null and b/.theos/obj/debug/arm64e/server/XUDPServer.m.9bfa848a.o differ diff --git a/.theos/obj/debug/server/.stamp b/.theos/obj/debug/server/.stamp new file mode 100644 index 0000000..e69de29 diff --git a/.theos/obj/debug/server/GCD/.stamp b/.theos/obj/debug/server/GCD/.stamp new file mode 100644 index 0000000..e69de29 diff --git a/.theos/packages/com.xyzshell.ioscontrol-0.0.7-10 b/.theos/packages/com.xyzshell.ioscontrol-0.0.7-10 new file mode 100644 index 0000000..d8263ee --- /dev/null +++ b/.theos/packages/com.xyzshell.ioscontrol-0.0.7-10 @@ -0,0 +1 @@ +2 \ No newline at end of file diff --git a/AppRunMan/.gitignore b/AppRunMan/.gitignore new file mode 100644 index 0000000..faf8687 --- /dev/null +++ b/AppRunMan/.gitignore @@ -0,0 +1,3 @@ +.theos/ +packages/ +.DS_Store diff --git a/AppRunMan/AppRunMan.plist b/AppRunMan/AppRunMan.plist new file mode 100644 index 0000000..10dc654 --- /dev/null +++ b/AppRunMan/AppRunMan.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.springboard" ); }; } diff --git a/AppRunMan/Makefile b/AppRunMan/Makefile new file mode 100644 index 0000000..192c2ca --- /dev/null +++ b/AppRunMan/Makefile @@ -0,0 +1,16 @@ +export ARCHS = arm64 arm64e + +TARGET := iphone:clang:latest:13.0 +INSTALL_TARGET_PROCESSES = SpringBoard + + +include $(THEOS)/makefiles/common.mk + +TWEAK_NAME = AppRunMan + +AppRunMan_FRAMEWORKS = CoreLocation CFNetwork CoreTelephony Security UIKit IOSurface JavaScriptCore network +AppRunMan_PRIVATE_FRAMEWORKS = IOKit +AppRunMan_FILES = Tweak.x $(wildcard server/*.m) $(wildcard server/GCD/*.m) +AppRunMan_CFLAGS = -Wno-error -Wno-module-import-in-extern-c -fobjc-arc + +include $(THEOS_MAKE_PATH)/tweak.mk diff --git a/AppRunMan/Tweak.x b/AppRunMan/Tweak.x new file mode 100644 index 0000000..a21e835 --- /dev/null +++ b/AppRunMan/Tweak.x @@ -0,0 +1,109 @@ +#import +#import +#import +#import +#import +#import + + +#import +#import + +#import "server/MySimpleServer.h" +#import "server/FloatingWindow.h" + +@interface UIWindow (FloatingWindow) +@end + +@implementation UIWindow (FloatingWindow) + +- (void)addFloatingWindow { + // Check if already exists + if (objc_getAssociatedObject(self, @selector(addFloatingWindow))) { + return; + } + + // Create floating window + UIWindow *floatingWindow = [[FloatingWindow alloc] initWithFrame]; + floatingWindow.windowLevel = UIWindowLevelAlert + 1; + floatingWindow.layer.masksToBounds = YES; + + // Show window + floatingWindow.hidden = NO; + + // Associate object to prevent multiple windows + objc_setAssociatedObject(self, @selector(addFloatingWindow), floatingWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + + + +@end + +%group all + +%hook SpringBoard + +- (void)applicationDidFinishLaunching:(id)arg1 +{ + %orig; + + // 延迟启动服务器,让系统UI完全加载 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + startSimpleServer(); + }); + + @autoreleasepool { + // 延迟添加悬浮窗,给系统UI足够的启动时间 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + // 添加保护机制 + @try { + for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) { + if ([windowScene isKindOfClass:[UIWindowScene class]]) { + UIWindow *window = windowScene.windows.firstObject; + if (window) { + [window addFloatingWindow]; + } + } + } + } @catch (NSException *exception) { + NSLog(@"Add floating window error: %@", exception); + } + }); + } +} + +// 添加生命周期方法以便清理 +- (void)applicationWillTerminate:(id)arg1 { + %orig; + // 清理服务器资源 + // 清理悬浮窗 +} + + +%end + +/* +// 注入网络权限 +%hook NSBundle + +- (NSDictionary *)infoDictionary { + NSMutableDictionary *dict = [[%orig mutableCopy] copy]; + [dict setObject:@YES forKey:@"NSLocalNetworkUsageDescription"]; + [dict setObject:@YES forKey:@"NSAllowsLocalNetworking"]; + return dict; +} + + +%end +*/ + + +%end + + +%ctor{ + NSLog(@"start app server"); + %init(all); +} \ No newline at end of file diff --git a/AppRunMan/control b/AppRunMan/control new file mode 100644 index 0000000..52352be --- /dev/null +++ b/AppRunMan/control @@ -0,0 +1,9 @@ +Package: com.xyzshell.apprunman +Name: AppRunMan +Version: 0.0.1 +Architecture: iphoneos-arm +Description: An awesome MobileSubstrate tweak! +Maintainer: xseanx +Author: xseanx +Section: Tweaks +Depends: mobilesubstrate (>= 0.9.5000) | org.coolstar.libhooker diff --git a/AppRunMan/server/CocoaAsyncSocket.h b/AppRunMan/server/CocoaAsyncSocket.h new file mode 100755 index 0000000..b7ac3b3 --- /dev/null +++ b/AppRunMan/server/CocoaAsyncSocket.h @@ -0,0 +1,19 @@ +// +// CocoaAsyncSocket.h +// CocoaAsyncSocket +// +// Created by Derek Clarkson on 10/08/2015. +// CocoaAsyncSocket project is in the public domain. +// + +#import + +//! Project version number for CocoaAsyncSocket. +FOUNDATION_EXPORT double cocoaAsyncSocketVersionNumber; + +//! Project version string for CocoaAsyncSocket. +FOUNDATION_EXPORT const unsigned char cocoaAsyncSocketVersionString[]; + + +#import "GCD/GCDAsyncUdpSocket.h" + diff --git a/AppRunMan/server/FloatingWindow.h b/AppRunMan/server/FloatingWindow.h new file mode 100644 index 0000000..6bfdf97 --- /dev/null +++ b/AppRunMan/server/FloatingWindow.h @@ -0,0 +1,36 @@ +// +// FloatingWindow.h +// nochange +// +// Created by mac on 2024/7/29. +// + +#ifndef FloatingWindow_h +#define FloatingWindow_h + +#import + +#import "XSHttpHelper.h" + +@interface FloatingWindow : UIWindow + +@property (nonatomic, strong) UILabel *nameLabel; +@property (nonatomic, strong) UILabel *ipLabel; +@property (nonatomic, strong) UILabel *deviceTypeLabel; +@property (nonatomic, strong) UIButton *actionButton; +@property (nonatomic, strong) UIButton *settingsButton; +@property (nonatomic, strong) UITextView *logTextView; + +@property (nonatomic, strong) XSHttpHelper *http; + +@property (nonatomic, strong) NSURLSessionDataTask *dataTask; + +- (void)changeBackgroundColor; + +- (instancetype)initWithFrame; + + + +@end + +#endif /* FloatingWindow_h */ diff --git a/AppRunMan/server/FloatingWindow.m b/AppRunMan/server/FloatingWindow.m new file mode 100644 index 0000000..33a16b3 --- /dev/null +++ b/AppRunMan/server/FloatingWindow.m @@ -0,0 +1,199 @@ +// +// FloatingWindow.m +// nochange +// +// Created by mac on 2024/7/29. +// + +#import +#import "FloatingWindow.h" +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" +#import "UIView+Toast.h" +#import "MyEventBus.h" +#import "XSHelper.h" +#import "MyAdTask2.h" +#import "IPhoneHertbeat.h" + +@interface FloatingWindow () { + +} + +@end + +@implementation FloatingWindow + +- (instancetype)initWithFrame { + CGRect screenBounds = [UIScreen mainScreen].bounds; + CGFloat floatingWindowWidth = 160; + CGFloat floatingWindowHeight = 140; + CGFloat xPosition = 0; + CGFloat yPosition = screenBounds.size.height - floatingWindowHeight; + + + CGRect frame = CGRectMake(xPosition, yPosition, floatingWindowWidth, floatingWindowHeight); + self = [super initWithFrame:frame]; + if (self) { + UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(detectPan:)]; + [self addGestureRecognizer:panRecognizer]; + + self.backgroundColor = RGB(193, 41, 48);// RGB(85, 172, 119); + self.layer.cornerRadius = 10; + self.clipsToBounds = YES; + + [self setupUI]; + [self updateInfo]; + self.http = [[XSHttpHelper alloc] init]; + [[MyEventBus sharedInstance] registerSubscriber:self]; + + } + return self; +} + + +- (void) dealloc { + [[MyEventBus sharedInstance] unregisterSubscriber:self]; +} + +- (void)setupUI { + // Name Label + self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 160, 18)]; + self.nameLabel.textColor = [UIColor whiteColor]; + self.nameLabel.font = [UIFont systemFontOfSize:14.0]; + [self addSubview:self.nameLabel]; + + // IP Label + self.ipLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, 160, 20)]; + [self addSubview:self.ipLabel]; + + // Device Type Label + self.deviceTypeLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 160, 30)]; + self.deviceTypeLabel.textColor = [UIColor whiteColor]; + self.deviceTypeLabel.numberOfLines = 0; + self.deviceTypeLabel.font = [UIFont systemFontOfSize:12.0]; + [self addSubview:self.deviceTypeLabel]; + + // Action Button + self.actionButton = [UIButton buttonWithType:UIButtonTypeSystem]; + self.actionButton.frame = CGRectMake(10, 100, 60, 30); + [self.actionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.actionButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; + // 'rgb(113, 201, 206)' + self.actionButton.backgroundColor = [UIColor colorWithRed:113 / 255.0 green:201 / 255.0 blue:206 /255.0 alpha:1.0]; + //self.actionButton.layer.borderWidth = 1.0; + //self.actionButton.layer.borderColor = [UIColor blueColor].CGColor; + self.actionButton.layer.cornerRadius = 4.0; + NSString *btnTitle = @"已停止"; + [self.actionButton setTitle:btnTitle forState:UIControlStateNormal]; + [self.actionButton addTarget:self action:@selector(actionButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:self.actionButton]; + + // Settings Button + self.settingsButton = [UIButton buttonWithType:UIButtonTypeSystem]; + self.settingsButton.frame = CGRectMake(80, 100, 60, 30); + [self.settingsButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.settingsButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted]; + self.settingsButton.backgroundColor = [UIColor colorWithRed:113 / 255.0 green:201 / 255.0 blue:206 /255.0 alpha:1.0]; + //self.actionButton.layer.borderWidth = 1.0; + //self.actionButton.layer.borderColor = [UIColor blueColor].CGColor; + self.settingsButton.layer.cornerRadius = 4.0; + [self.settingsButton setTitle:@"刷新" forState:UIControlStateNormal]; + [self.settingsButton addTarget:self action:@selector(settingsButtonTapped) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:self.settingsButton]; + + // self.center = CGPointMake(90, self.superview.bounds.size.height - 100); + +} + +- (void)updateInfo { + XSPhoneConfig *info = [XSPhoneConfig sharedInstance]; + self.nameLabel.text = [NSString stringWithFormat:@"%@", [info IPhoneName]]; + self.ipLabel.text = [NSString stringWithFormat:@"IP: %@", [[XSPhoneInfo sharedInstance] IPAddress]]; + self.deviceTypeLabel.text = @"unknow"; +} + +- (void)onEventUpdateStatus: (id)data { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + weakSelf.deviceTypeLabel.text = [NSString stringWithFormat:@"%@", data]; + }); +} + +- (void) onEventUpdateRunStatus: (id)data { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + //BOOL b = data; + + NSString *btnTitle = ([data isEqual: @(YES)] ? @"运行中" : @"已停止"); + NSLog(@"onEventUpdateRunStatus: %@,%@", data, btnTitle); + [weakSelf.actionButton setTitle:btnTitle forState:UIControlStateNormal]; + }); +} +- (void)showMyToast: (NSString *)msg { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + // UIView usage + [weakSelf makeToast:msg]; + }); +} + +- (void) onEventUpdateName: (id)data { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + XSPhoneConfig *info = [XSPhoneConfig sharedInstance]; + weakSelf.nameLabel.text = [NSString stringWithFormat:@"%@", [info IPhoneName]]; + }); +} + + + + +- (void)actionButtonTapped: (UIButton *)sender{ + NSLog(@"Action button tapped"); + MyAdTask2Mangger *man = [MyAdTask2Mangger sharedInstance]; + //MyAdTaskManager *man = [MyAdTaskManager sharedInstance]; + //IPhoneHertbeat *hertBeat = [IPhoneHertbeat sharedInstance]; + NSString *status = [man toggle]; // @"已停止"; + /* + if ([self.actionButton.titleLabel.text isEqual:@"运行中"]) { + [man stop]; + } else { + [man start]; + status = @"运行中"; + } + */ + //[self.actionButton setTitle:status forState:UIControlStateNormal]; +} + +- (void)settingsButtonTapped { + NSLog(@"Settings button tapped"); + [self updateInfo]; + //[self appendLog:@"设置按钮被按下"]; +} + +- (void)changeBackgroundColor { + self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 + green:arc4random_uniform(256)/255.0 + blue:arc4random_uniform(256)/255.0 + alpha:1.0]; +} + +- (void)appendLog:(NSString *)logMessage { + NSString *timestamp = [NSDateFormatter localizedStringFromDate:[NSDate date] + dateStyle:NSDateFormatterNoStyle + timeStyle:NSDateFormatterMediumStyle]; + NSString *fullLogMessage = [NSString stringWithFormat:@"%@: %@\n", timestamp, logMessage]; + self.logTextView.text = [self.logTextView.text stringByAppendingString:fullLogMessage]; + [self.logTextView scrollRangeToVisible:NSMakeRange(self.logTextView.text.length - 1, 1)]; +} + +- (void)detectPan:(UIPanGestureRecognizer *)panGesture { + UIWindow *floatingWindow = (UIWindow *)panGesture.view; + CGPoint translation = [panGesture translationInView:floatingWindow]; + floatingWindow.center = CGPointMake(floatingWindow.center.x + translation.x, floatingWindow.center.y + translation.y); + [panGesture setTranslation:CGPointZero inView:floatingWindow]; +} + + + +@end diff --git a/AppRunMan/server/GCD/GCDAsyncUdpSocket.h b/AppRunMan/server/GCD/GCDAsyncUdpSocket.h new file mode 100755 index 0000000..af327e0 --- /dev/null +++ b/AppRunMan/server/GCD/GCDAsyncUdpSocket.h @@ -0,0 +1,1036 @@ +// +// GCDAsyncUdpSocket +// +// This class is in the public domain. +// Originally created by Robbie Hanson of Deusty LLC. +// Updated and maintained by Deusty LLC and the Apple development community. +// +// https://github.com/robbiehanson/CocoaAsyncSocket +// + +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN +extern NSString *const GCDAsyncUdpSocketException; +extern NSString *const GCDAsyncUdpSocketErrorDomain; + +extern NSString *const GCDAsyncUdpSocketQueueName; +extern NSString *const GCDAsyncUdpSocketThreadName; + +typedef NS_ERROR_ENUM(GCDAsyncUdpSocketErrorDomain, GCDAsyncUdpSocketError) { + GCDAsyncUdpSocketNoError = 0, // Never used + GCDAsyncUdpSocketBadConfigError, // Invalid configuration + GCDAsyncUdpSocketBadParamError, // Invalid parameter was passed + GCDAsyncUdpSocketSendTimeoutError, // A send operation timed out + GCDAsyncUdpSocketClosedError, // The socket was closed + GCDAsyncUdpSocketOtherError, // Description provided in userInfo +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@class GCDAsyncUdpSocket; + +@protocol GCDAsyncUdpSocketDelegate +@optional + +/** + * By design, UDP is a connectionless protocol, and connecting is not needed. + * However, you may optionally choose to connect to a particular host for reasons + * outlined in the documentation for the various connect methods listed above. + * + * This method is called if one of the connect methods are invoked, and the connection is successful. +**/ +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address; + +/** + * By design, UDP is a connectionless protocol, and connecting is not needed. + * However, you may optionally choose to connect to a particular host for reasons + * outlined in the documentation for the various connect methods listed above. + * + * This method is called if one of the connect methods are invoked, and the connection fails. + * This may happen, for example, if a domain name is given for the host and the domain name is unable to be resolved. +**/ +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError * _Nullable)error; + +/** + * Called when the datagram with the given tag has been sent. +**/ +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag; + +/** + * Called if an error occurs while trying to send a datagram. + * This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet. +**/ +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError * _Nullable)error; + +/** + * Called when the socket has received the requested datagram. +**/ +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data + fromAddress:(NSData *)address + withFilterContext:(nullable id)filterContext; + +/** + * Called when the socket is closed. +**/ +- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError * _Nullable)error; + +@end + +/** + * You may optionally set a receive filter for the socket. + * A filter can provide several useful features: + * + * 1. Many times udp packets need to be parsed. + * Since the filter can run in its own independent queue, you can parallelize this parsing quite easily. + * The end result is a parallel socket io, datagram parsing, and packet processing. + * + * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited. + * The filter can prevent such packets from arriving at the delegate. + * And because the filter can run in its own independent queue, this doesn't slow down the delegate. + * + * - Since the udp protocol does not guarantee delivery, udp packets may be lost. + * Many protocols built atop udp thus provide various resend/re-request algorithms. + * This sometimes results in duplicate packets arriving. + * A filter may allow you to architect the duplicate detection code to run in parallel to normal processing. + * + * - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive. + * Such packets need to be ignored. + * + * 3. Sometimes traffic shapers are needed to simulate real world environments. + * A filter allows you to write custom code to simulate such environments. + * The ability to code this yourself is especially helpful when your simulated environment + * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), + * or the system tools to handle this aren't available (e.g. on a mobile device). + * + * @param data - The packet that was received. + * @param address - The address the data was received from. + * See utilities section for methods to extract info from address. + * @param context - Out parameter you may optionally set, which will then be passed to the delegate method. + * For example, filter block can parse the data and then, + * pass the parsed data to the delegate. + * + * @returns - YES if the received packet should be passed onto the delegate. + * NO if the received packet should be discarded, and not reported to the delegete. + * + * Example: + * + * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) { + * + * MyProtocolMessage *msg = [MyProtocol parseMessage:data]; + * + * *context = response; + * return (response != nil); + * }; + * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue]; + * +**/ +typedef BOOL (^GCDAsyncUdpSocketReceiveFilterBlock)(NSData *data, NSData *address, id __nullable * __nonnull context); + +/** + * You may optionally set a send filter for the socket. + * A filter can provide several interesting possibilities: + * + * 1. Optional caching of resolved addresses for domain names. + * The cache could later be consulted, resulting in fewer system calls to getaddrinfo. + * + * 2. Reusable modules of code for bandwidth monitoring. + * + * 3. Sometimes traffic shapers are needed to simulate real world environments. + * A filter allows you to write custom code to simulate such environments. + * The ability to code this yourself is especially helpful when your simulated environment + * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), + * or the system tools to handle this aren't available (e.g. on a mobile device). + * + * @param data - The packet that was received. + * @param address - The address the data was received from. + * See utilities section for methods to extract info from address. + * @param tag - The tag that was passed in the send method. + * + * @returns - YES if the packet should actually be sent over the socket. + * NO if the packet should be silently dropped (not sent over the socket). + * + * Regardless of the return value, the delegate will be informed that the packet was successfully sent. + * +**/ +typedef BOOL (^GCDAsyncUdpSocketSendFilterBlock)(NSData *data, NSData *address, long tag); + + +@interface GCDAsyncUdpSocket : NSObject + +/** + * GCDAsyncUdpSocket uses the standard delegate paradigm, + * but executes all delegate callbacks on a given delegate dispatch queue. + * This allows for maximum concurrency, while at the same time providing easy thread safety. + * + * You MUST set a delegate AND delegate dispatch queue before attempting to + * use the socket, or you will get an error. + * + * The socket queue is optional. + * If you pass NULL, GCDAsyncSocket will automatically create its own socket queue. + * If you choose to provide a socket queue, the socket queue must not be a concurrent queue, + * then please see the discussion for the method markSocketQueueTargetQueue. + * + * The delegate queue and socket queue can optionally be the same. +**/ +- (instancetype)init; +- (instancetype)initWithSocketQueue:(nullable dispatch_queue_t)sq; +- (instancetype)initWithDelegate:(nullable id)aDelegate delegateQueue:(nullable dispatch_queue_t)dq; +- (instancetype)initWithDelegate:(nullable id)aDelegate delegateQueue:(nullable dispatch_queue_t)dq socketQueue:(nullable dispatch_queue_t)sq NS_DESIGNATED_INITIALIZER; + +#pragma mark Configuration + +- (nullable id)delegate; +- (void)setDelegate:(nullable id)delegate; +- (void)synchronouslySetDelegate:(nullable id)delegate; + +- (nullable dispatch_queue_t)delegateQueue; +- (void)setDelegateQueue:(nullable dispatch_queue_t)delegateQueue; +- (void)synchronouslySetDelegateQueue:(nullable dispatch_queue_t)delegateQueue; + +- (void)getDelegate:(id __nullable * __nullable)delegatePtr delegateQueue:(dispatch_queue_t __nullable * __nullable)delegateQueuePtr; +- (void)setDelegate:(nullable id)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; +- (void)synchronouslySetDelegate:(nullable id)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; + +/** + * By default, both IPv4 and IPv6 are enabled. + * + * This means GCDAsyncUdpSocket automatically supports both protocols, + * and can send to IPv4 or IPv6 addresses, + * as well as receive over IPv4 and IPv6. + * + * For operations that require DNS resolution, GCDAsyncUdpSocket supports both IPv4 and IPv6. + * If a DNS lookup returns only IPv4 results, GCDAsyncUdpSocket will automatically use IPv4. + * If a DNS lookup returns only IPv6 results, GCDAsyncUdpSocket will automatically use IPv6. + * If a DNS lookup returns both IPv4 and IPv6 results, then the protocol used depends on the configured preference. + * If IPv4 is preferred, then IPv4 is used. + * If IPv6 is preferred, then IPv6 is used. + * If neutral, then the first IP version in the resolved array will be used. + * + * Starting with Mac OS X 10.7 Lion and iOS 5, the default IP preference is neutral. + * On prior systems the default IP preference is IPv4. + **/ +- (BOOL)isIPv4Enabled; +- (void)setIPv4Enabled:(BOOL)flag; + +- (BOOL)isIPv6Enabled; +- (void)setIPv6Enabled:(BOOL)flag; + +- (BOOL)isIPv4Preferred; +- (BOOL)isIPv6Preferred; +- (BOOL)isIPVersionNeutral; + +- (void)setPreferIPv4; +- (void)setPreferIPv6; +- (void)setIPVersionNeutral; + +/** + * Gets/Sets the maximum size of the buffer that will be allocated for receive operations. + * The default maximum size is 65535 bytes. + * + * The theoretical maximum size of any IPv4 UDP packet is UINT16_MAX = 65535. + * The theoretical maximum size of any IPv6 UDP packet is UINT32_MAX = 4294967295. + * + * Since the OS/GCD notifies us of the size of each received UDP packet, + * the actual allocated buffer size for each packet is exact. + * And in practice the size of UDP packets is generally much smaller than the max. + * Indeed most protocols will send and receive packets of only a few bytes, + * or will set a limit on the size of packets to prevent fragmentation in the IP layer. + * + * If you set the buffer size too small, the sockets API in the OS will silently discard + * any extra data, and you will not be notified of the error. +**/ +- (uint16_t)maxReceiveIPv4BufferSize; +- (void)setMaxReceiveIPv4BufferSize:(uint16_t)max; + +- (uint32_t)maxReceiveIPv6BufferSize; +- (void)setMaxReceiveIPv6BufferSize:(uint32_t)max; + +/** + * Gets/Sets the maximum size of the buffer that will be allocated for send operations. + * The default maximum size is 65535 bytes. + * + * Given that a typical link MTU is 1500 bytes, a large UDP datagram will have to be + * fragmented, and that’s both expensive and risky (if one fragment goes missing, the + * entire datagram is lost). You are much better off sending a large number of smaller + * UDP datagrams, preferably using a path MTU algorithm to avoid fragmentation. + * + * You must set it before the sockt is created otherwise it won't work. + * + **/ +- (uint16_t)maxSendBufferSize; +- (void)setMaxSendBufferSize:(uint16_t)max; + +/** + * User data allows you to associate arbitrary information with the socket. + * This data is not used internally in any way. +**/ +- (nullable id)userData; +- (void)setUserData:(nullable id)arbitraryUserData; + +#pragma mark Diagnostics + +/** + * Returns the local address info for the socket. + * + * The localAddress method returns a sockaddr structure wrapped in a NSData object. + * The localHost method returns the human readable IP address as a string. + * + * Note: Address info may not be available until after the socket has been binded, connected + * or until after data has been sent. +**/ +- (nullable NSData *)localAddress; +- (nullable NSString *)localHost; +- (uint16_t)localPort; + +- (nullable NSData *)localAddress_IPv4; +- (nullable NSString *)localHost_IPv4; +- (uint16_t)localPort_IPv4; + +- (nullable NSData *)localAddress_IPv6; +- (nullable NSString *)localHost_IPv6; +- (uint16_t)localPort_IPv6; + +/** + * Returns the remote address info for the socket. + * + * The connectedAddress method returns a sockaddr structure wrapped in a NSData object. + * The connectedHost method returns the human readable IP address as a string. + * + * Note: Since UDP is connectionless by design, connected address info + * will not be available unless the socket is explicitly connected to a remote host/port. + * If the socket is not connected, these methods will return nil / 0. +**/ +- (nullable NSData *)connectedAddress; +- (nullable NSString *)connectedHost; +- (uint16_t)connectedPort; + +/** + * Returns whether or not this socket has been connected to a single host. + * By design, UDP is a connectionless protocol, and connecting is not needed. + * If connected, the socket will only be able to send/receive data to/from the connected host. +**/ +- (BOOL)isConnected; + +/** + * Returns whether or not this socket has been closed. + * The only way a socket can be closed is if you explicitly call one of the close methods. +**/ +- (BOOL)isClosed; + +/** + * Returns whether or not this socket is IPv4. + * + * By default this will be true, unless: + * - IPv4 is disabled (via setIPv4Enabled:) + * - The socket is explicitly bound to an IPv6 address + * - The socket is connected to an IPv6 address +**/ +- (BOOL)isIPv4; + +/** + * Returns whether or not this socket is IPv6. + * + * By default this will be true, unless: + * - IPv6 is disabled (via setIPv6Enabled:) + * - The socket is explicitly bound to an IPv4 address + * _ The socket is connected to an IPv4 address + * + * This method will also return false on platforms that do not support IPv6. + * Note: The iPhone does not currently support IPv6. +**/ +- (BOOL)isIPv6; + +#pragma mark Binding + +/** + * Binds the UDP socket to the given port. + * Binding should be done for server sockets that receive data prior to sending it. + * Client sockets can skip binding, + * as the OS will automatically assign the socket an available port when it starts sending data. + * + * You may optionally pass a port number of zero to immediately bind the socket, + * yet still allow the OS to automatically assign an available port. + * + * You cannot bind a socket after its been connected. + * You can only bind a socket once. + * You can still connect a socket (if desired) after binding. + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. +**/ +- (BOOL)bindToPort:(uint16_t)port error:(NSError **)errPtr; + +/** + * Binds the UDP socket to the given port and optional interface. + * Binding should be done for server sockets that receive data prior to sending it. + * Client sockets can skip binding, + * as the OS will automatically assign the socket an available port when it starts sending data. + * + * You may optionally pass a port number of zero to immediately bind the socket, + * yet still allow the OS to automatically assign an available port. + * + * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). + * You may also use the special strings "localhost" or "loopback" to specify that + * the socket only accept packets from the local machine. + * + * You cannot bind a socket after its been connected. + * You can only bind a socket once. + * You can still connect a socket (if desired) after binding. + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. +**/ +- (BOOL)bindToPort:(uint16_t)port interface:(nullable NSString *)interface error:(NSError **)errPtr; + +/** + * Binds the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object. + * + * If you have an existing struct sockaddr you can convert it to a NSData object like so: + * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; + * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; + * + * Binding should be done for server sockets that receive data prior to sending it. + * Client sockets can skip binding, + * as the OS will automatically assign the socket an available port when it starts sending data. + * + * You cannot bind a socket after its been connected. + * You can only bind a socket once. + * You can still connect a socket (if desired) after binding. + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. +**/ +- (BOOL)bindToAddress:(NSData *)localAddr error:(NSError **)errPtr; + +#pragma mark Connecting + +/** + * Connects the UDP socket to the given host and port. + * By design, UDP is a connectionless protocol, and connecting is not needed. + * + * Choosing to connect to a specific host/port has the following effect: + * - You will only be able to send data to the connected host/port. + * - You will only be able to receive data from the connected host/port. + * - You will receive ICMP messages that come from the connected host/port, such as "connection refused". + * + * The actual process of connecting a UDP socket does not result in any communication on the socket. + * It simply changes the internal state of the socket. + * + * You cannot bind a socket after it has been connected. + * You can only connect a socket once. + * + * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). + * + * This method is asynchronous as it requires a DNS lookup to resolve the given host name. + * If an obvious error is detected, this method immediately returns NO and sets errPtr. + * If you don't care about the error, you can pass nil for errPtr. + * Otherwise, this method returns YES and begins the asynchronous connection process. + * The result of the asynchronous connection process will be reported via the delegate methods. + **/ +- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr; + +/** + * Connects the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object. + * + * If you have an existing struct sockaddr you can convert it to a NSData object like so: + * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; + * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; + * + * By design, UDP is a connectionless protocol, and connecting is not needed. + * + * Choosing to connect to a specific address has the following effect: + * - You will only be able to send data to the connected address. + * - You will only be able to receive data from the connected address. + * - You will receive ICMP messages that come from the connected address, such as "connection refused". + * + * Connecting a UDP socket does not result in any communication on the socket. + * It simply changes the internal state of the socket. + * + * You cannot bind a socket after its been connected. + * You can only connect a socket once. + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. + * + * Note: Unlike the connectToHost:onPort:error: method, this method does not require a DNS lookup. + * Thus when this method returns, the connection has either failed or fully completed. + * In other words, this method is synchronous, unlike the asynchronous connectToHost::: method. + * However, for compatibility and simplification of delegate code, if this method returns YES + * then the corresponding delegate method (udpSocket:didConnectToHost:port:) is still invoked. +**/ +- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr; + +#pragma mark Multicast + +/** + * Join multicast group. + * Group should be an IP address (eg @"225.228.0.1"). + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. +**/ +- (BOOL)joinMulticastGroup:(NSString *)group error:(NSError **)errPtr; + +/** + * Join multicast group. + * Group should be an IP address (eg @"225.228.0.1"). + * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. +**/ +- (BOOL)joinMulticastGroup:(NSString *)group onInterface:(nullable NSString *)interface error:(NSError **)errPtr; + +- (BOOL)leaveMulticastGroup:(NSString *)group error:(NSError **)errPtr; +- (BOOL)leaveMulticastGroup:(NSString *)group onInterface:(nullable NSString *)interface error:(NSError **)errPtr; + +/** + * Send multicast on a specified interface. + * For IPv4, interface should be the the IP address of the interface (eg @"192.168.10.1"). + * For IPv6, interface should be the a network interface name (eg @"en0"). + * + * On success, returns YES. + * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. +**/ + +- (BOOL)sendIPv4MulticastOnInterface:(NSString*)interface error:(NSError **)errPtr; +- (BOOL)sendIPv6MulticastOnInterface:(NSString*)interface error:(NSError **)errPtr; + +#pragma mark Reuse Port + +/** + * By default, only one socket can be bound to a given IP address + port at a time. + * To enable multiple processes to simultaneously bind to the same address+port, + * you need to enable this functionality in the socket. All processes that wish to + * use the address+port simultaneously must all enable reuse port on the socket + * bound to that port. + **/ +- (BOOL)enableReusePort:(BOOL)flag error:(NSError **)errPtr; + +#pragma mark Broadcast + +/** + * By default, the underlying socket in the OS will not allow you to send broadcast messages. + * In order to send broadcast messages, you need to enable this functionality in the socket. + * + * A broadcast is a UDP message to addresses like "192.168.255.255" or "255.255.255.255" that is + * delivered to every host on the network. + * The reason this is generally disabled by default (by the OS) is to prevent + * accidental broadcast messages from flooding the network. +**/ +- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr; + +#pragma mark Sending + +/** + * Asynchronously sends the given data, with the given timeout and tag. + * + * This method may only be used with a connected socket. + * Recall that connecting is optional for a UDP socket. + * For connected sockets, data can only be sent to the connected address. + * For non-connected sockets, the remote destination is specified for each packet. + * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. + * + * @param data + * The data to send. + * If data is nil or zero-length, this method does nothing. + * If passing NSMutableData, please read the thread-safety notice below. + * + * @param timeout + * The timeout for the send opeartion. + * If the timeout value is negative, the send operation will not use a timeout. + * + * @param tag + * The tag is for your convenience. + * It is not sent or received over the socket in any manner what-so-ever. + * It is reported back as a parameter in the udpSocket:didSendDataWithTag: + * or udpSocket:didNotSendDataWithTag:dueToError: methods. + * You can use it as an array index, state id, type constant, etc. + * + * + * Thread-Safety Note: + * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while + * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method + * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying + * that this particular send operation has completed. + * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. + * It simply retains it for performance reasons. + * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. + * Copying this data adds an unwanted/unneeded overhead. + * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket + * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time + * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. +**/ +- (void)sendData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; + +/** + * Asynchronously sends the given data, with the given timeout and tag, to the given host and port. + * + * This method cannot be used with a connected socket. + * Recall that connecting is optional for a UDP socket. + * For connected sockets, data can only be sent to the connected address. + * For non-connected sockets, the remote destination is specified for each packet. + * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. + * + * @param data + * The data to send. + * If data is nil or zero-length, this method does nothing. + * If passing NSMutableData, please read the thread-safety notice below. + * + * @param host + * The destination to send the udp packet to. + * May be specified as a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). + * You may also use the convenience strings of "loopback" or "localhost". + * + * @param port + * The port of the host to send to. + * + * @param timeout + * The timeout for the send opeartion. + * If the timeout value is negative, the send operation will not use a timeout. + * + * @param tag + * The tag is for your convenience. + * It is not sent or received over the socket in any manner what-so-ever. + * It is reported back as a parameter in the udpSocket:didSendDataWithTag: + * or udpSocket:didNotSendDataWithTag:dueToError: methods. + * You can use it as an array index, state id, type constant, etc. + * + * + * Thread-Safety Note: + * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while + * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method + * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying + * that this particular send operation has completed. + * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. + * It simply retains it for performance reasons. + * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. + * Copying this data adds an unwanted/unneeded overhead. + * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket + * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time + * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. +**/ +- (void)sendData:(NSData *)data + toHost:(NSString *)host + port:(uint16_t)port + withTimeout:(NSTimeInterval)timeout + tag:(long)tag; + +/** + * Asynchronously sends the given data, with the given timeout and tag, to the given address. + * + * This method cannot be used with a connected socket. + * Recall that connecting is optional for a UDP socket. + * For connected sockets, data can only be sent to the connected address. + * For non-connected sockets, the remote destination is specified for each packet. + * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. + * + * @param data + * The data to send. + * If data is nil or zero-length, this method does nothing. + * If passing NSMutableData, please read the thread-safety notice below. + * + * @param remoteAddr + * The address to send the data to (specified as a sockaddr structure wrapped in a NSData object). + * + * @param timeout + * The timeout for the send opeartion. + * If the timeout value is negative, the send operation will not use a timeout. + * + * @param tag + * The tag is for your convenience. + * It is not sent or received over the socket in any manner what-so-ever. + * It is reported back as a parameter in the udpSocket:didSendDataWithTag: + * or udpSocket:didNotSendDataWithTag:dueToError: methods. + * You can use it as an array index, state id, type constant, etc. + * + * + * Thread-Safety Note: + * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while + * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method + * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying + * that this particular send operation has completed. + * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. + * It simply retains it for performance reasons. + * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. + * Copying this data adds an unwanted/unneeded overhead. + * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket + * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time + * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. +**/ +- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag; + +/** + * You may optionally set a send filter for the socket. + * A filter can provide several interesting possibilities: + * + * 1. Optional caching of resolved addresses for domain names. + * The cache could later be consulted, resulting in fewer system calls to getaddrinfo. + * + * 2. Reusable modules of code for bandwidth monitoring. + * + * 3. Sometimes traffic shapers are needed to simulate real world environments. + * A filter allows you to write custom code to simulate such environments. + * The ability to code this yourself is especially helpful when your simulated environment + * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), + * or the system tools to handle this aren't available (e.g. on a mobile device). + * + * For more information about GCDAsyncUdpSocketSendFilterBlock, see the documentation for its typedef. + * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue. + * + * Note: This method invokes setSendFilter:withQueue:isAsynchronous: (documented below), + * passing YES for the isAsynchronous parameter. +**/ +- (void)setSendFilter:(nullable GCDAsyncUdpSocketSendFilterBlock)filterBlock withQueue:(nullable dispatch_queue_t)filterQueue; + +/** + * The receive filter can be run via dispatch_async or dispatch_sync. + * Most typical situations call for asynchronous operation. + * + * However, there are a few situations in which synchronous operation is preferred. + * Such is the case when the filter is extremely minimal and fast. + * This is because dispatch_sync is faster than dispatch_async. + * + * If you choose synchronous operation, be aware of possible deadlock conditions. + * Since the socket queue is executing your block via dispatch_sync, + * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue. + * For example, you can't query properties on the socket. +**/ +- (void)setSendFilter:(nullable GCDAsyncUdpSocketSendFilterBlock)filterBlock + withQueue:(nullable dispatch_queue_t)filterQueue + isAsynchronous:(BOOL)isAsynchronous; + +#pragma mark Receiving + +/** + * There are two modes of operation for receiving packets: one-at-a-time & continuous. + * + * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet. + * Receiving packets one-at-a-time may be better suited for implementing certain state machine code, + * where your state machine may not always be ready to process incoming packets. + * + * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received. + * Receiving packets continuously is better suited to real-time streaming applications. + * + * You may switch back and forth between one-at-a-time mode and continuous mode. + * If the socket is currently in continuous mode, calling this method will switch it to one-at-a-time mode. + * + * When a packet is received (and not filtered by the optional receive filter), + * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked. + * + * If the socket is able to begin receiving packets, this method returns YES. + * Otherwise it returns NO, and sets the errPtr with appropriate error information. + * + * An example error: + * You created a udp socket to act as a server, and immediately called receive. + * You forgot to first bind the socket to a port number, and received a error with a message like: + * "Must bind socket before you can receive data." +**/ +- (BOOL)receiveOnce:(NSError **)errPtr; + +/** + * There are two modes of operation for receiving packets: one-at-a-time & continuous. + * + * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet. + * Receiving packets one-at-a-time may be better suited for implementing certain state machine code, + * where your state machine may not always be ready to process incoming packets. + * + * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received. + * Receiving packets continuously is better suited to real-time streaming applications. + * + * You may switch back and forth between one-at-a-time mode and continuous mode. + * If the socket is currently in one-at-a-time mode, calling this method will switch it to continuous mode. + * + * For every received packet (not filtered by the optional receive filter), + * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked. + * + * If the socket is able to begin receiving packets, this method returns YES. + * Otherwise it returns NO, and sets the errPtr with appropriate error information. + * + * An example error: + * You created a udp socket to act as a server, and immediately called receive. + * You forgot to first bind the socket to a port number, and received a error with a message like: + * "Must bind socket before you can receive data." +**/ +- (BOOL)beginReceiving:(NSError **)errPtr; + +/** + * If the socket is currently receiving (beginReceiving has been called), this method pauses the receiving. + * That is, it won't read any more packets from the underlying OS socket until beginReceiving is called again. + * + * Important Note: + * GCDAsyncUdpSocket may be running in parallel with your code. + * That is, your delegate is likely running on a separate thread/dispatch_queue. + * When you invoke this method, GCDAsyncUdpSocket may have already dispatched delegate methods to be invoked. + * Thus, if those delegate methods have already been dispatch_async'd, + * your didReceive delegate method may still be invoked after this method has been called. + * You should be aware of this, and program defensively. +**/ +- (void)pauseReceiving; + +/** + * You may optionally set a receive filter for the socket. + * This receive filter may be set to run in its own queue (independent of delegate queue). + * + * A filter can provide several useful features. + * + * 1. Many times udp packets need to be parsed. + * Since the filter can run in its own independent queue, you can parallelize this parsing quite easily. + * The end result is a parallel socket io, datagram parsing, and packet processing. + * + * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited. + * The filter can prevent such packets from arriving at the delegate. + * And because the filter can run in its own independent queue, this doesn't slow down the delegate. + * + * - Since the udp protocol does not guarantee delivery, udp packets may be lost. + * Many protocols built atop udp thus provide various resend/re-request algorithms. + * This sometimes results in duplicate packets arriving. + * A filter may allow you to architect the duplicate detection code to run in parallel to normal processing. + * + * - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive. + * Such packets need to be ignored. + * + * 3. Sometimes traffic shapers are needed to simulate real world environments. + * A filter allows you to write custom code to simulate such environments. + * The ability to code this yourself is especially helpful when your simulated environment + * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), + * or the system tools to handle this aren't available (e.g. on a mobile device). + * + * Example: + * + * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) { + * + * MyProtocolMessage *msg = [MyProtocol parseMessage:data]; + * + * *context = response; + * return (response != nil); + * }; + * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue]; + * + * For more information about GCDAsyncUdpSocketReceiveFilterBlock, see the documentation for its typedef. + * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue. + * + * Note: This method invokes setReceiveFilter:withQueue:isAsynchronous: (documented below), + * passing YES for the isAsynchronous parameter. +**/ +- (void)setReceiveFilter:(nullable GCDAsyncUdpSocketReceiveFilterBlock)filterBlock withQueue:(nullable dispatch_queue_t)filterQueue; + +/** + * The receive filter can be run via dispatch_async or dispatch_sync. + * Most typical situations call for asynchronous operation. + * + * However, there are a few situations in which synchronous operation is preferred. + * Such is the case when the filter is extremely minimal and fast. + * This is because dispatch_sync is faster than dispatch_async. + * + * If you choose synchronous operation, be aware of possible deadlock conditions. + * Since the socket queue is executing your block via dispatch_sync, + * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue. + * For example, you can't query properties on the socket. +**/ +- (void)setReceiveFilter:(nullable GCDAsyncUdpSocketReceiveFilterBlock)filterBlock + withQueue:(nullable dispatch_queue_t)filterQueue + isAsynchronous:(BOOL)isAsynchronous; + +#pragma mark Closing + +/** + * Immediately closes the underlying socket. + * Any pending send operations are discarded. + * + * The GCDAsyncUdpSocket instance may optionally be used again. + * (it will setup/configure/use another unnderlying BSD socket). +**/ +- (void)close; + +/** + * Closes the underlying socket after all pending send operations have been sent. + * + * The GCDAsyncUdpSocket instance may optionally be used again. + * (it will setup/configure/use another unnderlying BSD socket). +**/ +- (void)closeAfterSending; + +#pragma mark Advanced +/** + * GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue. + * In most cases, the instance creates this queue itself. + * However, to allow for maximum flexibility, the internal queue may be passed in the init method. + * This allows for some advanced options such as controlling socket priority via target queues. + * However, when one begins to use target queues like this, they open the door to some specific deadlock issues. + * + * For example, imagine there are 2 queues: + * dispatch_queue_t socketQueue; + * dispatch_queue_t socketTargetQueue; + * + * If you do this (pseudo-code): + * socketQueue.targetQueue = socketTargetQueue; + * + * Then all socketQueue operations will actually get run on the given socketTargetQueue. + * This is fine and works great in most situations. + * But if you run code directly from within the socketTargetQueue that accesses the socket, + * you could potentially get deadlock. Imagine the following code: + * + * - (BOOL)socketHasSomething + * { + * __block BOOL result = NO; + * dispatch_block_t block = ^{ + * result = [self someInternalMethodToBeRunOnlyOnSocketQueue]; + * } + * if (is_executing_on_queue(socketQueue)) + * block(); + * else + * dispatch_sync(socketQueue, block); + * + * return result; + * } + * + * What happens if you call this method from the socketTargetQueue? The result is deadlock. + * This is because the GCD API offers no mechanism to discover a queue's targetQueue. + * Thus we have no idea if our socketQueue is configured with a targetQueue. + * If we had this information, we could easily avoid deadlock. + * But, since these API's are missing or unfeasible, you'll have to explicitly set it. + * + * IF you pass a socketQueue via the init method, + * AND you've configured the passed socketQueue with a targetQueue, + * THEN you should pass the end queue in the target hierarchy. + * + * For example, consider the following queue hierarchy: + * socketQueue -> ipQueue -> moduleQueue + * + * This example demonstrates priority shaping within some server. + * All incoming client connections from the same IP address are executed on the same target queue. + * And all connections for a particular module are executed on the same target queue. + * Thus, the priority of all networking for the entire module can be changed on the fly. + * Additionally, networking traffic from a single IP cannot monopolize the module. + * + * Here's how you would accomplish something like that: + * - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock + * { + * dispatch_queue_t socketQueue = dispatch_queue_create("", NULL); + * dispatch_queue_t ipQueue = [self ipQueueForAddress:address]; + * + * dispatch_set_target_queue(socketQueue, ipQueue); + * dispatch_set_target_queue(iqQueue, moduleQueue); + * + * return socketQueue; + * } + * - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket + * { + * [clientConnections addObject:newSocket]; + * [newSocket markSocketQueueTargetQueue:moduleQueue]; + * } + * + * Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue. + * This is often NOT the case, as such queues are used solely for execution shaping. + **/ +- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue; +- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue; + +/** + * It's not thread-safe to access certain variables from outside the socket's internal queue. + * + * For example, the socket file descriptor. + * File descriptors are simply integers which reference an index in the per-process file table. + * However, when one requests a new file descriptor (by opening a file or socket), + * the file descriptor returned is guaranteed to be the lowest numbered unused descriptor. + * So if we're not careful, the following could be possible: + * + * - Thread A invokes a method which returns the socket's file descriptor. + * - The socket is closed via the socket's internal queue on thread B. + * - Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD. + * - Thread A is now accessing/altering the file instead of the socket. + * + * In addition to this, other variables are not actually objects, + * and thus cannot be retained/released or even autoreleased. + * An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct. + * + * Although there are internal variables that make it difficult to maintain thread-safety, + * it is important to provide access to these variables + * to ensure this class can be used in a wide array of environments. + * This method helps to accomplish this by invoking the current block on the socket's internal queue. + * The methods below can be invoked from within the block to access + * those generally thread-unsafe internal variables in a thread-safe manner. + * The given block will be invoked synchronously on the socket's internal queue. + * + * If you save references to any protected variables and use them outside the block, you do so at your own peril. +**/ +- (void)performBlock:(dispatch_block_t)block; + +/** + * These methods are only available from within the context of a performBlock: invocation. + * See the documentation for the performBlock: method above. + * + * Provides access to the socket's file descriptor(s). + * If the socket isn't connected, or explicity bound to a particular interface, + * it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6. +**/ +- (int)socketFD; +- (int)socket4FD; +- (int)socket6FD; + +#if TARGET_OS_IPHONE + +/** + * These methods are only available from within the context of a performBlock: invocation. + * See the documentation for the performBlock: method above. + * + * Returns (creating if necessary) a CFReadStream/CFWriteStream for the internal socket. + * + * Generally GCDAsyncUdpSocket doesn't use CFStream. (It uses the faster GCD API's.) + * However, if you need one for any reason, + * these methods are a convenient way to get access to a safe instance of one. +**/ +- (nullable CFReadStreamRef)readStream; +- (nullable CFWriteStreamRef)writeStream; + +/** + * This method is only available from within the context of a performBlock: invocation. + * See the documentation for the performBlock: method above. + * + * Configures the socket to allow it to operate when the iOS application has been backgrounded. + * In other words, this method creates a read & write stream, and invokes: + * + * CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); + * CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); + * + * Returns YES if successful, NO otherwise. + * + * Example usage: + * + * [asyncUdpSocket performBlock:^{ + * [asyncUdpSocket enableBackgroundingOnSocket]; + * }]; + * + * + * NOTE : Apple doesn't currently support backgrounding UDP sockets. (Only TCP for now). +**/ +//- (BOOL)enableBackgroundingOnSockets; + +#endif + +#pragma mark Utilities + +/** + * Extracting host/port/family information from raw address data. +**/ + ++ (nullable NSString *)hostFromAddress:(NSData *)address; ++ (uint16_t)portFromAddress:(NSData *)address; ++ (int)familyFromAddress:(NSData *)address; + ++ (BOOL)isIPv4Address:(NSData *)address; ++ (BOOL)isIPv6Address:(NSData *)address; + ++ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(uint16_t * __nullable)portPtr fromAddress:(NSData *)address; ++ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(uint16_t * __nullable)portPtr family:(int * __nullable)afPtr fromAddress:(NSData *)address; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AppRunMan/server/GCD/GCDAsyncUdpSocket.m b/AppRunMan/server/GCD/GCDAsyncUdpSocket.m new file mode 100755 index 0000000..af0cbf2 --- /dev/null +++ b/AppRunMan/server/GCD/GCDAsyncUdpSocket.m @@ -0,0 +1,5632 @@ +// +// GCDAsyncUdpSocket +// +// This class is in the public domain. +// Originally created by Robbie Hanson of Deusty LLC. +// Updated and maintained by Deusty LLC and the Apple development community. +// +// https://github.com/robbiehanson/CocoaAsyncSocket +// + +#import "GCDAsyncUdpSocket.h" + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +// For more information see: https://github.com/robbiehanson/CocoaAsyncSocket/wiki/ARC +#endif + +#if TARGET_OS_IPHONE + #import + #import +#endif + +#import +#import +#import +#import +#import +#import +#import + + +#if 0 + +// Logging Enabled - See log level below + +// Logging uses the CocoaLumberjack framework (which is also GCD based). +// https://github.com/robbiehanson/CocoaLumberjack +// +// It allows us to do a lot of logging without significantly slowing down the code. +#import "DDLog.h" + +#define LogAsync NO +#define LogContext 65535 + +#define LogObjc(flg, frmt, ...) LOG_OBJC_MAYBE(LogAsync, logLevel, flg, LogContext, frmt, ##__VA_ARGS__) +#define LogC(flg, frmt, ...) LOG_C_MAYBE(LogAsync, logLevel, flg, LogContext, frmt, ##__VA_ARGS__) + +#define LogError(frmt, ...) LogObjc(LOG_FLAG_ERROR, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogWarn(frmt, ...) LogObjc(LOG_FLAG_WARN, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogInfo(frmt, ...) LogObjc(LOG_FLAG_INFO, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogVerbose(frmt, ...) LogObjc(LOG_FLAG_VERBOSE, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) + +#define LogCError(frmt, ...) LogC(LOG_FLAG_ERROR, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogCWarn(frmt, ...) LogC(LOG_FLAG_WARN, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogCInfo(frmt, ...) LogC(LOG_FLAG_INFO, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) +#define LogCVerbose(frmt, ...) LogC(LOG_FLAG_VERBOSE, (@"%@: " frmt), THIS_FILE, ##__VA_ARGS__) + +#define LogTrace() LogObjc(LOG_FLAG_VERBOSE, @"%@: %@", THIS_FILE, THIS_METHOD) +#define LogCTrace() LogC(LOG_FLAG_VERBOSE, @"%@: %s", THIS_FILE, __FUNCTION__) + +// Log levels : off, error, warn, info, verbose +static const int logLevel = LOG_LEVEL_VERBOSE; + +#else + +// Logging Disabled + +#define LogError(frmt, ...) {} +#define LogWarn(frmt, ...) {} +#define LogInfo(frmt, ...) {} +#define LogVerbose(frmt, ...) {} + +#define LogCError(frmt, ...) {} +#define LogCWarn(frmt, ...) {} +#define LogCInfo(frmt, ...) {} +#define LogCVerbose(frmt, ...) {} + +#define LogTrace() {} +#define LogCTrace(frmt, ...) {} + +#endif + +/** + * Seeing a return statements within an inner block + * can sometimes be mistaken for a return point of the enclosing method. + * This makes inline blocks a bit easier to read. +**/ +#define return_from_block return + +/** + * A socket file descriptor is really just an integer. + * It represents the index of the socket within the kernel. + * This makes invalid file descriptor comparisons easier to read. +**/ +#define SOCKET_NULL -1 + +/** + * Just to type less code. +**/ +#define AutoreleasedBlock(block) ^{ @autoreleasepool { block(); }} + + +@class GCDAsyncUdpSendPacket; + +NSString *const GCDAsyncUdpSocketException = @"GCDAsyncUdpSocketException"; +NSString *const GCDAsyncUdpSocketErrorDomain = @"GCDAsyncUdpSocketErrorDomain"; + +NSString *const GCDAsyncUdpSocketQueueName = @"GCDAsyncUdpSocket"; +NSString *const GCDAsyncUdpSocketThreadName = @"GCDAsyncUdpSocket-CFStream"; + +enum GCDAsyncUdpSocketFlags +{ + kDidCreateSockets = 1 << 0, // If set, the sockets have been created. + kDidBind = 1 << 1, // If set, bind has been called. + kConnecting = 1 << 2, // If set, a connection attempt is in progress. + kDidConnect = 1 << 3, // If set, socket is connected. + kReceiveOnce = 1 << 4, // If set, one-at-a-time receive is enabled + kReceiveContinuous = 1 << 5, // If set, continuous receive is enabled + kIPv4Deactivated = 1 << 6, // If set, socket4 was closed due to bind or connect on IPv6. + kIPv6Deactivated = 1 << 7, // If set, socket6 was closed due to bind or connect on IPv4. + kSend4SourceSuspended = 1 << 8, // If set, send4Source is suspended. + kSend6SourceSuspended = 1 << 9, // If set, send6Source is suspended. + kReceive4SourceSuspended = 1 << 10, // If set, receive4Source is suspended. + kReceive6SourceSuspended = 1 << 11, // If set, receive6Source is suspended. + kSock4CanAcceptBytes = 1 << 12, // If set, we know socket4 can accept bytes. If unset, it's unknown. + kSock6CanAcceptBytes = 1 << 13, // If set, we know socket6 can accept bytes. If unset, it's unknown. + kForbidSendReceive = 1 << 14, // If set, no new send or receive operations are allowed to be queued. + kCloseAfterSends = 1 << 15, // If set, close as soon as no more sends are queued. + kFlipFlop = 1 << 16, // Used to alternate between IPv4 and IPv6 sockets. +#if TARGET_OS_IPHONE + kAddedStreamListener = 1 << 17, // If set, CFStreams have been added to listener thread +#endif +}; + +enum GCDAsyncUdpSocketConfig +{ + kIPv4Disabled = 1 << 0, // If set, IPv4 is disabled + kIPv6Disabled = 1 << 1, // If set, IPv6 is disabled + kPreferIPv4 = 1 << 2, // If set, IPv4 is preferred over IPv6 + kPreferIPv6 = 1 << 3, // If set, IPv6 is preferred over IPv4 +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface GCDAsyncUdpSocket () +{ +#if __has_feature(objc_arc_weak) + __weak id delegate; +#else + __unsafe_unretained id delegate; +#endif + dispatch_queue_t delegateQueue; + + GCDAsyncUdpSocketReceiveFilterBlock receiveFilterBlock; + dispatch_queue_t receiveFilterQueue; + BOOL receiveFilterAsync; + + GCDAsyncUdpSocketSendFilterBlock sendFilterBlock; + dispatch_queue_t sendFilterQueue; + BOOL sendFilterAsync; + + uint32_t flags; + uint16_t config; + + uint16_t max4ReceiveSize; + uint32_t max6ReceiveSize; + + uint16_t maxSendSize; + + int socket4FD; + int socket6FD; + + dispatch_queue_t socketQueue; + + dispatch_source_t send4Source; + dispatch_source_t send6Source; + dispatch_source_t receive4Source; + dispatch_source_t receive6Source; + dispatch_source_t sendTimer; + + GCDAsyncUdpSendPacket *currentSend; + NSMutableArray *sendQueue; + + unsigned long socket4FDBytesAvailable; + unsigned long socket6FDBytesAvailable; + + uint32_t pendingFilterOperations; + + NSData *cachedLocalAddress4; + NSString *cachedLocalHost4; + uint16_t cachedLocalPort4; + + NSData *cachedLocalAddress6; + NSString *cachedLocalHost6; + uint16_t cachedLocalPort6; + + NSData *cachedConnectedAddress; + NSString *cachedConnectedHost; + uint16_t cachedConnectedPort; + int cachedConnectedFamily; + + void *IsOnSocketQueueOrTargetQueueKey; + +#if TARGET_OS_IPHONE + CFStreamClientContext streamContext; + CFReadStreamRef readStream4; + CFReadStreamRef readStream6; + CFWriteStreamRef writeStream4; + CFWriteStreamRef writeStream6; +#endif + + id userData; +} + +- (void)resumeSend4Source; +- (void)resumeSend6Source; +- (void)resumeReceive4Source; +- (void)resumeReceive6Source; +- (void)closeSockets; + +- (void)maybeConnect; +- (BOOL)connectWithAddress4:(NSData *)address4 error:(NSError **)errPtr; +- (BOOL)connectWithAddress6:(NSData *)address6 error:(NSError **)errPtr; + +- (void)maybeDequeueSend; +- (void)doPreSend; +- (void)doSend; +- (void)endCurrentSend; +- (void)setupSendTimerWithTimeout:(NSTimeInterval)timeout; + +- (void)doReceive; +- (void)doReceiveEOF; + +- (void)closeWithError:(NSError *)error; + +- (BOOL)performMulticastRequest:(int)requestType forGroup:(NSString *)group onInterface:(NSString *)interface error:(NSError **)errPtr; + +#if TARGET_OS_IPHONE +- (BOOL)createReadAndWriteStreams:(NSError **)errPtr; +- (BOOL)registerForStreamCallbacks:(NSError **)errPtr; +- (BOOL)addStreamsToRunLoop:(NSError **)errPtr; +- (BOOL)openStreams:(NSError **)errPtr; +- (void)removeStreamsFromRunLoop; +- (void)closeReadAndWriteStreams; +#endif + ++ (NSString *)hostFromSockaddr4:(const struct sockaddr_in *)pSockaddr4; ++ (NSString *)hostFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6; ++ (uint16_t)portFromSockaddr4:(const struct sockaddr_in *)pSockaddr4; ++ (uint16_t)portFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6; + +#if TARGET_OS_IPHONE +// Forward declaration ++ (void)listenerThread:(id)unused; +#endif + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * The GCDAsyncUdpSendPacket encompasses the instructions for a single send/write. +**/ +@interface GCDAsyncUdpSendPacket : NSObject { +@public + NSData *buffer; + NSTimeInterval timeout; + long tag; + + BOOL resolveInProgress; + BOOL filterInProgress; + + NSArray *resolvedAddresses; + NSError *resolveError; + + NSData *address; + int addressFamily; +} + +- (instancetype)initWithData:(NSData *)d timeout:(NSTimeInterval)t tag:(long)i NS_DESIGNATED_INITIALIZER; + +@end + +@implementation GCDAsyncUdpSendPacket + +// Cover the superclass' designated initializer +- (instancetype)init NS_UNAVAILABLE +{ + NSAssert(0, @"Use the designated initializer"); + return nil; +} + +- (instancetype)initWithData:(NSData *)d timeout:(NSTimeInterval)t tag:(long)i +{ + if ((self = [super init])) + { + buffer = d; + timeout = t; + tag = i; + + resolveInProgress = NO; + } + return self; +} + + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface GCDAsyncUdpSpecialPacket : NSObject { +@public +// uint8_t type; + + BOOL resolveInProgress; + + NSArray *addresses; + NSError *error; +} + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +@end + +@implementation GCDAsyncUdpSpecialPacket + +- (instancetype)init +{ + self = [super init]; + return self; +} + + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation GCDAsyncUdpSocket + +- (instancetype)init +{ + LogTrace(); + + return [self initWithDelegate:nil delegateQueue:NULL socketQueue:NULL]; +} + +- (instancetype)initWithSocketQueue:(dispatch_queue_t)sq +{ + LogTrace(); + + return [self initWithDelegate:nil delegateQueue:NULL socketQueue:sq]; +} + +- (instancetype)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq +{ + LogTrace(); + + return [self initWithDelegate:aDelegate delegateQueue:dq socketQueue:NULL]; +} + +- (instancetype)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq +{ + LogTrace(); + + if ((self = [super init])) + { + delegate = aDelegate; + + if (dq) + { + delegateQueue = dq; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(delegateQueue); + #endif + } + + max4ReceiveSize = 65535; + max6ReceiveSize = 65535; + + maxSendSize = 65535; + + socket4FD = SOCKET_NULL; + socket6FD = SOCKET_NULL; + + if (sq) + { + NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), + @"The given socketQueue parameter must not be a concurrent queue."); + NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), + @"The given socketQueue parameter must not be a concurrent queue."); + NSAssert(sq != dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), + @"The given socketQueue parameter must not be a concurrent queue."); + + socketQueue = sq; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(socketQueue); + #endif + } + else + { + socketQueue = dispatch_queue_create([GCDAsyncUdpSocketQueueName UTF8String], NULL); + } + + // The dispatch_queue_set_specific() and dispatch_get_specific() functions take a "void *key" parameter. + // From the documentation: + // + // > Keys are only compared as pointers and are never dereferenced. + // > Thus, you can use a pointer to a static variable for a specific subsystem or + // > any other value that allows you to identify the value uniquely. + // + // We're just going to use the memory address of an ivar. + // Specifically an ivar that is explicitly named for our purpose to make the code more readable. + // + // However, it feels tedious (and less readable) to include the "&" all the time: + // dispatch_get_specific(&IsOnSocketQueueOrTargetQueueKey) + // + // So we're going to make it so it doesn't matter if we use the '&' or not, + // by assigning the value of the ivar to the address of the ivar. + // Thus: IsOnSocketQueueOrTargetQueueKey == &IsOnSocketQueueOrTargetQueueKey; + + IsOnSocketQueueOrTargetQueueKey = &IsOnSocketQueueOrTargetQueueKey; + + void *nonNullUnusedPointer = (__bridge void *)self; + dispatch_queue_set_specific(socketQueue, IsOnSocketQueueOrTargetQueueKey, nonNullUnusedPointer, NULL); + + currentSend = nil; + sendQueue = [[NSMutableArray alloc] initWithCapacity:5]; + + #if TARGET_OS_IPHONE + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillEnterForeground:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + #endif + } + return self; +} + +- (void)dealloc +{ + LogInfo(@"%@ - %@ (start)", THIS_METHOD, self); + +#if TARGET_OS_IPHONE + [[NSNotificationCenter defaultCenter] removeObserver:self]; +#endif + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + [self closeWithError:nil]; + } + else + { + dispatch_sync(socketQueue, ^{ + [self closeWithError:nil]; + }); + } + + delegate = nil; + #if !OS_OBJECT_USE_OBJC + if (delegateQueue) dispatch_release(delegateQueue); + #endif + delegateQueue = NULL; + + #if !OS_OBJECT_USE_OBJC + if (socketQueue) dispatch_release(socketQueue); + #endif + socketQueue = NULL; + + LogInfo(@"%@ - %@ (finish)", THIS_METHOD, self); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (id)delegate +{ + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + return delegate; + } + else + { + __block id result = nil; + + dispatch_sync(socketQueue, ^{ + result = self->delegate; + }); + + return result; + } +} + +- (void)setDelegate:(id)newDelegate synchronously:(BOOL)synchronously +{ + dispatch_block_t block = ^{ + self->delegate = newDelegate; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) { + block(); + } + else { + if (synchronously) + dispatch_sync(socketQueue, block); + else + dispatch_async(socketQueue, block); + } +} + +- (void)setDelegate:(id)newDelegate +{ + [self setDelegate:newDelegate synchronously:NO]; +} + +- (void)synchronouslySetDelegate:(id)newDelegate +{ + [self setDelegate:newDelegate synchronously:YES]; +} + +- (dispatch_queue_t)delegateQueue +{ + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + return delegateQueue; + } + else + { + __block dispatch_queue_t result = NULL; + + dispatch_sync(socketQueue, ^{ + result = self->delegateQueue; + }); + + return result; + } +} + +- (void)setDelegateQueue:(dispatch_queue_t)newDelegateQueue synchronously:(BOOL)synchronously +{ + dispatch_block_t block = ^{ + + #if !OS_OBJECT_USE_OBJC + if (self->delegateQueue) dispatch_release(self->delegateQueue); + if (newDelegateQueue) dispatch_retain(newDelegateQueue); + #endif + + self->delegateQueue = newDelegateQueue; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) { + block(); + } + else { + if (synchronously) + dispatch_sync(socketQueue, block); + else + dispatch_async(socketQueue, block); + } +} + +- (void)setDelegateQueue:(dispatch_queue_t)newDelegateQueue +{ + [self setDelegateQueue:newDelegateQueue synchronously:NO]; +} + +- (void)synchronouslySetDelegateQueue:(dispatch_queue_t)newDelegateQueue +{ + [self setDelegateQueue:newDelegateQueue synchronously:YES]; +} + +- (void)getDelegate:(id *)delegatePtr delegateQueue:(dispatch_queue_t *)delegateQueuePtr +{ + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + if (delegatePtr) *delegatePtr = delegate; + if (delegateQueuePtr) *delegateQueuePtr = delegateQueue; + } + else + { + __block id dPtr = NULL; + __block dispatch_queue_t dqPtr = NULL; + + dispatch_sync(socketQueue, ^{ + dPtr = self->delegate; + dqPtr = self->delegateQueue; + }); + + if (delegatePtr) *delegatePtr = dPtr; + if (delegateQueuePtr) *delegateQueuePtr = dqPtr; + } +} + +- (void)setDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue synchronously:(BOOL)synchronously +{ + dispatch_block_t block = ^{ + + self->delegate = newDelegate; + + #if !OS_OBJECT_USE_OBJC + if (self->delegateQueue) dispatch_release(self->delegateQueue); + if (newDelegateQueue) dispatch_retain(newDelegateQueue); + #endif + + self->delegateQueue = newDelegateQueue; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) { + block(); + } + else { + if (synchronously) + dispatch_sync(socketQueue, block); + else + dispatch_async(socketQueue, block); + } +} + +- (void)setDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue +{ + [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:NO]; +} + +- (void)synchronouslySetDelegate:(id)newDelegate delegateQueue:(dispatch_queue_t)newDelegateQueue +{ + [self setDelegate:newDelegate delegateQueue:newDelegateQueue synchronously:YES]; +} + +- (BOOL)isIPv4Enabled +{ + // Note: YES means kIPv4Disabled is OFF + + __block BOOL result = NO; + + dispatch_block_t block = ^{ + + result = ((self->config & kIPv4Disabled) == 0); + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setIPv4Enabled:(BOOL)flag +{ + // Note: YES means kIPv4Disabled is OFF + + dispatch_block_t block = ^{ + + LogVerbose(@"%@ %@", THIS_METHOD, (flag ? @"YES" : @"NO")); + + if (flag) + self->config &= ~kIPv4Disabled; + else + self->config |= kIPv4Disabled; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (BOOL)isIPv6Enabled +{ + // Note: YES means kIPv6Disabled is OFF + + __block BOOL result = NO; + + dispatch_block_t block = ^{ + + result = ((self->config & kIPv6Disabled) == 0); + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setIPv6Enabled:(BOOL)flag +{ + // Note: YES means kIPv6Disabled is OFF + + dispatch_block_t block = ^{ + + LogVerbose(@"%@ %@", THIS_METHOD, (flag ? @"YES" : @"NO")); + + if (flag) + self->config &= ~kIPv6Disabled; + else + self->config |= kIPv6Disabled; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (BOOL)isIPv4Preferred +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + result = (self->config & kPreferIPv4) ? YES : NO; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (BOOL)isIPv6Preferred +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + result = (self->config & kPreferIPv6) ? YES : NO; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (BOOL)isIPVersionNeutral +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + result = (self->config & (kPreferIPv4 | kPreferIPv6)) == 0; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setPreferIPv4 +{ + dispatch_block_t block = ^{ + + LogTrace(); + + self->config |= kPreferIPv4; + self->config &= ~kPreferIPv6; + + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)setPreferIPv6 +{ + dispatch_block_t block = ^{ + + LogTrace(); + + self->config &= ~kPreferIPv4; + self->config |= kPreferIPv6; + + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)setIPVersionNeutral +{ + dispatch_block_t block = ^{ + + LogTrace(); + + self->config &= ~kPreferIPv4; + self->config &= ~kPreferIPv6; + + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (uint16_t)maxReceiveIPv4BufferSize +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + result = self->max4ReceiveSize; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setMaxReceiveIPv4BufferSize:(uint16_t)max +{ + dispatch_block_t block = ^{ + + LogVerbose(@"%@ %u", THIS_METHOD, (unsigned)max); + + self->max4ReceiveSize = max; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (uint32_t)maxReceiveIPv6BufferSize +{ + __block uint32_t result = 0; + + dispatch_block_t block = ^{ + + result = self->max6ReceiveSize; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setMaxReceiveIPv6BufferSize:(uint32_t)max +{ + dispatch_block_t block = ^{ + + LogVerbose(@"%@ %u", THIS_METHOD, (unsigned)max); + + self->max6ReceiveSize = max; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)setMaxSendBufferSize:(uint16_t)max +{ + dispatch_block_t block = ^{ + + LogVerbose(@"%@ %u", THIS_METHOD, (unsigned)max); + + self->maxSendSize = max; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (uint16_t)maxSendBufferSize +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + result = self->maxSendSize; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (id)userData +{ + __block id result = nil; + + dispatch_block_t block = ^{ + + result = self->userData; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (void)setUserData:(id)arbitraryUserData +{ + dispatch_block_t block = ^{ + + if (self->userData != arbitraryUserData) + { + self->userData = arbitraryUserData; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Delegate Helpers +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)notifyDidConnectToAddress:(NSData *)anAddress +{ + LogTrace(); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:@selector(udpSocket:didConnectToAddress:)]) + { + NSData *address = [anAddress copy]; // In case param is NSMutableData + + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocket:self didConnectToAddress:address]; + }}); + } +} + +- (void)notifyDidNotConnect:(NSError *)error +{ + LogTrace(); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:@selector(udpSocket:didNotConnect:)]) + { + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocket:self didNotConnect:error]; + }}); + } +} + +- (void)notifyDidSendDataWithTag:(long)tag +{ + LogTrace(); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:@selector(udpSocket:didSendDataWithTag:)]) + { + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocket:self didSendDataWithTag:tag]; + }}); + } +} + +- (void)notifyDidNotSendDataWithTag:(long)tag dueToError:(NSError *)error +{ + LogTrace(); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:@selector(udpSocket:didNotSendDataWithTag:dueToError:)]) + { + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocket:self didNotSendDataWithTag:tag dueToError:error]; + }}); + } +} + +- (void)notifyDidReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)context +{ + LogTrace(); + + SEL selector = @selector(udpSocket:didReceiveData:fromAddress:withFilterContext:); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:selector]) + { + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocket:self didReceiveData:data fromAddress:address withFilterContext:context]; + }}); + } +} + +- (void)notifyDidCloseWithError:(NSError *)error +{ + LogTrace(); + + __strong id theDelegate = delegate; + if (delegateQueue && [theDelegate respondsToSelector:@selector(udpSocketDidClose:withError:)]) + { + dispatch_async(delegateQueue, ^{ @autoreleasepool { + + [theDelegate udpSocketDidClose:self withError:error]; + }}); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Errors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSError *)badConfigError:(NSString *)errMsg +{ + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:GCDAsyncUdpSocketErrorDomain + code:GCDAsyncUdpSocketBadConfigError + userInfo:userInfo]; +} + +- (NSError *)badParamError:(NSString *)errMsg +{ + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:GCDAsyncUdpSocketErrorDomain + code:GCDAsyncUdpSocketBadParamError + userInfo:userInfo]; +} + +- (NSError *)gaiError:(int)gai_error +{ + NSString *errMsg = [NSString stringWithCString:gai_strerror(gai_error) encoding:NSASCIIStringEncoding]; + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:@"kCFStreamErrorDomainNetDB" code:gai_error userInfo:userInfo]; +} + +- (NSError *)errnoErrorWithReason:(NSString *)reason +{ + NSString *errMsg = [NSString stringWithUTF8String:strerror(errno)]; + NSDictionary *userInfo; + + if (reason) + userInfo = @{NSLocalizedDescriptionKey : errMsg, + NSLocalizedFailureReasonErrorKey : reason}; + else + userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:userInfo]; +} + +- (NSError *)errnoError +{ + return [self errnoErrorWithReason:nil]; +} + +/** + * Returns a standard send timeout error. +**/ +- (NSError *)sendTimeoutError +{ + NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncUdpSocketSendTimeoutError", + @"GCDAsyncUdpSocket", [NSBundle mainBundle], + @"Send operation timed out", nil); + + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:GCDAsyncUdpSocketErrorDomain + code:GCDAsyncUdpSocketSendTimeoutError + userInfo:userInfo]; +} + +- (NSError *)socketClosedError +{ + NSString *errMsg = NSLocalizedStringWithDefaultValue(@"GCDAsyncUdpSocketClosedError", + @"GCDAsyncUdpSocket", [NSBundle mainBundle], + @"Socket closed", nil); + + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:GCDAsyncUdpSocketErrorDomain code:GCDAsyncUdpSocketClosedError userInfo:userInfo]; +} + +- (NSError *)otherError:(NSString *)errMsg +{ + NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errMsg}; + + return [NSError errorWithDomain:GCDAsyncUdpSocketErrorDomain + code:GCDAsyncUdpSocketOtherError + userInfo:userInfo]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Utilities +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)preOp:(NSError **)errPtr +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if (delegate == nil) // Must have delegate set + { + if (errPtr) + { + NSString *msg = @"Attempting to use socket without a delegate. Set a delegate first."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + if (delegateQueue == NULL) // Must have delegate queue set + { + if (errPtr) + { + NSString *msg = @"Attempting to use socket without a delegate queue. Set a delegate queue first."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + return YES; +} + +/** + * This method executes on a global concurrent queue. + * When complete, it executes the given completion block on the socketQueue. +**/ +- (void)asyncResolveHost:(NSString *)aHost + port:(uint16_t)port + withCompletionBlock:(void (^)(NSArray *addresses, NSError *error))completionBlock +{ + LogTrace(); + + // Check parameter(s) + + if (aHost == nil) + { + NSString *msg = @"The host param is nil. Should be domain name or IP address string."; + NSError *error = [self badParamError:msg]; + + // We should still use dispatch_async since this method is expected to be asynchronous + + dispatch_async(socketQueue, ^{ @autoreleasepool { + + completionBlock(nil, error); + }}); + + return; + } + + // It's possible that the given aHost parameter is actually a NSMutableString. + // So we want to copy it now, within this block that will be executed synchronously. + // This way the asynchronous lookup block below doesn't have to worry about it changing. + + NSString *host = [aHost copy]; + + + dispatch_queue_t globalConcurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_async(globalConcurrentQueue, ^{ @autoreleasepool { + + NSMutableArray *addresses = [NSMutableArray arrayWithCapacity:2]; + NSError *error = nil; + + if ([host isEqualToString:@"localhost"] || [host isEqualToString:@"loopback"]) + { + // Use LOOPBACK address + struct sockaddr_in sockaddr4; + memset(&sockaddr4, 0, sizeof(sockaddr4)); + + sockaddr4.sin_len = sizeof(struct sockaddr_in); + sockaddr4.sin_family = AF_INET; + sockaddr4.sin_port = htons(port); + sockaddr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + struct sockaddr_in6 sockaddr6; + memset(&sockaddr6, 0, sizeof(sockaddr6)); + + sockaddr6.sin6_len = sizeof(struct sockaddr_in6); + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = htons(port); + sockaddr6.sin6_addr = in6addr_loopback; + + // Wrap the native address structures and add to list + [addresses addObject:[NSData dataWithBytes:&sockaddr4 length:sizeof(sockaddr4)]]; + [addresses addObject:[NSData dataWithBytes:&sockaddr6 length:sizeof(sockaddr6)]]; + } + else + { + NSString *portStr = [NSString stringWithFormat:@"%hu", port]; + + struct addrinfo hints, *res, *res0; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + int gai_error = getaddrinfo([host UTF8String], [portStr UTF8String], &hints, &res0); + + if (gai_error) + { + error = [self gaiError:gai_error]; + } + else + { + for(res = res0; res; res = res->ai_next) + { + if (res->ai_family == AF_INET) + { + // Found IPv4 address + // Wrap the native address structure and add to list + + [addresses addObject:[NSData dataWithBytes:res->ai_addr length:res->ai_addrlen]]; + } + else if (res->ai_family == AF_INET6) + { + + // Fixes connection issues with IPv6, it is the same solution for udp socket. + // https://github.com/robbiehanson/CocoaAsyncSocket/issues/429#issuecomment-222477158 + struct sockaddr_in6 *sockaddr = (struct sockaddr_in6 *)(void *)res->ai_addr; + in_port_t *portPtr = &sockaddr->sin6_port; + if ((portPtr != NULL) && (*portPtr == 0)) { + *portPtr = htons(port); + } + + // Found IPv6 address + // Wrap the native address structure and add to list + [addresses addObject:[NSData dataWithBytes:res->ai_addr length:res->ai_addrlen]]; + } + } + freeaddrinfo(res0); + + if ([addresses count] == 0) + { + error = [self gaiError:EAI_FAIL]; + } + } + } + + dispatch_async(self->socketQueue, ^{ @autoreleasepool { + + completionBlock(addresses, error); + }}); + + }}); +} + +/** + * This method picks an address from the given list of addresses. + * The address picked depends upon which protocols are disabled, deactived, & preferred. + * + * Returns the address family (AF_INET or AF_INET6) of the picked address, + * or AF_UNSPEC and the corresponding error is there's a problem. +**/ +- (int)getAddress:(NSData **)addressPtr error:(NSError **)errorPtr fromAddresses:(NSArray *)addresses +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert([addresses count] > 0, @"Expected at least one address"); + + int resultAF = AF_UNSPEC; + NSData *resultAddress = nil; + NSError *resultError = nil; + + // Check for problems + + BOOL resolvedIPv4Address = NO; + BOOL resolvedIPv6Address = NO; + + for (NSData *address in addresses) + { + switch ([[self class] familyFromAddress:address]) + { + case AF_INET : resolvedIPv4Address = YES; break; + case AF_INET6 : resolvedIPv6Address = YES; break; + + default : NSAssert(NO, @"Addresses array contains invalid address"); + } + } + + BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO; + BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO; + + if (isIPv4Disabled && !resolvedIPv6Address) + { + NSString *msg = @"IPv4 has been disabled and DNS lookup found no IPv6 address(es)."; + resultError = [self otherError:msg]; + + if (addressPtr) *addressPtr = resultAddress; + if (errorPtr) *errorPtr = resultError; + + return resultAF; + } + + if (isIPv6Disabled && !resolvedIPv4Address) + { + NSString *msg = @"IPv6 has been disabled and DNS lookup found no IPv4 address(es)."; + resultError = [self otherError:msg]; + + if (addressPtr) *addressPtr = resultAddress; + if (errorPtr) *errorPtr = resultError; + + return resultAF; + } + + BOOL isIPv4Deactivated = (flags & kIPv4Deactivated) ? YES : NO; + BOOL isIPv6Deactivated = (flags & kIPv6Deactivated) ? YES : NO; + + if (isIPv4Deactivated && !resolvedIPv6Address) + { + NSString *msg = @"IPv4 has been deactivated due to bind/connect, and DNS lookup found no IPv6 address(es)."; + resultError = [self otherError:msg]; + + if (addressPtr) *addressPtr = resultAddress; + if (errorPtr) *errorPtr = resultError; + + return resultAF; + } + + if (isIPv6Deactivated && !resolvedIPv4Address) + { + NSString *msg = @"IPv6 has been deactivated due to bind/connect, and DNS lookup found no IPv4 address(es)."; + resultError = [self otherError:msg]; + + if (addressPtr) *addressPtr = resultAddress; + if (errorPtr) *errorPtr = resultError; + + return resultAF; + } + + // Extract first IPv4 and IPv6 address in list + + BOOL ipv4WasFirstInList = YES; + NSData *address4 = nil; + NSData *address6 = nil; + + for (NSData *address in addresses) + { + int af = [[self class] familyFromAddress:address]; + + if (af == AF_INET) + { + if (address4 == nil) + { + address4 = address; + + if (address6) + break; + else + ipv4WasFirstInList = YES; + } + } + else // af == AF_INET6 + { + if (address6 == nil) + { + address6 = address; + + if (address4) + break; + else + ipv4WasFirstInList = NO; + } + } + } + + // Determine socket type + + BOOL preferIPv4 = (config & kPreferIPv4) ? YES : NO; + BOOL preferIPv6 = (config & kPreferIPv6) ? YES : NO; + + BOOL useIPv4 = ((preferIPv4 && address4) || (address6 == nil)); + BOOL useIPv6 = ((preferIPv6 && address6) || (address4 == nil)); + + NSAssert(!(preferIPv4 && preferIPv6), @"Invalid config state"); + NSAssert(!(useIPv4 && useIPv6), @"Invalid logic"); + + if (useIPv4 || (!useIPv6 && ipv4WasFirstInList)) + { + resultAF = AF_INET; + resultAddress = address4; + } + else + { + resultAF = AF_INET6; + resultAddress = address6; + } + + if (addressPtr) *addressPtr = resultAddress; + if (errorPtr) *errorPtr = resultError; + + return resultAF; +} + +/** + * Finds the address(es) of an interface description. + * An inteface description may be an interface name (en0, en1, lo0) or corresponding IP (192.168.4.34). +**/ +- (void)convertIntefaceDescription:(NSString *)interfaceDescription + port:(uint16_t)port + intoAddress4:(NSData **)interfaceAddr4Ptr + address6:(NSData **)interfaceAddr6Ptr +{ + NSData *addr4 = nil; + NSData *addr6 = nil; + + if (interfaceDescription == nil) + { + // ANY address + + struct sockaddr_in sockaddr4; + memset(&sockaddr4, 0, sizeof(sockaddr4)); + + sockaddr4.sin_len = sizeof(sockaddr4); + sockaddr4.sin_family = AF_INET; + sockaddr4.sin_port = htons(port); + sockaddr4.sin_addr.s_addr = htonl(INADDR_ANY); + + struct sockaddr_in6 sockaddr6; + memset(&sockaddr6, 0, sizeof(sockaddr6)); + + sockaddr6.sin6_len = sizeof(sockaddr6); + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = htons(port); + sockaddr6.sin6_addr = in6addr_any; + + addr4 = [NSData dataWithBytes:&sockaddr4 length:sizeof(sockaddr4)]; + addr6 = [NSData dataWithBytes:&sockaddr6 length:sizeof(sockaddr6)]; + } + else if ([interfaceDescription isEqualToString:@"localhost"] || + [interfaceDescription isEqualToString:@"loopback"]) + { + // LOOPBACK address + + struct sockaddr_in sockaddr4; + memset(&sockaddr4, 0, sizeof(sockaddr4)); + + sockaddr4.sin_len = sizeof(struct sockaddr_in); + sockaddr4.sin_family = AF_INET; + sockaddr4.sin_port = htons(port); + sockaddr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + struct sockaddr_in6 sockaddr6; + memset(&sockaddr6, 0, sizeof(sockaddr6)); + + sockaddr6.sin6_len = sizeof(struct sockaddr_in6); + sockaddr6.sin6_family = AF_INET6; + sockaddr6.sin6_port = htons(port); + sockaddr6.sin6_addr = in6addr_loopback; + + addr4 = [NSData dataWithBytes:&sockaddr4 length:sizeof(sockaddr4)]; + addr6 = [NSData dataWithBytes:&sockaddr6 length:sizeof(sockaddr6)]; + } + else + { + const char *iface = [interfaceDescription UTF8String]; + + struct ifaddrs *addrs; + const struct ifaddrs *cursor; + + if ((getifaddrs(&addrs) == 0)) + { + cursor = addrs; + while (cursor != NULL) + { + if ((addr4 == nil) && (cursor->ifa_addr->sa_family == AF_INET)) + { + // IPv4 + + struct sockaddr_in *addr = (struct sockaddr_in *)(void *)cursor->ifa_addr; + + if (strcmp(cursor->ifa_name, iface) == 0) + { + // Name match + + struct sockaddr_in nativeAddr4 = *addr; + nativeAddr4.sin_port = htons(port); + + addr4 = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)]; + } + else + { + char ip[INET_ADDRSTRLEN]; + + const char *conversion; + conversion = inet_ntop(AF_INET, &addr->sin_addr, ip, sizeof(ip)); + + if ((conversion != NULL) && (strcmp(ip, iface) == 0)) + { + // IP match + + struct sockaddr_in nativeAddr4 = *addr; + nativeAddr4.sin_port = htons(port); + + addr4 = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)]; + } + } + } + else if ((addr6 == nil) && (cursor->ifa_addr->sa_family == AF_INET6)) + { + // IPv6 + + const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cursor->ifa_addr; + + if (strcmp(cursor->ifa_name, iface) == 0) + { + // Name match + + struct sockaddr_in6 nativeAddr6 = *addr; + nativeAddr6.sin6_port = htons(port); + + addr6 = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)]; + } + else + { + char ip[INET6_ADDRSTRLEN]; + + const char *conversion; + conversion = inet_ntop(AF_INET6, &addr->sin6_addr, ip, sizeof(ip)); + + if ((conversion != NULL) && (strcmp(ip, iface) == 0)) + { + // IP match + + struct sockaddr_in6 nativeAddr6 = *addr; + nativeAddr6.sin6_port = htons(port); + + addr6 = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)]; + } + } + } + + cursor = cursor->ifa_next; + } + + freeifaddrs(addrs); + } + } + + if (interfaceAddr4Ptr) *interfaceAddr4Ptr = addr4; + if (interfaceAddr6Ptr) *interfaceAddr6Ptr = addr6; +} + +/** + * Converts a numeric hostname into its corresponding address. + * The hostname is expected to be an IPv4 or IPv6 address represented as a human-readable string. (e.g. 192.168.4.34) +**/ +- (void)convertNumericHost:(NSString *)numericHost + port:(uint16_t)port + intoAddress4:(NSData **)addr4Ptr + address6:(NSData **)addr6Ptr +{ + NSData *addr4 = nil; + NSData *addr6 = nil; + + if (numericHost) + { + NSString *portStr = [NSString stringWithFormat:@"%hu", port]; + + struct addrinfo hints, *res, *res0; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = AI_NUMERICHOST; // No name resolution should be attempted + + if (getaddrinfo([numericHost UTF8String], [portStr UTF8String], &hints, &res0) == 0) + { + for (res = res0; res; res = res->ai_next) + { + if ((addr4 == nil) && (res->ai_family == AF_INET)) + { + // Found IPv4 address + // Wrap the native address structure + addr4 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen]; + } + else if ((addr6 == nil) && (res->ai_family == AF_INET6)) + { + // Found IPv6 address + // Wrap the native address structure + addr6 = [NSData dataWithBytes:res->ai_addr length:res->ai_addrlen]; + } + } + freeaddrinfo(res0); + } + } + + if (addr4Ptr) *addr4Ptr = addr4; + if (addr6Ptr) *addr6Ptr = addr6; +} + +- (BOOL)isConnectedToAddress4:(NSData *)someAddr4 +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(flags & kDidConnect, @"Not connected"); + NSAssert(cachedConnectedAddress, @"Expected cached connected address"); + + if (cachedConnectedFamily != AF_INET) + { + return NO; + } + + const struct sockaddr_in *sSockaddr4 = (const struct sockaddr_in *)[someAddr4 bytes]; + const struct sockaddr_in *cSockaddr4 = (const struct sockaddr_in *)[cachedConnectedAddress bytes]; + + if (memcmp(&sSockaddr4->sin_addr, &cSockaddr4->sin_addr, sizeof(struct in_addr)) != 0) + { + return NO; + } + if (memcmp(&sSockaddr4->sin_port, &cSockaddr4->sin_port, sizeof(in_port_t)) != 0) + { + return NO; + } + + return YES; +} + +- (BOOL)isConnectedToAddress6:(NSData *)someAddr6 +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(flags & kDidConnect, @"Not connected"); + NSAssert(cachedConnectedAddress, @"Expected cached connected address"); + + if (cachedConnectedFamily != AF_INET6) + { + return NO; + } + + const struct sockaddr_in6 *sSockaddr6 = (const struct sockaddr_in6 *)[someAddr6 bytes]; + const struct sockaddr_in6 *cSockaddr6 = (const struct sockaddr_in6 *)[cachedConnectedAddress bytes]; + + if (memcmp(&sSockaddr6->sin6_addr, &cSockaddr6->sin6_addr, sizeof(struct in6_addr)) != 0) + { + return NO; + } + if (memcmp(&sSockaddr6->sin6_port, &cSockaddr6->sin6_port, sizeof(in_port_t)) != 0) + { + return NO; + } + + return YES; +} + +- (unsigned int)indexOfInterfaceAddr4:(NSData *)interfaceAddr4 +{ + if (interfaceAddr4 == nil) + return 0; + if ([interfaceAddr4 length] != sizeof(struct sockaddr_in)) + return 0; + + int result = 0; + const struct sockaddr_in *ifaceAddr = (const struct sockaddr_in *)[interfaceAddr4 bytes]; + + struct ifaddrs *addrs; + const struct ifaddrs *cursor; + + if ((getifaddrs(&addrs) == 0)) + { + cursor = addrs; + while (cursor != NULL) + { + if (cursor->ifa_addr->sa_family == AF_INET) + { + // IPv4 + + const struct sockaddr_in *addr = (const struct sockaddr_in *)(const void *)cursor->ifa_addr; + + if (memcmp(&addr->sin_addr, &ifaceAddr->sin_addr, sizeof(struct in_addr)) == 0) + { + result = if_nametoindex(cursor->ifa_name); + break; + } + } + + cursor = cursor->ifa_next; + } + + freeifaddrs(addrs); + } + + return result; +} + +- (unsigned int)indexOfInterfaceAddr6:(NSData *)interfaceAddr6 +{ + if (interfaceAddr6 == nil) + return 0; + if ([interfaceAddr6 length] != sizeof(struct sockaddr_in6)) + return 0; + + int result = 0; + const struct sockaddr_in6 *ifaceAddr = (const struct sockaddr_in6 *)[interfaceAddr6 bytes]; + + struct ifaddrs *addrs; + const struct ifaddrs *cursor; + + if ((getifaddrs(&addrs) == 0)) + { + cursor = addrs; + while (cursor != NULL) + { + if (cursor->ifa_addr->sa_family == AF_INET6) + { + // IPv6 + + const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)(const void *)cursor->ifa_addr; + + if (memcmp(&addr->sin6_addr, &ifaceAddr->sin6_addr, sizeof(struct in6_addr)) == 0) + { + result = if_nametoindex(cursor->ifa_name); + break; + } + } + + cursor = cursor->ifa_next; + } + + freeifaddrs(addrs); + } + + return result; +} + +- (void)setupSendAndReceiveSourcesForSocket4 +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + send4Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socket4FD, 0, socketQueue); + receive4Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket4FD, 0, socketQueue); + + // Setup event handlers + + dispatch_source_set_event_handler(send4Source, ^{ @autoreleasepool { + + LogVerbose(@"send4EventBlock"); + LogVerbose(@"dispatch_source_get_data(send4Source) = %lu", dispatch_source_get_data(send4Source)); + + self->flags |= kSock4CanAcceptBytes; + + // If we're ready to send data, do so immediately. + // Otherwise pause the send source or it will continue to fire over and over again. + + if (self->currentSend == nil) + { + LogVerbose(@"Nothing to send"); + [self suspendSend4Source]; + } + else if (self->currentSend->resolveInProgress) + { + LogVerbose(@"currentSend - waiting for address resolve"); + [self suspendSend4Source]; + } + else if (self->currentSend->filterInProgress) + { + LogVerbose(@"currentSend - waiting on sendFilter"); + [self suspendSend4Source]; + } + else + { + [self doSend]; + } + + }}); + + dispatch_source_set_event_handler(receive4Source, ^{ @autoreleasepool { + + LogVerbose(@"receive4EventBlock"); + + self->socket4FDBytesAvailable = dispatch_source_get_data(self->receive4Source); + LogVerbose(@"socket4FDBytesAvailable: %lu", socket4FDBytesAvailable); + + if (self->socket4FDBytesAvailable > 0) + [self doReceive]; + else + [self doReceiveEOF]; + + }}); + + // Setup cancel handlers + + __block int socketFDRefCount = 2; + + int theSocketFD = socket4FD; + + #if !OS_OBJECT_USE_OBJC + dispatch_source_t theSendSource = send4Source; + dispatch_source_t theReceiveSource = receive4Source; + #endif + + dispatch_source_set_cancel_handler(send4Source, ^{ + + LogVerbose(@"send4CancelBlock"); + + #if !OS_OBJECT_USE_OBJC + LogVerbose(@"dispatch_release(send4Source)"); + dispatch_release(theSendSource); + #endif + + if (--socketFDRefCount == 0) + { + LogVerbose(@"close(socket4FD)"); + close(theSocketFD); + } + }); + + dispatch_source_set_cancel_handler(receive4Source, ^{ + + LogVerbose(@"receive4CancelBlock"); + + #if !OS_OBJECT_USE_OBJC + LogVerbose(@"dispatch_release(receive4Source)"); + dispatch_release(theReceiveSource); + #endif + + if (--socketFDRefCount == 0) + { + LogVerbose(@"close(socket4FD)"); + close(theSocketFD); + } + }); + + // We will not be able to receive until the socket is bound to a port, + // either explicitly via bind, or implicitly by connect or by sending data. + // + // But we should be able to send immediately. + + socket4FDBytesAvailable = 0; + flags |= kSock4CanAcceptBytes; + + flags |= kSend4SourceSuspended; + flags |= kReceive4SourceSuspended; +} + +- (void)setupSendAndReceiveSourcesForSocket6 +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + send6Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socket6FD, 0, socketQueue); + receive6Source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socket6FD, 0, socketQueue); + + // Setup event handlers + + dispatch_source_set_event_handler(send6Source, ^{ @autoreleasepool { + + LogVerbose(@"send6EventBlock"); + LogVerbose(@"dispatch_source_get_data(send6Source) = %lu", dispatch_source_get_data(send6Source)); + + self->flags |= kSock6CanAcceptBytes; + + // If we're ready to send data, do so immediately. + // Otherwise pause the send source or it will continue to fire over and over again. + + if (self->currentSend == nil) + { + LogVerbose(@"Nothing to send"); + [self suspendSend6Source]; + } + else if (self->currentSend->resolveInProgress) + { + LogVerbose(@"currentSend - waiting for address resolve"); + [self suspendSend6Source]; + } + else if (self->currentSend->filterInProgress) + { + LogVerbose(@"currentSend - waiting on sendFilter"); + [self suspendSend6Source]; + } + else + { + [self doSend]; + } + + }}); + + dispatch_source_set_event_handler(receive6Source, ^{ @autoreleasepool { + + LogVerbose(@"receive6EventBlock"); + + self->socket6FDBytesAvailable = dispatch_source_get_data(self->receive6Source); + LogVerbose(@"socket6FDBytesAvailable: %lu", socket6FDBytesAvailable); + + if (self->socket6FDBytesAvailable > 0) + [self doReceive]; + else + [self doReceiveEOF]; + + }}); + + // Setup cancel handlers + + __block int socketFDRefCount = 2; + + int theSocketFD = socket6FD; + + #if !OS_OBJECT_USE_OBJC + dispatch_source_t theSendSource = send6Source; + dispatch_source_t theReceiveSource = receive6Source; + #endif + + dispatch_source_set_cancel_handler(send6Source, ^{ + + LogVerbose(@"send6CancelBlock"); + + #if !OS_OBJECT_USE_OBJC + LogVerbose(@"dispatch_release(send6Source)"); + dispatch_release(theSendSource); + #endif + + if (--socketFDRefCount == 0) + { + LogVerbose(@"close(socket6FD)"); + close(theSocketFD); + } + }); + + dispatch_source_set_cancel_handler(receive6Source, ^{ + + LogVerbose(@"receive6CancelBlock"); + + #if !OS_OBJECT_USE_OBJC + LogVerbose(@"dispatch_release(receive6Source)"); + dispatch_release(theReceiveSource); + #endif + + if (--socketFDRefCount == 0) + { + LogVerbose(@"close(socket6FD)"); + close(theSocketFD); + } + }); + + // We will not be able to receive until the socket is bound to a port, + // either explicitly via bind, or implicitly by connect or by sending data. + // + // But we should be able to send immediately. + + socket6FDBytesAvailable = 0; + flags |= kSock6CanAcceptBytes; + + flags |= kSend6SourceSuspended; + flags |= kReceive6SourceSuspended; +} + +- (BOOL)createSocket4:(BOOL)useIPv4 socket6:(BOOL)useIPv6 error:(NSError * __autoreleasing *)errPtr +{ + LogTrace(); + + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(((flags & kDidCreateSockets) == 0), @"Sockets have already been created"); + + // CreateSocket Block + // This block will be invoked below. + + int(^createSocket)(int) = ^int (int domain) { + + int socketFD = socket(domain, SOCK_DGRAM, 0); + + if (socketFD == SOCKET_NULL) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error in socket() function"]; + + return SOCKET_NULL; + } + + int status; + + // Set socket options + + status = fcntl(socketFD, F_SETFL, O_NONBLOCK); + if (status == -1) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error enabling non-blocking IO on socket (fcntl)"]; + + close(socketFD); + return SOCKET_NULL; + } + + int reuseaddr = 1; + status = setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)); + if (status == -1) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error enabling address reuse (setsockopt)"]; + + close(socketFD); + return SOCKET_NULL; + } + + int nosigpipe = 1; + status = setsockopt(socketFD, SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe, sizeof(nosigpipe)); + if (status == -1) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error disabling sigpipe (setsockopt)"]; + + close(socketFD); + return SOCKET_NULL; + } + + /** + * The theoretical maximum size of any IPv4 UDP packet is UINT16_MAX = 65535. + * The theoretical maximum size of any IPv6 UDP packet is UINT32_MAX = 4294967295. + * + * The default maximum size of the UDP buffer in iOS is 9216 bytes. + * + * This is the reason of #222(GCD does not necessarily return the size of an entire UDP packet) and + * #535(GCDAsyncUDPSocket can not send data when data is greater than 9K) + * + * + * Enlarge the maximum size of UDP packet. + * I can not ensure the protocol type now so that the max size is set to 65535 :) + **/ + + status = setsockopt(socketFD, SOL_SOCKET, SO_SNDBUF, (const char*)&self->maxSendSize, sizeof(int)); + if (status == -1) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error setting send buffer size (setsockopt)"]; + close(socketFD); + return SOCKET_NULL; + } + + status = setsockopt(socketFD, SOL_SOCKET, SO_RCVBUF, (const char*)&self->maxSendSize, sizeof(int)); + if (status == -1) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error setting receive buffer size (setsockopt)"]; + close(socketFD); + return SOCKET_NULL; + } + + + return socketFD; + }; + + // Create sockets depending upon given configuration. + + if (useIPv4) + { + LogVerbose(@"Creating IPv4 socket"); + + socket4FD = createSocket(AF_INET); + if (socket4FD == SOCKET_NULL) + { + // errPtr set in local createSocket() block + return NO; + } + } + + if (useIPv6) + { + LogVerbose(@"Creating IPv6 socket"); + + socket6FD = createSocket(AF_INET6); + if (socket6FD == SOCKET_NULL) + { + // errPtr set in local createSocket() block + + if (socket4FD != SOCKET_NULL) + { + close(socket4FD); + socket4FD = SOCKET_NULL; + } + + return NO; + } + } + + // Setup send and receive sources + + if (useIPv4) + [self setupSendAndReceiveSourcesForSocket4]; + if (useIPv6) + [self setupSendAndReceiveSourcesForSocket6]; + + flags |= kDidCreateSockets; + return YES; +} + +- (BOOL)createSockets:(NSError **)errPtr +{ + LogTrace(); + + BOOL useIPv4 = [self isIPv4Enabled]; + BOOL useIPv6 = [self isIPv6Enabled]; + + return [self createSocket4:useIPv4 socket6:useIPv6 error:errPtr]; +} + +- (void)suspendSend4Source +{ + if (send4Source && !(flags & kSend4SourceSuspended)) + { + LogVerbose(@"dispatch_suspend(send4Source)"); + + dispatch_suspend(send4Source); + flags |= kSend4SourceSuspended; + } +} + +- (void)suspendSend6Source +{ + if (send6Source && !(flags & kSend6SourceSuspended)) + { + LogVerbose(@"dispatch_suspend(send6Source)"); + + dispatch_suspend(send6Source); + flags |= kSend6SourceSuspended; + } +} + +- (void)resumeSend4Source +{ + if (send4Source && (flags & kSend4SourceSuspended)) + { + LogVerbose(@"dispatch_resume(send4Source)"); + + dispatch_resume(send4Source); + flags &= ~kSend4SourceSuspended; + } +} + +- (void)resumeSend6Source +{ + if (send6Source && (flags & kSend6SourceSuspended)) + { + LogVerbose(@"dispatch_resume(send6Source)"); + + dispatch_resume(send6Source); + flags &= ~kSend6SourceSuspended; + } +} + +- (void)suspendReceive4Source +{ + if (receive4Source && !(flags & kReceive4SourceSuspended)) + { + LogVerbose(@"dispatch_suspend(receive4Source)"); + + dispatch_suspend(receive4Source); + flags |= kReceive4SourceSuspended; + } +} + +- (void)suspendReceive6Source +{ + if (receive6Source && !(flags & kReceive6SourceSuspended)) + { + LogVerbose(@"dispatch_suspend(receive6Source)"); + + dispatch_suspend(receive6Source); + flags |= kReceive6SourceSuspended; + } +} + +- (void)resumeReceive4Source +{ + if (receive4Source && (flags & kReceive4SourceSuspended)) + { + LogVerbose(@"dispatch_resume(receive4Source)"); + + dispatch_resume(receive4Source); + flags &= ~kReceive4SourceSuspended; + } +} + +- (void)resumeReceive6Source +{ + if (receive6Source && (flags & kReceive6SourceSuspended)) + { + LogVerbose(@"dispatch_resume(receive6Source)"); + + dispatch_resume(receive6Source); + flags &= ~kReceive6SourceSuspended; + } +} + +- (void)closeSocket4 +{ + if (socket4FD != SOCKET_NULL) + { + LogVerbose(@"dispatch_source_cancel(send4Source)"); + dispatch_source_cancel(send4Source); + + LogVerbose(@"dispatch_source_cancel(receive4Source)"); + dispatch_source_cancel(receive4Source); + + // For some crazy reason (in my opinion), cancelling a dispatch source doesn't + // invoke the cancel handler if the dispatch source is paused. + // So we have to unpause the source if needed. + // This allows the cancel handler to be run, which in turn releases the source and closes the socket. + + [self resumeSend4Source]; + [self resumeReceive4Source]; + + // The sockets will be closed by the cancel handlers of the corresponding source + + send4Source = NULL; + receive4Source = NULL; + + socket4FD = SOCKET_NULL; + + // Clear socket states + + socket4FDBytesAvailable = 0; + flags &= ~kSock4CanAcceptBytes; + + // Clear cached info + + cachedLocalAddress4 = nil; + cachedLocalHost4 = nil; + cachedLocalPort4 = 0; + } +} + +- (void)closeSocket6 +{ + if (socket6FD != SOCKET_NULL) + { + LogVerbose(@"dispatch_source_cancel(send6Source)"); + dispatch_source_cancel(send6Source); + + LogVerbose(@"dispatch_source_cancel(receive6Source)"); + dispatch_source_cancel(receive6Source); + + // For some crazy reason (in my opinion), cancelling a dispatch source doesn't + // invoke the cancel handler if the dispatch source is paused. + // So we have to unpause the source if needed. + // This allows the cancel handler to be run, which in turn releases the source and closes the socket. + + [self resumeSend6Source]; + [self resumeReceive6Source]; + + send6Source = NULL; + receive6Source = NULL; + + // The sockets will be closed by the cancel handlers of the corresponding source + + socket6FD = SOCKET_NULL; + + // Clear socket states + + socket6FDBytesAvailable = 0; + flags &= ~kSock6CanAcceptBytes; + + // Clear cached info + + cachedLocalAddress6 = nil; + cachedLocalHost6 = nil; + cachedLocalPort6 = 0; + } +} + +- (void)closeSockets +{ + [self closeSocket4]; + [self closeSocket6]; + + flags &= ~kDidCreateSockets; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Diagnostics +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)getLocalAddress:(NSData **)dataPtr + host:(NSString **)hostPtr + port:(uint16_t *)portPtr + forSocket:(int)socketFD + withFamily:(int)socketFamily +{ + + NSData *data = nil; + NSString *host = nil; + uint16_t port = 0; + + if (socketFamily == AF_INET) + { + struct sockaddr_in sockaddr4; + socklen_t sockaddr4len = sizeof(sockaddr4); + + if (getsockname(socketFD, (struct sockaddr *)&sockaddr4, &sockaddr4len) == 0) + { + data = [NSData dataWithBytes:&sockaddr4 length:sockaddr4len]; + host = [[self class] hostFromSockaddr4:&sockaddr4]; + port = [[self class] portFromSockaddr4:&sockaddr4]; + } + else + { + LogWarn(@"Error in getsockname: %@", [self errnoError]); + } + } + else if (socketFamily == AF_INET6) + { + struct sockaddr_in6 sockaddr6; + socklen_t sockaddr6len = sizeof(sockaddr6); + + if (getsockname(socketFD, (struct sockaddr *)&sockaddr6, &sockaddr6len) == 0) + { + data = [NSData dataWithBytes:&sockaddr6 length:sockaddr6len]; + host = [[self class] hostFromSockaddr6:&sockaddr6]; + port = [[self class] portFromSockaddr6:&sockaddr6]; + } + else + { + LogWarn(@"Error in getsockname: %@", [self errnoError]); + } + } + + if (dataPtr) *dataPtr = data; + if (hostPtr) *hostPtr = host; + if (portPtr) *portPtr = port; + + return (data != nil); +} + +- (void)maybeUpdateCachedLocalAddress4Info +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if ( cachedLocalAddress4 || ((flags & kDidBind) == 0) || (socket4FD == SOCKET_NULL) ) + { + return; + } + + NSData *address = nil; + NSString *host = nil; + uint16_t port = 0; + + if ([self getLocalAddress:&address host:&host port:&port forSocket:socket4FD withFamily:AF_INET]) + { + + cachedLocalAddress4 = address; + cachedLocalHost4 = host; + cachedLocalPort4 = port; + } +} + +- (void)maybeUpdateCachedLocalAddress6Info +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if ( cachedLocalAddress6 || ((flags & kDidBind) == 0) || (socket6FD == SOCKET_NULL) ) + { + return; + } + + NSData *address = nil; + NSString *host = nil; + uint16_t port = 0; + + if ([self getLocalAddress:&address host:&host port:&port forSocket:socket6FD withFamily:AF_INET6]) + { + + cachedLocalAddress6 = address; + cachedLocalHost6 = host; + cachedLocalPort6 = port; + } +} + +- (NSData *)localAddress +{ + __block NSData *result = nil; + + dispatch_block_t block = ^{ + + if (self->socket4FD != SOCKET_NULL) + { + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalAddress4; + } + else + { + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalAddress6; + } + + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSString *)localHost +{ + __block NSString *result = nil; + + dispatch_block_t block = ^{ + + if (self->socket4FD != SOCKET_NULL) + { + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalHost4; + } + else + { + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalHost6; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (uint16_t)localPort +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + if (self->socket4FD != SOCKET_NULL) + { + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalPort4; + } + else + { + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalPort6; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSData *)localAddress_IPv4 +{ + __block NSData *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalAddress4; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSString *)localHost_IPv4 +{ + __block NSString *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalHost4; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (uint16_t)localPort_IPv4 +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress4Info]; + result = self->cachedLocalPort4; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSData *)localAddress_IPv6 +{ + __block NSData *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalAddress6; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSString *)localHost_IPv6 +{ + __block NSString *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalHost6; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (uint16_t)localPort_IPv6 +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedLocalAddress6Info]; + result = self->cachedLocalPort6; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (void)maybeUpdateCachedConnectedAddressInfo +{ + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if (cachedConnectedAddress || (flags & kDidConnect) == 0) + { + return; + } + + NSData *data = nil; + NSString *host = nil; + uint16_t port = 0; + int family = AF_UNSPEC; + + if (socket4FD != SOCKET_NULL) + { + struct sockaddr_in sockaddr4; + socklen_t sockaddr4len = sizeof(sockaddr4); + + if (getpeername(socket4FD, (struct sockaddr *)&sockaddr4, &sockaddr4len) == 0) + { + data = [NSData dataWithBytes:&sockaddr4 length:sockaddr4len]; + host = [[self class] hostFromSockaddr4:&sockaddr4]; + port = [[self class] portFromSockaddr4:&sockaddr4]; + family = AF_INET; + } + else + { + LogWarn(@"Error in getpeername: %@", [self errnoError]); + } + } + else if (socket6FD != SOCKET_NULL) + { + struct sockaddr_in6 sockaddr6; + socklen_t sockaddr6len = sizeof(sockaddr6); + + if (getpeername(socket6FD, (struct sockaddr *)&sockaddr6, &sockaddr6len) == 0) + { + data = [NSData dataWithBytes:&sockaddr6 length:sockaddr6len]; + host = [[self class] hostFromSockaddr6:&sockaddr6]; + port = [[self class] portFromSockaddr6:&sockaddr6]; + family = AF_INET6; + } + else + { + LogWarn(@"Error in getpeername: %@", [self errnoError]); + } + } + + + cachedConnectedAddress = data; + cachedConnectedHost = host; + cachedConnectedPort = port; + cachedConnectedFamily = family; +} + +- (NSData *)connectedAddress +{ + __block NSData *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedConnectedAddressInfo]; + result = self->cachedConnectedAddress; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (NSString *)connectedHost +{ + __block NSString *result = nil; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedConnectedAddressInfo]; + result = self->cachedConnectedHost; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (uint16_t)connectedPort +{ + __block uint16_t result = 0; + + dispatch_block_t block = ^{ + + [self maybeUpdateCachedConnectedAddressInfo]; + result = self->cachedConnectedPort; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, AutoreleasedBlock(block)); + + return result; +} + +- (BOOL)isConnected +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + result = (self->flags & kDidConnect) ? YES : NO; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (BOOL)isClosed +{ + __block BOOL result = YES; + + dispatch_block_t block = ^{ + + result = (self->flags & kDidCreateSockets) ? NO : YES; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (BOOL)isIPv4 +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + + if (self->flags & kDidCreateSockets) + { + result = (self->socket4FD != SOCKET_NULL); + } + else + { + result = [self isIPv4Enabled]; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +- (BOOL)isIPv6 +{ + __block BOOL result = NO; + + dispatch_block_t block = ^{ + + if (self->flags & kDidCreateSockets) + { + result = (self->socket6FD != SOCKET_NULL); + } + else + { + result = [self isIPv6Enabled]; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Binding +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * This method runs through the various checks required prior to a bind attempt. + * It is shared between the various bind methods. +**/ +- (BOOL)preBind:(NSError **)errPtr +{ + if (![self preOp:errPtr]) + { + return NO; + } + + if (flags & kDidBind) + { + if (errPtr) + { + NSString *msg = @"Cannot bind a socket more than once."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + if ((flags & kConnecting) || (flags & kDidConnect)) + { + if (errPtr) + { + NSString *msg = @"Cannot bind after connecting. If needed, bind first, then connect."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO; + BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO; + + if (isIPv4Disabled && isIPv6Disabled) // Must have IPv4 or IPv6 enabled + { + if (errPtr) + { + NSString *msg = @"Both IPv4 and IPv6 have been disabled. Must enable at least one protocol first."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + return YES; +} + +- (BOOL)bindToPort:(uint16_t)port error:(NSError **)errPtr +{ + return [self bindToPort:port interface:nil error:errPtr]; +} + +- (BOOL)bindToPort:(uint16_t)port interface:(NSString *)interface error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + // Run through sanity checks + + if (![self preBind:&err]) + { + return_from_block; + } + + // Check the given interface + + NSData *interface4 = nil; + NSData *interface6 = nil; + + [self convertIntefaceDescription:interface port:port intoAddress4:&interface4 address6:&interface6]; + + if ((interface4 == nil) && (interface6 == nil)) + { + NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address."; + err = [self badParamError:msg]; + + return_from_block; + } + + BOOL isIPv4Disabled = (self->config & kIPv4Disabled) ? YES : NO; + BOOL isIPv6Disabled = (self->config & kIPv6Disabled) ? YES : NO; + + if (isIPv4Disabled && (interface6 == nil)) + { + NSString *msg = @"IPv4 has been disabled and specified interface doesn't support IPv6."; + err = [self badParamError:msg]; + + return_from_block; + } + + if (isIPv6Disabled && (interface4 == nil)) + { + NSString *msg = @"IPv6 has been disabled and specified interface doesn't support IPv4."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Determine protocol(s) + + BOOL useIPv4 = !isIPv4Disabled && (interface4 != nil); + BOOL useIPv6 = !isIPv6Disabled && (interface6 != nil); + + // Create the socket(s) if needed + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSocket4:useIPv4 socket6:useIPv6 error:&err]) + { + return_from_block; + } + } + + // Bind the socket(s) + + LogVerbose(@"Binding socket to port(%hu) interface(%@)", port, interface); + + if (useIPv4) + { + int status = bind(self->socket4FD, (const struct sockaddr *)[interface4 bytes], (socklen_t)[interface4 length]); + if (status == -1) + { + [self closeSockets]; + + NSString *reason = @"Error in bind() function"; + err = [self errnoErrorWithReason:reason]; + + return_from_block; + } + } + + if (useIPv6) + { + int status = bind(self->socket6FD, (const struct sockaddr *)[interface6 bytes], (socklen_t)[interface6 length]); + if (status == -1) + { + [self closeSockets]; + + NSString *reason = @"Error in bind() function"; + err = [self errnoErrorWithReason:reason]; + + return_from_block; + } + } + + // Update flags + + self->flags |= kDidBind; + + if (!useIPv4) self->flags |= kIPv4Deactivated; + if (!useIPv6) self->flags |= kIPv6Deactivated; + + result = YES; + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error binding to port/interface: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (BOOL)bindToAddress:(NSData *)localAddr error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + // Run through sanity checks + + if (![self preBind:&err]) + { + return_from_block; + } + + // Check the given address + + int addressFamily = [[self class] familyFromAddress:localAddr]; + + if (addressFamily == AF_UNSPEC) + { + NSString *msg = @"A valid IPv4 or IPv6 address was not given"; + err = [self badParamError:msg]; + + return_from_block; + } + + NSData *localAddr4 = (addressFamily == AF_INET) ? localAddr : nil; + NSData *localAddr6 = (addressFamily == AF_INET6) ? localAddr : nil; + + BOOL isIPv4Disabled = (self->config & kIPv4Disabled) ? YES : NO; + BOOL isIPv6Disabled = (self->config & kIPv6Disabled) ? YES : NO; + + if (isIPv4Disabled && localAddr4) + { + NSString *msg = @"IPv4 has been disabled and an IPv4 address was passed."; + err = [self badParamError:msg]; + + return_from_block; + } + + if (isIPv6Disabled && localAddr6) + { + NSString *msg = @"IPv6 has been disabled and an IPv6 address was passed."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Determine protocol(s) + + BOOL useIPv4 = !isIPv4Disabled && (localAddr4 != nil); + BOOL useIPv6 = !isIPv6Disabled && (localAddr6 != nil); + + // Create the socket(s) if needed + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSocket4:useIPv4 socket6:useIPv6 error:&err]) + { + return_from_block; + } + } + + // Bind the socket(s) + + if (useIPv4) + { + LogVerbose(@"Binding socket to address(%@:%hu)", + [[self class] hostFromAddress:localAddr4], + [[self class] portFromAddress:localAddr4]); + + int status = bind(self->socket4FD, (const struct sockaddr *)[localAddr4 bytes], (socklen_t)[localAddr4 length]); + if (status == -1) + { + [self closeSockets]; + + NSString *reason = @"Error in bind() function"; + err = [self errnoErrorWithReason:reason]; + + return_from_block; + } + } + else + { + LogVerbose(@"Binding socket to address(%@:%hu)", + [[self class] hostFromAddress:localAddr6], + [[self class] portFromAddress:localAddr6]); + + int status = bind(self->socket6FD, (const struct sockaddr *)[localAddr6 bytes], (socklen_t)[localAddr6 length]); + if (status == -1) + { + [self closeSockets]; + + NSString *reason = @"Error in bind() function"; + err = [self errnoErrorWithReason:reason]; + + return_from_block; + } + } + + // Update flags + + self->flags |= kDidBind; + + if (!useIPv4) self->flags |= kIPv4Deactivated; + if (!useIPv6) self->flags |= kIPv6Deactivated; + + result = YES; + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error binding to address: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Connecting +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * This method runs through the various checks required prior to a connect attempt. + * It is shared between the various connect methods. +**/ +- (BOOL)preConnect:(NSError **)errPtr +{ + if (![self preOp:errPtr]) + { + return NO; + } + + if ((flags & kConnecting) || (flags & kDidConnect)) + { + if (errPtr) + { + NSString *msg = @"Cannot connect a socket more than once."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + BOOL isIPv4Disabled = (config & kIPv4Disabled) ? YES : NO; + BOOL isIPv6Disabled = (config & kIPv6Disabled) ? YES : NO; + + if (isIPv4Disabled && isIPv6Disabled) // Must have IPv4 or IPv6 enabled + { + if (errPtr) + { + NSString *msg = @"Both IPv4 and IPv6 have been disabled. Must enable at least one protocol first."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + return YES; +} + +- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + // Run through sanity checks. + + if (![self preConnect:&err]) + { + return_from_block; + } + + // Check parameter(s) + + if (host == nil) + { + NSString *msg = @"The host param is nil. Should be domain name or IP address string."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Create the socket(s) if needed + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + // Create special connect packet + + GCDAsyncUdpSpecialPacket *packet = [[GCDAsyncUdpSpecialPacket alloc] init]; + packet->resolveInProgress = YES; + + // Start asynchronous DNS resolve for host:port on background queue + + LogVerbose(@"Dispatching DNS resolve for connect..."); + + [self asyncResolveHost:host port:port withCompletionBlock:^(NSArray *addresses, NSError *error) { + + // The asyncResolveHost:port:: method asynchronously dispatches a task onto the global concurrent queue, + // and immediately returns. Once the async resolve task completes, + // this block is executed on our socketQueue. + + packet->resolveInProgress = NO; + + packet->addresses = addresses; + packet->error = error; + + [self maybeConnect]; + }]; + + // Updates flags, add connect packet to send queue, and pump send queue + + self->flags |= kConnecting; + + [self->sendQueue addObject:packet]; + [self maybeDequeueSend]; + + result = YES; + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error connecting to host/port: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + // Run through sanity checks. + + if (![self preConnect:&err]) + { + return_from_block; + } + + // Check parameter(s) + + if (remoteAddr == nil) + { + NSString *msg = @"The address param is nil. Should be a valid address."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Create the socket(s) if needed + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + // The remoteAddr parameter could be of type NSMutableData. + // So we copy it to be safe. + + NSData *address = [remoteAddr copy]; + NSArray *addresses = [NSArray arrayWithObject:address]; + + GCDAsyncUdpSpecialPacket *packet = [[GCDAsyncUdpSpecialPacket alloc] init]; + packet->addresses = addresses; + + // Updates flags, add connect packet to send queue, and pump send queue + + self->flags |= kConnecting; + + [self->sendQueue addObject:packet]; + [self maybeDequeueSend]; + + result = YES; + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error connecting to address: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (void)maybeConnect +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + + BOOL sendQueueReady = [currentSend isKindOfClass:[GCDAsyncUdpSpecialPacket class]]; + + if (sendQueueReady) + { + GCDAsyncUdpSpecialPacket *connectPacket = (GCDAsyncUdpSpecialPacket *)currentSend; + + if (connectPacket->resolveInProgress) + { + LogVerbose(@"Waiting for DNS resolve..."); + } + else + { + if (connectPacket->error) + { + [self notifyDidNotConnect:connectPacket->error]; + } + else + { + NSData *address = nil; + NSError *error = nil; + + int addressFamily = [self getAddress:&address error:&error fromAddresses:connectPacket->addresses]; + + // Perform connect + + BOOL result = NO; + + switch (addressFamily) + { + case AF_INET : result = [self connectWithAddress4:address error:&error]; break; + case AF_INET6 : result = [self connectWithAddress6:address error:&error]; break; + } + + if (result) + { + flags |= kDidBind; + flags |= kDidConnect; + + cachedConnectedAddress = address; + cachedConnectedHost = [[self class] hostFromAddress:address]; + cachedConnectedPort = [[self class] portFromAddress:address]; + cachedConnectedFamily = addressFamily; + + [self notifyDidConnectToAddress:address]; + } + else + { + [self notifyDidNotConnect:error]; + } + } + + flags &= ~kConnecting; + + [self endCurrentSend]; + [self maybeDequeueSend]; + } + } +} + +- (BOOL)connectWithAddress4:(NSData *)address4 error:(NSError **)errPtr +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + int status = connect(socket4FD, (const struct sockaddr *)[address4 bytes], (socklen_t)[address4 length]); + if (status != 0) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error in connect() function"]; + + return NO; + } + + [self closeSocket6]; + flags |= kIPv6Deactivated; + + return YES; +} + +- (BOOL)connectWithAddress6:(NSData *)address6 error:(NSError **)errPtr +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + int status = connect(socket6FD, (const struct sockaddr *)[address6 bytes], (socklen_t)[address6 length]); + if (status != 0) + { + if (errPtr) + *errPtr = [self errnoErrorWithReason:@"Error in connect() function"]; + + return NO; + } + + [self closeSocket4]; + flags |= kIPv4Deactivated; + + return YES; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Multicast +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)preJoin:(NSError **)errPtr +{ + if (![self preOp:errPtr]) + { + return NO; + } + + if (!(flags & kDidBind)) + { + if (errPtr) + { + NSString *msg = @"Must bind a socket before joining a multicast group."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + if ((flags & kConnecting) || (flags & kDidConnect)) + { + if (errPtr) + { + NSString *msg = @"Cannot join a multicast group if connected."; + *errPtr = [self badConfigError:msg]; + } + return NO; + } + + return YES; +} + +- (BOOL)joinMulticastGroup:(NSString *)group error:(NSError **)errPtr +{ + return [self joinMulticastGroup:group onInterface:nil error:errPtr]; +} + +- (BOOL)joinMulticastGroup:(NSString *)group onInterface:(NSString *)interface error:(NSError **)errPtr +{ + // IP_ADD_MEMBERSHIP == IPV6_JOIN_GROUP + return [self performMulticastRequest:IP_ADD_MEMBERSHIP forGroup:group onInterface:interface error:errPtr]; +} + +- (BOOL)leaveMulticastGroup:(NSString *)group error:(NSError **)errPtr +{ + return [self leaveMulticastGroup:group onInterface:nil error:errPtr]; +} + +- (BOOL)leaveMulticastGroup:(NSString *)group onInterface:(NSString *)interface error:(NSError **)errPtr +{ + // IP_DROP_MEMBERSHIP == IPV6_LEAVE_GROUP + return [self performMulticastRequest:IP_DROP_MEMBERSHIP forGroup:group onInterface:interface error:errPtr]; +} + +- (BOOL)performMulticastRequest:(int)requestType + forGroup:(NSString *)group + onInterface:(NSString *)interface + error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + // Run through sanity checks + + if (![self preJoin:&err]) + { + return_from_block; + } + + // Convert group to address + + NSData *groupAddr4 = nil; + NSData *groupAddr6 = nil; + + [self convertNumericHost:group port:0 intoAddress4:&groupAddr4 address6:&groupAddr6]; + + if ((groupAddr4 == nil) && (groupAddr6 == nil)) + { + NSString *msg = @"Unknown group. Specify valid group IP address."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Convert interface to address + + NSData *interfaceAddr4 = nil; + NSData *interfaceAddr6 = nil; + + [self convertIntefaceDescription:interface port:0 intoAddress4:&interfaceAddr4 address6:&interfaceAddr6]; + + if ((interfaceAddr4 == nil) && (interfaceAddr6 == nil)) + { + NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\") or IP address."; + err = [self badParamError:msg]; + + return_from_block; + } + + // Perform join + + if ((self->socket4FD != SOCKET_NULL) && groupAddr4 && interfaceAddr4) + { + const struct sockaddr_in *nativeGroup = (const struct sockaddr_in *)[groupAddr4 bytes]; + const struct sockaddr_in *nativeIface = (const struct sockaddr_in *)[interfaceAddr4 bytes]; + + struct ip_mreq imreq; + imreq.imr_multiaddr = nativeGroup->sin_addr; + imreq.imr_interface = nativeIface->sin_addr; + + int status = setsockopt(self->socket4FD, IPPROTO_IP, requestType, (const void *)&imreq, sizeof(imreq)); + if (status != 0) + { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + + return_from_block; + } + + // Using IPv4 only + [self closeSocket6]; + + result = YES; + } + else if ((self->socket6FD != SOCKET_NULL) && groupAddr6 && interfaceAddr6) + { + const struct sockaddr_in6 *nativeGroup = (const struct sockaddr_in6 *)[groupAddr6 bytes]; + + struct ipv6_mreq imreq; + imreq.ipv6mr_multiaddr = nativeGroup->sin6_addr; + imreq.ipv6mr_interface = [self indexOfInterfaceAddr6:interfaceAddr6]; + + int status = setsockopt(self->socket6FD, IPPROTO_IPV6, requestType, (const void *)&imreq, sizeof(imreq)); + if (status != 0) + { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + + return_from_block; + } + + // Using IPv6 only + [self closeSocket4]; + + result = YES; + } + else + { + NSString *msg = @"Socket, group, and interface do not have matching IP versions"; + err = [self badParamError:msg]; + + return_from_block; + } + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (BOOL)sendIPv4MulticastOnInterface:(NSString*)interface error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + if (![self preOp:&err]) + { + return_from_block; + } + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + // Convert interface to address + + NSData *interfaceAddr4 = nil; + NSData *interfaceAddr6 = nil; + + [self convertIntefaceDescription:interface port:0 intoAddress4:&interfaceAddr4 address6:&interfaceAddr6]; + + if (interfaceAddr4 == nil) + { + NSString *msg = @"Unknown interface. Specify valid interface by IP address."; + err = [self badParamError:msg]; + return_from_block; + } + + if (self->socket4FD != SOCKET_NULL) { + const struct sockaddr_in *nativeIface = (struct sockaddr_in *)[interfaceAddr4 bytes]; + struct in_addr interface_addr = nativeIface->sin_addr; + int status = setsockopt(self->socket4FD, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)); + if (status != 0) { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + return_from_block; + } + result = YES; + } + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (BOOL)sendIPv6MulticastOnInterface:(NSString*)interface error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + if (![self preOp:&err]) + { + return_from_block; + } + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + // Convert interface to address + + NSData *interfaceAddr4 = nil; + NSData *interfaceAddr6 = nil; + + [self convertIntefaceDescription:interface port:0 intoAddress4:&interfaceAddr4 address6:&interfaceAddr6]; + + if (interfaceAddr6 == nil) + { + NSString *msg = @"Unknown interface. Specify valid interface by name (e.g. \"en1\")."; + err = [self badParamError:msg]; + return_from_block; + } + + if ((self->socket6FD != SOCKET_NULL)) { + uint32_t scope_id = [self indexOfInterfaceAddr6:interfaceAddr6]; + int status = setsockopt(self->socket6FD, IPPROTO_IPV6, IPV6_MULTICAST_IF, &scope_id, sizeof(scope_id)); + if (status != 0) { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + return_from_block; + } + result = YES; + } + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (errPtr) + *errPtr = err; + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Reuse port +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)enableReusePort:(BOOL)flag error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + if (![self preOp:&err]) + { + return_from_block; + } + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + int value = flag ? 1 : 0; + if (self->socket4FD != SOCKET_NULL) + { + int error = setsockopt(self->socket4FD, SOL_SOCKET, SO_REUSEPORT, (const void *)&value, sizeof(value)); + + if (error) + { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + + return_from_block; + } + result = YES; + } + + if (self->socket6FD != SOCKET_NULL) + { + int error = setsockopt(self->socket6FD, SOL_SOCKET, SO_REUSEPORT, (const void *)&value, sizeof(value)); + + if (error) + { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + + return_from_block; + } + result = YES; + } + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (errPtr) + *errPtr = err; + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Broadcast +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr +{ + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ @autoreleasepool { + + if (![self preOp:&err]) + { + return_from_block; + } + + if ((self->flags & kDidCreateSockets) == 0) + { + if (![self createSockets:&err]) + { + return_from_block; + } + } + + if (self->socket4FD != SOCKET_NULL) + { + int value = flag ? 1 : 0; + int error = setsockopt(self->socket4FD, SOL_SOCKET, SO_BROADCAST, (const void *)&value, sizeof(value)); + + if (error) + { + err = [self errnoErrorWithReason:@"Error in setsockopt() function"]; + + return_from_block; + } + result = YES; + } + + // IPv6 does not implement broadcast, the ability to send a packet to all hosts on the attached link. + // The same effect can be achieved by sending a packet to the link-local all hosts multicast group. + + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (errPtr) + *errPtr = err; + + return result; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Sending +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)sendData:(NSData *)data withTag:(long)tag +{ + [self sendData:data withTimeout:-1.0 tag:tag]; +} + +- (void)sendData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag +{ + LogTrace(); + + if ([data length] == 0) + { + LogWarn(@"Ignoring attempt to send nil/empty data."); + return; + } + + + + GCDAsyncUdpSendPacket *packet = [[GCDAsyncUdpSendPacket alloc] initWithData:data timeout:timeout tag:tag]; + + dispatch_async(socketQueue, ^{ @autoreleasepool { + + [self->sendQueue addObject:packet]; + [self maybeDequeueSend]; + }}); + +} + +- (void)sendData:(NSData *)data + toHost:(NSString *)host + port:(uint16_t)port + withTimeout:(NSTimeInterval)timeout + tag:(long)tag +{ + LogTrace(); + + if ([data length] == 0) + { + LogWarn(@"Ignoring attempt to send nil/empty data."); + return; + } + + GCDAsyncUdpSendPacket *packet = [[GCDAsyncUdpSendPacket alloc] initWithData:data timeout:timeout tag:tag]; + packet->resolveInProgress = YES; + + [self asyncResolveHost:host port:port withCompletionBlock:^(NSArray *addresses, NSError *error) { + + // The asyncResolveHost:port:: method asynchronously dispatches a task onto the global concurrent queue, + // and immediately returns. Once the async resolve task completes, + // this block is executed on our socketQueue. + + packet->resolveInProgress = NO; + + packet->resolvedAddresses = addresses; + packet->resolveError = error; + + if (packet == self->currentSend) + { + LogVerbose(@"currentSend - address resolved"); + [self doPreSend]; + } + }]; + + dispatch_async(socketQueue, ^{ @autoreleasepool { + + [self->sendQueue addObject:packet]; + [self maybeDequeueSend]; + + }}); + +} + +- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag +{ + LogTrace(); + + if ([data length] == 0) + { + LogWarn(@"Ignoring attempt to send nil/empty data."); + return; + } + + GCDAsyncUdpSendPacket *packet = [[GCDAsyncUdpSendPacket alloc] initWithData:data timeout:timeout tag:tag]; + packet->addressFamily = [GCDAsyncUdpSocket familyFromAddress:remoteAddr]; + packet->address = remoteAddr; + + dispatch_async(socketQueue, ^{ @autoreleasepool { + + [self->sendQueue addObject:packet]; + [self maybeDequeueSend]; + }}); +} + +- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock withQueue:(dispatch_queue_t)filterQueue +{ + [self setSendFilter:filterBlock withQueue:filterQueue isAsynchronous:YES]; +} + +- (void)setSendFilter:(GCDAsyncUdpSocketSendFilterBlock)filterBlock + withQueue:(dispatch_queue_t)filterQueue + isAsynchronous:(BOOL)isAsynchronous +{ + GCDAsyncUdpSocketSendFilterBlock newFilterBlock = NULL; + dispatch_queue_t newFilterQueue = NULL; + + if (filterBlock) + { + NSAssert(filterQueue, @"Must provide a dispatch_queue in which to run the filter block."); + + newFilterBlock = [filterBlock copy]; + newFilterQueue = filterQueue; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(newFilterQueue); + #endif + } + + dispatch_block_t block = ^{ + + #if !OS_OBJECT_USE_OBJC + if (self->sendFilterQueue) dispatch_release(self->sendFilterQueue); + #endif + + self->sendFilterBlock = newFilterBlock; + self->sendFilterQueue = newFilterQueue; + self->sendFilterAsync = isAsynchronous; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)maybeDequeueSend +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + // If we don't have a send operation already in progress + if (currentSend == nil) + { + // Create the sockets if needed + if ((flags & kDidCreateSockets) == 0) + { + NSError *err = nil; + if (![self createSockets:&err]) + { + [self closeWithError:err]; + return; + } + } + + while ([sendQueue count] > 0) + { + // Dequeue the next object in the queue + currentSend = [sendQueue objectAtIndex:0]; + [sendQueue removeObjectAtIndex:0]; + + if ([currentSend isKindOfClass:[GCDAsyncUdpSpecialPacket class]]) + { + [self maybeConnect]; + + return; // The maybeConnect method, if it connects, will invoke this method again + } + else if (currentSend->resolveError) + { + // Notify delegate + [self notifyDidNotSendDataWithTag:currentSend->tag dueToError:currentSend->resolveError]; + + // Clear currentSend + currentSend = nil; + + continue; + } + else + { + // Start preprocessing checks on the send packet + [self doPreSend]; + + break; + } + } + + if ((currentSend == nil) && (flags & kCloseAfterSends)) + { + [self closeWithError:nil]; + } + } +} + +/** + * This method is called after a sendPacket has been dequeued. + * It performs various preprocessing checks on the packet, + * and queries the sendFilter (if set) to determine if the packet can be sent. + * + * If the packet passes all checks, it will be passed on to the doSend method. +**/ +- (void)doPreSend +{ + LogTrace(); + + // + // 1. Check for problems with send packet + // + + BOOL waitingForResolve = NO; + NSError *error = nil; + + if (flags & kDidConnect) + { + // Connected socket + + if (currentSend->resolveInProgress || currentSend->resolvedAddresses || currentSend->resolveError) + { + NSString *msg = @"Cannot specify destination of packet for connected socket"; + error = [self badConfigError:msg]; + } + else + { + currentSend->address = cachedConnectedAddress; + currentSend->addressFamily = cachedConnectedFamily; + } + } + else + { + // Non-Connected socket + + if (currentSend->resolveInProgress) + { + // We're waiting for the packet's destination to be resolved. + waitingForResolve = YES; + } + else if (currentSend->resolveError) + { + error = currentSend->resolveError; + } + else if (currentSend->address == nil) + { + if (currentSend->resolvedAddresses == nil) + { + NSString *msg = @"You must specify destination of packet for a non-connected socket"; + error = [self badConfigError:msg]; + } + else + { + // Pick the proper address to use (out of possibly several resolved addresses) + + NSData *address = nil; + int addressFamily = AF_UNSPEC; + + addressFamily = [self getAddress:&address error:&error fromAddresses:currentSend->resolvedAddresses]; + + currentSend->address = address; + currentSend->addressFamily = addressFamily; + } + } + } + + if (waitingForResolve) + { + // We're waiting for the packet's destination to be resolved. + + LogVerbose(@"currentSend - waiting for address resolve"); + + if (flags & kSock4CanAcceptBytes) { + [self suspendSend4Source]; + } + if (flags & kSock6CanAcceptBytes) { + [self suspendSend6Source]; + } + + return; + } + + if (error) + { + // Unable to send packet due to some error. + // Notify delegate and move on. + + [self notifyDidNotSendDataWithTag:currentSend->tag dueToError:error]; + [self endCurrentSend]; + [self maybeDequeueSend]; + + return; + } + + // + // 2. Query sendFilter (if applicable) + // + + if (sendFilterBlock && sendFilterQueue) + { + // Query sendFilter + + if (sendFilterAsync) + { + // Scenario 1 of 3 - Need to asynchronously query sendFilter + + currentSend->filterInProgress = YES; + GCDAsyncUdpSendPacket *sendPacket = currentSend; + + dispatch_async(sendFilterQueue, ^{ @autoreleasepool { + + BOOL allowed = self->sendFilterBlock(sendPacket->buffer, sendPacket->address, sendPacket->tag); + + dispatch_async(self->socketQueue, ^{ @autoreleasepool { + + sendPacket->filterInProgress = NO; + if (sendPacket == self->currentSend) + { + if (allowed) + { + [self doSend]; + } + else + { + LogVerbose(@"currentSend - silently dropped by sendFilter"); + + [self notifyDidSendDataWithTag:self->currentSend->tag]; + [self endCurrentSend]; + [self maybeDequeueSend]; + } + } + }}); + }}); + } + else + { + // Scenario 2 of 3 - Need to synchronously query sendFilter + + __block BOOL allowed = YES; + + dispatch_sync(sendFilterQueue, ^{ @autoreleasepool { + + allowed = self->sendFilterBlock(self->currentSend->buffer, self->currentSend->address, self->currentSend->tag); + }}); + + if (allowed) + { + [self doSend]; + } + else + { + LogVerbose(@"currentSend - silently dropped by sendFilter"); + + [self notifyDidSendDataWithTag:currentSend->tag]; + [self endCurrentSend]; + [self maybeDequeueSend]; + } + } + } + else // if (!sendFilterBlock || !sendFilterQueue) + { + // Scenario 3 of 3 - No sendFilter. Just go straight into sending. + + [self doSend]; + } +} + +/** + * This method performs the actual sending of data in the currentSend packet. + * It should only be called if the +**/ +- (void)doSend +{ + LogTrace(); + + NSAssert(currentSend != nil, @"Invalid logic"); + + // Perform the actual send + + ssize_t result = 0; + + if (flags & kDidConnect) + { + // Connected socket + + const void *buffer = [currentSend->buffer bytes]; + size_t length = (size_t)[currentSend->buffer length]; + + if (currentSend->addressFamily == AF_INET) + { + result = send(socket4FD, buffer, length, 0); + LogVerbose(@"send(socket4FD) = %d", result); + } + else + { + result = send(socket6FD, buffer, length, 0); + LogVerbose(@"send(socket6FD) = %d", result); + } + } + else + { + // Non-Connected socket + + const void *buffer = [currentSend->buffer bytes]; + size_t length = (size_t)[currentSend->buffer length]; + + const void *dst = [currentSend->address bytes]; + socklen_t dstSize = (socklen_t)[currentSend->address length]; + + if (currentSend->addressFamily == AF_INET) + { + result = sendto(socket4FD, buffer, length, 0, dst, dstSize); + LogVerbose(@"sendto(socket4FD) = %d", result); + } + else + { + result = sendto(socket6FD, buffer, length, 0, dst, dstSize); + LogVerbose(@"sendto(socket6FD) = %d", result); + } + } + + // If the socket wasn't bound before, it is now + + if ((flags & kDidBind) == 0) + { + flags |= kDidBind; + } + + // Check the results. + // + // From the send() & sendto() manpage: + // + // Upon successful completion, the number of bytes which were sent is returned. + // Otherwise, -1 is returned and the global variable errno is set to indicate the error. + + BOOL waitingForSocket = NO; + NSError *socketError = nil; + + if (result == 0) + { + waitingForSocket = YES; + } + else if (result < 0) + { + if (errno == EAGAIN) + waitingForSocket = YES; + else + socketError = [self errnoErrorWithReason:@"Error in send() function."]; + } + + if (waitingForSocket) + { + // Not enough room in the underlying OS socket send buffer. + // Wait for a notification of available space. + + LogVerbose(@"currentSend - waiting for socket"); + + if (!(flags & kSock4CanAcceptBytes)) { + [self resumeSend4Source]; + } + if (!(flags & kSock6CanAcceptBytes)) { + [self resumeSend6Source]; + } + + if ((sendTimer == NULL) && (currentSend->timeout >= 0.0)) + { + // Unable to send packet right away. + // Start timer to timeout the send operation. + + [self setupSendTimerWithTimeout:currentSend->timeout]; + } + } + else if (socketError) + { + [self closeWithError:socketError]; + } + else // done + { + [self notifyDidSendDataWithTag:currentSend->tag]; + [self endCurrentSend]; + [self maybeDequeueSend]; + } +} + +/** + * Releases all resources associated with the currentSend. +**/ +- (void)endCurrentSend +{ + if (sendTimer) + { + dispatch_source_cancel(sendTimer); + #if !OS_OBJECT_USE_OBJC + dispatch_release(sendTimer); + #endif + sendTimer = NULL; + } + + currentSend = nil; +} + +/** + * Performs the operations to timeout the current send operation, and move on. +**/ +- (void)doSendTimeout +{ + LogTrace(); + + [self notifyDidNotSendDataWithTag:currentSend->tag dueToError:[self sendTimeoutError]]; + [self endCurrentSend]; + [self maybeDequeueSend]; +} + +/** + * Sets up a timer that fires to timeout the current send operation. + * This method should only be called once per send packet. +**/ +- (void)setupSendTimerWithTimeout:(NSTimeInterval)timeout +{ + NSAssert(sendTimer == NULL, @"Invalid logic"); + NSAssert(timeout >= 0.0, @"Invalid logic"); + + LogTrace(); + + sendTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, socketQueue); + + dispatch_source_set_event_handler(sendTimer, ^{ @autoreleasepool { + + [self doSendTimeout]; + }}); + + dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)); + + dispatch_source_set_timer(sendTimer, tt, DISPATCH_TIME_FOREVER, 0); + dispatch_resume(sendTimer); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Receiving +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)receiveOnce:(NSError **)errPtr +{ + LogTrace(); + + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ + + if ((self->flags & kReceiveOnce) == 0) + { + if ((self->flags & kDidCreateSockets) == 0) + { + NSString *msg = @"Must bind socket before you can receive data. " + @"You can do this explicitly via bind, or implicitly via connect or by sending data."; + + err = [self badConfigError:msg]; + return_from_block; + } + + self->flags |= kReceiveOnce; // Enable + self->flags &= ~kReceiveContinuous; // Disable + + dispatch_async(self->socketQueue, ^{ @autoreleasepool { + + [self doReceive]; + }}); + } + + result = YES; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error in beginReceiving: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (BOOL)beginReceiving:(NSError **)errPtr +{ + LogTrace(); + + __block BOOL result = NO; + __block NSError *err = nil; + + dispatch_block_t block = ^{ + + if ((self->flags & kReceiveContinuous) == 0) + { + if ((self->flags & kDidCreateSockets) == 0) + { + NSString *msg = @"Must bind socket before you can receive data. " + @"You can do this explicitly via bind, or implicitly via connect or by sending data."; + + err = [self badConfigError:msg]; + return_from_block; + } + + self->flags |= kReceiveContinuous; // Enable + self->flags &= ~kReceiveOnce; // Disable + + dispatch_async(self->socketQueue, ^{ @autoreleasepool { + + [self doReceive]; + }}); + } + + result = YES; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); + + if (err) + LogError(@"Error in beginReceiving: %@", err); + + if (errPtr) + *errPtr = err; + + return result; +} + +- (void)pauseReceiving +{ + LogTrace(); + + dispatch_block_t block = ^{ + + self->flags &= ~kReceiveOnce; // Disable + self->flags &= ~kReceiveContinuous; // Disable + + if (self->socket4FDBytesAvailable > 0) { + [self suspendReceive4Source]; + } + if (self->socket6FDBytesAvailable > 0) { + [self suspendReceive6Source]; + } + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)setReceiveFilter:(GCDAsyncUdpSocketReceiveFilterBlock)filterBlock withQueue:(dispatch_queue_t)filterQueue +{ + [self setReceiveFilter:filterBlock withQueue:filterQueue isAsynchronous:YES]; +} + +- (void)setReceiveFilter:(GCDAsyncUdpSocketReceiveFilterBlock)filterBlock + withQueue:(dispatch_queue_t)filterQueue + isAsynchronous:(BOOL)isAsynchronous +{ + GCDAsyncUdpSocketReceiveFilterBlock newFilterBlock = NULL; + dispatch_queue_t newFilterQueue = NULL; + + if (filterBlock) + { + NSAssert(filterQueue, @"Must provide a dispatch_queue in which to run the filter block."); + + newFilterBlock = [filterBlock copy]; + newFilterQueue = filterQueue; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(newFilterQueue); + #endif + } + + dispatch_block_t block = ^{ + + #if !OS_OBJECT_USE_OBJC + if (self->receiveFilterQueue) dispatch_release(self->receiveFilterQueue); + #endif + + self->receiveFilterBlock = newFilterBlock; + self->receiveFilterQueue = newFilterQueue; + self->receiveFilterAsync = isAsynchronous; + }; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +- (void)doReceive +{ + LogTrace(); + + if ((flags & (kReceiveOnce | kReceiveContinuous)) == 0) + { + LogVerbose(@"Receiving is paused..."); + + if (socket4FDBytesAvailable > 0) { + [self suspendReceive4Source]; + } + if (socket6FDBytesAvailable > 0) { + [self suspendReceive6Source]; + } + + return; + } + + if ((flags & kReceiveOnce) && (pendingFilterOperations > 0)) + { + LogVerbose(@"Receiving is temporarily paused (pending filter operations)..."); + + if (socket4FDBytesAvailable > 0) { + [self suspendReceive4Source]; + } + if (socket6FDBytesAvailable > 0) { + [self suspendReceive6Source]; + } + + return; + } + + if ((socket4FDBytesAvailable == 0) && (socket6FDBytesAvailable == 0)) + { + LogVerbose(@"No data available to receive..."); + + if (socket4FDBytesAvailable == 0) { + [self resumeReceive4Source]; + } + if (socket6FDBytesAvailable == 0) { + [self resumeReceive6Source]; + } + + return; + } + + // Figure out if we should receive on socket4 or socket6 + + BOOL doReceive4; + + if (flags & kDidConnect) + { + // Connected socket + + doReceive4 = (socket4FD != SOCKET_NULL); + } + else + { + // Non-Connected socket + + if (socket4FDBytesAvailable > 0) + { + if (socket6FDBytesAvailable > 0) + { + // Bytes available on socket4 & socket6 + + doReceive4 = (flags & kFlipFlop) ? YES : NO; + + flags ^= kFlipFlop; // flags = flags xor kFlipFlop; (toggle flip flop bit) + } + else { + // Bytes available on socket4, but not socket6 + doReceive4 = YES; + } + } + else { + // Bytes available on socket6, but not socket4 + doReceive4 = NO; + } + } + + // Perform socket IO + + ssize_t result = 0; + + NSData *data = nil; + NSData *addr4 = nil; + NSData *addr6 = nil; + + if (doReceive4) + { + NSAssert(socket4FDBytesAvailable > 0, @"Invalid logic"); + LogVerbose(@"Receiving on IPv4"); + + struct sockaddr_in sockaddr4; + socklen_t sockaddr4len = sizeof(sockaddr4); + + // #222: GCD does not necessarily return the size of an entire UDP packet + // from dispatch_source_get_data(), so we must use the maximum packet size. + size_t bufSize = max4ReceiveSize; + void *buf = malloc(bufSize); + + result = recvfrom(socket4FD, buf, bufSize, 0, (struct sockaddr *)&sockaddr4, &sockaddr4len); + LogVerbose(@"recvfrom(socket4FD) = %i", (int)result); + + if (result > 0) + { + if ((size_t)result >= socket4FDBytesAvailable) + socket4FDBytesAvailable = 0; + else + socket4FDBytesAvailable -= result; + + if ((size_t)result != bufSize) { + buf = realloc(buf, result); + } + + data = [NSData dataWithBytesNoCopy:buf length:result freeWhenDone:YES]; + addr4 = [NSData dataWithBytes:&sockaddr4 length:sockaddr4len]; + } + else + { + LogVerbose(@"recvfrom(socket4FD) = %@", [self errnoError]); + socket4FDBytesAvailable = 0; + free(buf); + } + } + else + { + NSAssert(socket6FDBytesAvailable > 0, @"Invalid logic"); + LogVerbose(@"Receiving on IPv6"); + + struct sockaddr_in6 sockaddr6; + socklen_t sockaddr6len = sizeof(sockaddr6); + + // #222: GCD does not necessarily return the size of an entire UDP packet + // from dispatch_source_get_data(), so we must use the maximum packet size. + size_t bufSize = max6ReceiveSize; + void *buf = malloc(bufSize); + + result = recvfrom(socket6FD, buf, bufSize, 0, (struct sockaddr *)&sockaddr6, &sockaddr6len); + LogVerbose(@"recvfrom(socket6FD) -> %i", (int)result); + + if (result > 0) + { + if ((size_t)result >= socket6FDBytesAvailable) + socket6FDBytesAvailable = 0; + else + socket6FDBytesAvailable -= result; + + if ((size_t)result != bufSize) { + buf = realloc(buf, result); + } + + data = [NSData dataWithBytesNoCopy:buf length:result freeWhenDone:YES]; + addr6 = [NSData dataWithBytes:&sockaddr6 length:sockaddr6len]; + } + else + { + LogVerbose(@"recvfrom(socket6FD) = %@", [self errnoError]); + socket6FDBytesAvailable = 0; + free(buf); + } + } + + + BOOL waitingForSocket = NO; + BOOL notifiedDelegate = NO; + BOOL ignored = NO; + + NSError *socketError = nil; + + if (result == 0) + { + waitingForSocket = YES; + } + else if (result < 0) + { + if (errno == EAGAIN) + waitingForSocket = YES; + else + socketError = [self errnoErrorWithReason:@"Error in recvfrom() function"]; + } + else + { + if (flags & kDidConnect) + { + if (addr4 && ![self isConnectedToAddress4:addr4]) + ignored = YES; + if (addr6 && ![self isConnectedToAddress6:addr6]) + ignored = YES; + } + + NSData *addr = (addr4 != nil) ? addr4 : addr6; + + if (!ignored) + { + if (receiveFilterBlock && receiveFilterQueue) + { + // Run data through filter, and if approved, notify delegate + + __block id filterContext = nil; + __block BOOL allowed = NO; + + if (receiveFilterAsync) + { + pendingFilterOperations++; + dispatch_async(receiveFilterQueue, ^{ @autoreleasepool { + + allowed = self->receiveFilterBlock(data, addr, &filterContext); + + // Transition back to socketQueue to get the current delegate / delegateQueue + dispatch_async(self->socketQueue, ^{ @autoreleasepool { + + self->pendingFilterOperations--; + + if (allowed) + { + [self notifyDidReceiveData:data fromAddress:addr withFilterContext:filterContext]; + } + else + { + LogVerbose(@"received packet silently dropped by receiveFilter"); + } + + if (self->flags & kReceiveOnce) + { + if (allowed) + { + // The delegate has been notified, + // so our receive once operation has completed. + self->flags &= ~kReceiveOnce; + } + else if (self->pendingFilterOperations == 0) + { + // All pending filter operations have completed, + // and none were allowed through. + // Our receive once operation hasn't completed yet. + [self doReceive]; + } + } + }}); + }}); + } + else // if (!receiveFilterAsync) + { + dispatch_sync(receiveFilterQueue, ^{ @autoreleasepool { + + allowed = self->receiveFilterBlock(data, addr, &filterContext); + }}); + + if (allowed) + { + [self notifyDidReceiveData:data fromAddress:addr withFilterContext:filterContext]; + notifiedDelegate = YES; + } + else + { + LogVerbose(@"received packet silently dropped by receiveFilter"); + ignored = YES; + } + } + } + else // if (!receiveFilterBlock || !receiveFilterQueue) + { + [self notifyDidReceiveData:data fromAddress:addr withFilterContext:nil]; + notifiedDelegate = YES; + } + } + } + + if (waitingForSocket) + { + // Wait for a notification of available data. + + if (socket4FDBytesAvailable == 0) { + [self resumeReceive4Source]; + } + if (socket6FDBytesAvailable == 0) { + [self resumeReceive6Source]; + } + } + else if (socketError) + { + [self closeWithError:socketError]; + } + else + { + if (flags & kReceiveContinuous) + { + // Continuous receive mode + [self doReceive]; + } + else + { + // One-at-a-time receive mode + if (notifiedDelegate) + { + // The delegate has been notified (no set filter). + // So our receive once operation has completed. + flags &= ~kReceiveOnce; + } + else if (ignored) + { + [self doReceive]; + } + else + { + // Waiting on asynchronous receive filter... + } + } + } +} + +- (void)doReceiveEOF +{ + LogTrace(); + + [self closeWithError:[self socketClosedError]]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Closing +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)closeWithError:(NSError *)error +{ + LogVerbose(@"closeWithError: %@", error); + + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if (currentSend) [self endCurrentSend]; + + [sendQueue removeAllObjects]; + + // If a socket has been created, we should notify the delegate. + BOOL shouldCallDelegate = (flags & kDidCreateSockets) ? YES : NO; + + // Close all sockets, send/receive sources, cfstreams, etc +#if TARGET_OS_IPHONE + [self removeStreamsFromRunLoop]; + [self closeReadAndWriteStreams]; +#endif + [self closeSockets]; + + // Clear all flags (config remains as is) + flags = 0; + + if (shouldCallDelegate) + { + [self notifyDidCloseWithError:error]; + } +} + +- (void)close +{ + LogTrace(); + + dispatch_block_t block = ^{ @autoreleasepool { + + [self closeWithError:nil]; + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); +} + +- (void)closeAfterSending +{ + LogTrace(); + + dispatch_block_t block = ^{ @autoreleasepool { + + self->flags |= kCloseAfterSends; + + if (self->currentSend == nil && [self->sendQueue count] == 0) + { + [self closeWithError:nil]; + } + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark CFStream +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if TARGET_OS_IPHONE + +static NSThread *listenerThread; + ++ (void)ignore:(id)_ +{} + ++ (void)startListenerThreadIfNeeded +{ + static dispatch_once_t predicate; + dispatch_once(&predicate, ^{ + + listenerThread = [[NSThread alloc] initWithTarget:self + selector:@selector(listenerThread:) + object:nil]; + [listenerThread start]; + }); +} + ++ (void)listenerThread:(id)unused +{ + @autoreleasepool { + + [[NSThread currentThread] setName:GCDAsyncUdpSocketThreadName]; + + LogInfo(@"ListenerThread: Started"); + + // We can't run the run loop unless it has an associated input source or a timer. + // So we'll just create a timer that will never fire - unless the server runs for a decades. + [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow] + target:self + selector:@selector(ignore:) + userInfo:nil + repeats:YES]; + + [[NSRunLoop currentRunLoop] run]; + + LogInfo(@"ListenerThread: Stopped"); + } +} + ++ (void)addStreamListener:(GCDAsyncUdpSocket *)asyncUdpSocket +{ + LogTrace(); + NSAssert([NSThread currentThread] == listenerThread, @"Invoked on wrong thread"); + + CFRunLoopRef runLoop = CFRunLoopGetCurrent(); + + if (asyncUdpSocket->readStream4) + CFReadStreamScheduleWithRunLoop(asyncUdpSocket->readStream4, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->readStream6) + CFReadStreamScheduleWithRunLoop(asyncUdpSocket->readStream6, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->writeStream4) + CFWriteStreamScheduleWithRunLoop(asyncUdpSocket->writeStream4, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->writeStream6) + CFWriteStreamScheduleWithRunLoop(asyncUdpSocket->writeStream6, runLoop, kCFRunLoopDefaultMode); +} + ++ (void)removeStreamListener:(GCDAsyncUdpSocket *)asyncUdpSocket +{ + LogTrace(); + NSAssert([NSThread currentThread] == listenerThread, @"Invoked on wrong thread"); + + CFRunLoopRef runLoop = CFRunLoopGetCurrent(); + + if (asyncUdpSocket->readStream4) + CFReadStreamUnscheduleFromRunLoop(asyncUdpSocket->readStream4, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->readStream6) + CFReadStreamUnscheduleFromRunLoop(asyncUdpSocket->readStream6, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->writeStream4) + CFWriteStreamUnscheduleFromRunLoop(asyncUdpSocket->writeStream4, runLoop, kCFRunLoopDefaultMode); + + if (asyncUdpSocket->writeStream6) + CFWriteStreamUnscheduleFromRunLoop(asyncUdpSocket->writeStream6, runLoop, kCFRunLoopDefaultMode); +} + +static void CFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void *pInfo) +{ + @autoreleasepool { + GCDAsyncUdpSocket *asyncUdpSocket = (__bridge GCDAsyncUdpSocket *)pInfo; + + switch(type) + { + case kCFStreamEventOpenCompleted: + { + LogCVerbose(@"CFReadStreamCallback - Open"); + break; + } + case kCFStreamEventHasBytesAvailable: + { + LogCVerbose(@"CFReadStreamCallback - HasBytesAvailable"); + break; + } + case kCFStreamEventErrorOccurred: + case kCFStreamEventEndEncountered: + { + NSError *error = (__bridge_transfer NSError *)CFReadStreamCopyError(stream); + if (error == nil && type == kCFStreamEventEndEncountered) + { + error = [asyncUdpSocket socketClosedError]; + } + + dispatch_async(asyncUdpSocket->socketQueue, ^{ @autoreleasepool { + + LogCVerbose(@"CFReadStreamCallback - %@", + (type == kCFStreamEventErrorOccurred) ? @"Error" : @"EndEncountered"); + + if (stream != asyncUdpSocket->readStream4 && + stream != asyncUdpSocket->readStream6 ) + { + LogCVerbose(@"CFReadStreamCallback - Ignored"); + return_from_block; + } + + [asyncUdpSocket closeWithError:error]; + + }}); + + break; + } + default: + { + LogCError(@"CFReadStreamCallback - UnknownType: %i", (int)type); + } + } + } +} + +static void CFWriteStreamCallback(CFWriteStreamRef stream, CFStreamEventType type, void *pInfo) +{ + @autoreleasepool { + GCDAsyncUdpSocket *asyncUdpSocket = (__bridge GCDAsyncUdpSocket *)pInfo; + + switch(type) + { + case kCFStreamEventOpenCompleted: + { + LogCVerbose(@"CFWriteStreamCallback - Open"); + break; + } + case kCFStreamEventCanAcceptBytes: + { + LogCVerbose(@"CFWriteStreamCallback - CanAcceptBytes"); + break; + } + case kCFStreamEventErrorOccurred: + case kCFStreamEventEndEncountered: + { + NSError *error = (__bridge_transfer NSError *)CFWriteStreamCopyError(stream); + if (error == nil && type == kCFStreamEventEndEncountered) + { + error = [asyncUdpSocket socketClosedError]; + } + + dispatch_async(asyncUdpSocket->socketQueue, ^{ @autoreleasepool { + + LogCVerbose(@"CFWriteStreamCallback - %@", + (type == kCFStreamEventErrorOccurred) ? @"Error" : @"EndEncountered"); + + if (stream != asyncUdpSocket->writeStream4 && + stream != asyncUdpSocket->writeStream6 ) + { + LogCVerbose(@"CFWriteStreamCallback - Ignored"); + return_from_block; + } + + [asyncUdpSocket closeWithError:error]; + + }}); + + break; + } + default: + { + LogCError(@"CFWriteStreamCallback - UnknownType: %i", (int)type); + } + } + } +} + +- (BOOL)createReadAndWriteStreams:(NSError **)errPtr +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + NSError *err = nil; + + if (readStream4 || writeStream4 || readStream6 || writeStream6) + { + // Streams already created + return YES; + } + + if (socket4FD == SOCKET_NULL && socket6FD == SOCKET_NULL) + { + err = [self otherError:@"Cannot create streams without a file descriptor"]; + goto Failed; + } + + // Create streams + + LogVerbose(@"Creating read and write stream(s)..."); + + if (socket4FD != SOCKET_NULL) + { + CFStreamCreatePairWithSocket(NULL, (CFSocketNativeHandle)socket4FD, &readStream4, &writeStream4); + if (!readStream4 || !writeStream4) + { + err = [self otherError:@"Error in CFStreamCreatePairWithSocket() [IPv4]"]; + goto Failed; + } + } + + if (socket6FD != SOCKET_NULL) + { + CFStreamCreatePairWithSocket(NULL, (CFSocketNativeHandle)socket6FD, &readStream6, &writeStream6); + if (!readStream6 || !writeStream6) + { + err = [self otherError:@"Error in CFStreamCreatePairWithSocket() [IPv6]"]; + goto Failed; + } + } + + // Ensure the CFStream's don't close our underlying socket + + CFReadStreamSetProperty(readStream4, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse); + CFWriteStreamSetProperty(writeStream4, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse); + + CFReadStreamSetProperty(readStream6, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse); + CFWriteStreamSetProperty(writeStream6, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse); + + return YES; + +Failed: + if (readStream4) + { + CFReadStreamClose(readStream4); + CFRelease(readStream4); + readStream4 = NULL; + } + if (writeStream4) + { + CFWriteStreamClose(writeStream4); + CFRelease(writeStream4); + writeStream4 = NULL; + } + if (readStream6) + { + CFReadStreamClose(readStream6); + CFRelease(readStream6); + readStream6 = NULL; + } + if (writeStream6) + { + CFWriteStreamClose(writeStream6); + CFRelease(writeStream6); + writeStream6 = NULL; + } + + if (errPtr) + *errPtr = err; + + return NO; +} + +- (BOOL)registerForStreamCallbacks:(NSError **)errPtr +{ + LogTrace(); + + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(readStream4 || writeStream4 || readStream6 || writeStream6, @"Read/Write streams are null"); + + NSError *err = nil; + + streamContext.version = 0; + streamContext.info = (__bridge void *)self; + streamContext.retain = nil; + streamContext.release = nil; + streamContext.copyDescription = nil; + + CFOptionFlags readStreamEvents = kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; + CFOptionFlags writeStreamEvents = kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; + +// readStreamEvents |= (kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable); +// writeStreamEvents |= (kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes); + + if (socket4FD != SOCKET_NULL) + { + if (readStream4 == NULL || writeStream4 == NULL) + { + err = [self otherError:@"Read/Write stream4 is null"]; + goto Failed; + } + + BOOL r1 = CFReadStreamSetClient(readStream4, readStreamEvents, &CFReadStreamCallback, &streamContext); + BOOL r2 = CFWriteStreamSetClient(writeStream4, writeStreamEvents, &CFWriteStreamCallback, &streamContext); + + if (!r1 || !r2) + { + err = [self otherError:@"Error in CFStreamSetClient(), [IPv4]"]; + goto Failed; + } + } + + if (socket6FD != SOCKET_NULL) + { + if (readStream6 == NULL || writeStream6 == NULL) + { + err = [self otherError:@"Read/Write stream6 is null"]; + goto Failed; + } + + BOOL r1 = CFReadStreamSetClient(readStream6, readStreamEvents, &CFReadStreamCallback, &streamContext); + BOOL r2 = CFWriteStreamSetClient(writeStream6, writeStreamEvents, &CFWriteStreamCallback, &streamContext); + + if (!r1 || !r2) + { + err = [self otherError:@"Error in CFStreamSetClient() [IPv6]"]; + goto Failed; + } + } + + return YES; + +Failed: + if (readStream4) { + CFReadStreamSetClient(readStream4, kCFStreamEventNone, NULL, NULL); + } + if (writeStream4) { + CFWriteStreamSetClient(writeStream4, kCFStreamEventNone, NULL, NULL); + } + if (readStream6) { + CFReadStreamSetClient(readStream6, kCFStreamEventNone, NULL, NULL); + } + if (writeStream6) { + CFWriteStreamSetClient(writeStream6, kCFStreamEventNone, NULL, NULL); + } + + if (errPtr) *errPtr = err; + return NO; +} + +- (BOOL)addStreamsToRunLoop:(NSError **)errPtr +{ + LogTrace(); + + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(readStream4 || writeStream4 || readStream6 || writeStream6, @"Read/Write streams are null"); + + if (!(flags & kAddedStreamListener)) + { + [[self class] startListenerThreadIfNeeded]; + [[self class] performSelector:@selector(addStreamListener:) + onThread:listenerThread + withObject:self + waitUntilDone:YES]; + + flags |= kAddedStreamListener; + } + + return YES; +} + +- (BOOL)openStreams:(NSError **)errPtr +{ + LogTrace(); + + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + NSAssert(readStream4 || writeStream4 || readStream6 || writeStream6, @"Read/Write streams are null"); + + NSError *err = nil; + + if (socket4FD != SOCKET_NULL) + { + BOOL r1 = CFReadStreamOpen(readStream4); + BOOL r2 = CFWriteStreamOpen(writeStream4); + + if (!r1 || !r2) + { + err = [self otherError:@"Error in CFStreamOpen() [IPv4]"]; + goto Failed; + } + } + + if (socket6FD != SOCKET_NULL) + { + BOOL r1 = CFReadStreamOpen(readStream6); + BOOL r2 = CFWriteStreamOpen(writeStream6); + + if (!r1 || !r2) + { + err = [self otherError:@"Error in CFStreamOpen() [IPv6]"]; + goto Failed; + } + } + + return YES; + +Failed: + if (errPtr) *errPtr = err; + return NO; +} + +- (void)removeStreamsFromRunLoop +{ + LogTrace(); + NSAssert(dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey), @"Must be dispatched on socketQueue"); + + if (flags & kAddedStreamListener) + { + [[self class] performSelector:@selector(removeStreamListener:) + onThread:listenerThread + withObject:self + waitUntilDone:YES]; + + flags &= ~kAddedStreamListener; + } +} + +- (void)closeReadAndWriteStreams +{ + LogTrace(); + + if (readStream4) + { + CFReadStreamSetClient(readStream4, kCFStreamEventNone, NULL, NULL); + CFReadStreamClose(readStream4); + CFRelease(readStream4); + readStream4 = NULL; + } + if (writeStream4) + { + CFWriteStreamSetClient(writeStream4, kCFStreamEventNone, NULL, NULL); + CFWriteStreamClose(writeStream4); + CFRelease(writeStream4); + writeStream4 = NULL; + } + if (readStream6) + { + CFReadStreamSetClient(readStream6, kCFStreamEventNone, NULL, NULL); + CFReadStreamClose(readStream6); + CFRelease(readStream6); + readStream6 = NULL; + } + if (writeStream6) + { + CFWriteStreamSetClient(writeStream6, kCFStreamEventNone, NULL, NULL); + CFWriteStreamClose(writeStream6); + CFRelease(writeStream6); + writeStream6 = NULL; + } +} + +#endif + +#if TARGET_OS_IPHONE +- (void)applicationWillEnterForeground:(NSNotification *)notification +{ + LogTrace(); + + // If the application was backgrounded, then iOS may have shut down our sockets. + // So we take a quick look to see if any of them received an EOF. + + dispatch_block_t block = ^{ @autoreleasepool { + + [self resumeReceive4Source]; + [self resumeReceive6Source]; + }}; + + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_async(socketQueue, block); +} +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Advanced +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * See header file for big discussion of this method. + **/ +- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketNewTargetQueue +{ + void *nonNullUnusedPointer = (__bridge void *)self; + dispatch_queue_set_specific(socketNewTargetQueue, IsOnSocketQueueOrTargetQueueKey, nonNullUnusedPointer, NULL); +} + +/** + * See header file for big discussion of this method. + **/ +- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketOldTargetQueue +{ + dispatch_queue_set_specific(socketOldTargetQueue, IsOnSocketQueueOrTargetQueueKey, NULL, NULL); +} + +- (void)performBlock:(dispatch_block_t)block +{ + if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + block(); + else + dispatch_sync(socketQueue, block); +} + +- (int)socketFD +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return SOCKET_NULL; + } + + if (socket4FD != SOCKET_NULL) + return socket4FD; + else + return socket6FD; +} + +- (int)socket4FD +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return SOCKET_NULL; + } + + return socket4FD; +} + +- (int)socket6FD +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return SOCKET_NULL; + } + + return socket6FD; +} + +#if TARGET_OS_IPHONE + +- (CFReadStreamRef)readStream +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return NULL; + } + + NSError *err = nil; + if (![self createReadAndWriteStreams:&err]) + { + LogError(@"Error creating CFStream(s): %@", err); + return NULL; + } + + // Todo... + + if (readStream4) + return readStream4; + else + return readStream6; +} + +- (CFWriteStreamRef)writeStream +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return NULL; + } + + NSError *err = nil; + if (![self createReadAndWriteStreams:&err]) + { + LogError(@"Error creating CFStream(s): %@", err); + return NULL; + } + + if (writeStream4) + return writeStream4; + else + return writeStream6; +} + +- (BOOL)enableBackgroundingOnSockets +{ + if (! dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey)) + { + LogWarn(@"%@: %@ - Method only available from within the context of a performBlock: invocation", + THIS_FILE, THIS_METHOD); + return NO; + } + + // Why is this commented out? + // See comments below. + +// NSError *err = nil; +// if (![self createReadAndWriteStreams:&err]) +// { +// LogError(@"Error creating CFStream(s): %@", err); +// return NO; +// } +// +// LogVerbose(@"Enabling backgrouding on socket"); +// +// BOOL r1, r2; +// +// if (readStream4 && writeStream4) +// { +// r1 = CFReadStreamSetProperty(readStream4, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); +// r2 = CFWriteStreamSetProperty(writeStream4, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); +// +// if (!r1 || !r2) +// { +// LogError(@"Error setting voip type (IPv4)"); +// return NO; +// } +// } +// +// if (readStream6 && writeStream6) +// { +// r1 = CFReadStreamSetProperty(readStream6, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); +// r2 = CFWriteStreamSetProperty(writeStream6, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); +// +// if (!r1 || !r2) +// { +// LogError(@"Error setting voip type (IPv6)"); +// return NO; +// } +// } +// +// return YES; + + // The above code will actually appear to work. + // The methods will return YES, and everything will appear fine. + // + // One tiny problem: the sockets will still get closed when the app gets backgrounded. + // + // Apple does not officially support backgrounding UDP sockets. + + return NO; +} + +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Class Methods +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (NSString *)hostFromSockaddr4:(const struct sockaddr_in *)pSockaddr4 +{ + char addrBuf[INET_ADDRSTRLEN]; + + if (inet_ntop(AF_INET, &pSockaddr4->sin_addr, addrBuf, (socklen_t)sizeof(addrBuf)) == NULL) + { + addrBuf[0] = '\0'; + } + + return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding]; +} + ++ (NSString *)hostFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6 +{ + char addrBuf[INET6_ADDRSTRLEN]; + + if (inet_ntop(AF_INET6, &pSockaddr6->sin6_addr, addrBuf, (socklen_t)sizeof(addrBuf)) == NULL) + { + addrBuf[0] = '\0'; + } + + return [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding]; +} + ++ (uint16_t)portFromSockaddr4:(const struct sockaddr_in *)pSockaddr4 +{ + return ntohs(pSockaddr4->sin_port); +} + ++ (uint16_t)portFromSockaddr6:(const struct sockaddr_in6 *)pSockaddr6 +{ + return ntohs(pSockaddr6->sin6_port); +} + ++ (NSString *)hostFromAddress:(NSData *)address +{ + NSString *host = nil; + [self getHost:&host port:NULL family:NULL fromAddress:address]; + + return host; +} + ++ (uint16_t)portFromAddress:(NSData *)address +{ + uint16_t port = 0; + [self getHost:NULL port:&port family:NULL fromAddress:address]; + + return port; +} + ++ (int)familyFromAddress:(NSData *)address +{ + int af = AF_UNSPEC; + [self getHost:NULL port:NULL family:&af fromAddress:address]; + + return af; +} + ++ (BOOL)isIPv4Address:(NSData *)address +{ + int af = AF_UNSPEC; + [self getHost:NULL port:NULL family:&af fromAddress:address]; + + return (af == AF_INET); +} + ++ (BOOL)isIPv6Address:(NSData *)address +{ + int af = AF_UNSPEC; + [self getHost:NULL port:NULL family:&af fromAddress:address]; + + return (af == AF_INET6); +} + ++ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr fromAddress:(NSData *)address +{ + return [self getHost:hostPtr port:portPtr family:NULL fromAddress:address]; +} + ++ (BOOL)getHost:(NSString **)hostPtr port:(uint16_t *)portPtr family:(int *)afPtr fromAddress:(NSData *)address +{ + if ([address length] >= sizeof(struct sockaddr)) + { + const struct sockaddr *addrX = (const struct sockaddr *)[address bytes]; + + if (addrX->sa_family == AF_INET) + { + if ([address length] >= sizeof(struct sockaddr_in)) + { + const struct sockaddr_in *addr4 = (const struct sockaddr_in *)(const void *)addrX; + + if (hostPtr) *hostPtr = [self hostFromSockaddr4:addr4]; + if (portPtr) *portPtr = [self portFromSockaddr4:addr4]; + if (afPtr) *afPtr = AF_INET; + + return YES; + } + } + else if (addrX->sa_family == AF_INET6) + { + if ([address length] >= sizeof(struct sockaddr_in6)) + { + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)(const void *)addrX; + + if (hostPtr) *hostPtr = [self hostFromSockaddr6:addr6]; + if (portPtr) *portPtr = [self portFromSockaddr6:addr6]; + if (afPtr) *afPtr = AF_INET6; + + return YES; + } + } + } + + if (hostPtr) *hostPtr = nil; + if (portPtr) *portPtr = 0; + if (afPtr) *afPtr = AF_UNSPEC; + + return NO; +} + +@end diff --git a/AppRunMan/server/IOHIDUsageTables.h b/AppRunMan/server/IOHIDUsageTables.h new file mode 100644 index 0000000..175ea0e --- /dev/null +++ b/AppRunMan/server/IOHIDUsageTables.h @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef _IOHIDUSAGETABLES_H +#define _IOHIDUSAGETABLES_H + +/* ****************************************************************************************** + * HID Usage Tables + * + * The following constants are from the USB 'HID Usage Tables' specification, revision 1.1rc3 + * ****************************************************************************************** */ + + +/* Usage Pages */ +enum +{ + kHIDPage_Undefined = 0x00, + kHIDPage_GenericDesktop = 0x01, + kHIDPage_Simulation = 0x02, + kHIDPage_VR = 0x03, + kHIDPage_Sport = 0x04, + kHIDPage_Game = 0x05, + /* Reserved 0x06 */ + kHIDPage_KeyboardOrKeypad = 0x07, /* USB Device Class Definition for Human Interface Devices (HID). Note: the usage type for all key codes is Selector (Sel). */ + kHIDPage_LEDs = 0x08, + kHIDPage_Button = 0x09, + kHIDPage_Ordinal = 0x0A, + kHIDPage_Telephony = 0x0B, + kHIDPage_Consumer = 0x0C, + kHIDPage_Digitizer = 0x0D, + /* Reserved 0x0E */ + kHIDPage_PID = 0x0F, /* USB Physical Interface Device definitions for force feedback and related devices. */ + kHIDPage_Unicode = 0x10, + /* Reserved 0x11 - 0x13 */ + kHIDPage_AlphanumericDisplay = 0x14, + /* Reserved 0x15 - 0x7F */ + /* Monitor 0x80 - 0x83 USB Device Class Definition for Monitor Devices */ + /* Power 0x84 - 0x87 USB Device Class Definition for Power Devices */ + /* Reserved 0x88 - 0x8B */ + kHIDPage_BarCodeScanner = 0x8C, /* (Point of Sale) USB Device Class Definition for Bar Code Scanner Devices */ + kHIDPage_Scale = 0x8D, /* (Point of Sale) USB Device Class Definition for Scale Devices */ + /* ReservedPointofSalepages 0x8E - 0x8F */ + kHIDPage_CameraControl = 0x90, /* USB Device Class Definition for Image Class Devices */ + kHIDPage_Arcade = 0x91, /* OAAF Definitions for arcade and coinop related Devices */ + /* Reserved 0x92 - 0xFEFF */ + /* VendorDefined 0xFF00 - 0xFFFF */ + kHIDPage_VendorDefinedStart = 0xFF00, +}; + +/* Undefined Usage for all usage pages */ +enum +{ + kHIDUsage_Undefined = 0x00 +}; + +/* GenericDesktop Page (0x01) */ +enum +{ + kHIDUsage_GD_Pointer = 0x01, /* Physical Collection */ + kHIDUsage_GD_Mouse = 0x02, /* Application Collection */ + /* 0x03 Reserved */ + kHIDUsage_GD_Joystick = 0x04, /* Application Collection */ + kHIDUsage_GD_GamePad = 0x05, /* Application Collection */ + kHIDUsage_GD_Keyboard = 0x06, /* Application Collection */ + kHIDUsage_GD_Keypad = 0x07, /* Application Collection */ + kHIDUsage_GD_MultiAxisController = 0x08, /* Application Collection */ + /* 0x09 - 0x2F Reserved */ + kHIDUsage_GD_X = 0x30, /* Dynamic Value */ + kHIDUsage_GD_Y = 0x31, /* Dynamic Value */ + kHIDUsage_GD_Z = 0x32, /* Dynamic Value */ + kHIDUsage_GD_Rx = 0x33, /* Dynamic Value */ + kHIDUsage_GD_Ry = 0x34, /* Dynamic Value */ + kHIDUsage_GD_Rz = 0x35, /* Dynamic Value */ + kHIDUsage_GD_Slider = 0x36, /* Dynamic Value */ + kHIDUsage_GD_Dial = 0x37, /* Dynamic Value */ + kHIDUsage_GD_Wheel = 0x38, /* Dynamic Value */ + kHIDUsage_GD_Hatswitch = 0x39, /* Dynamic Value */ + kHIDUsage_GD_CountedBuffer = 0x3A, /* Logical Collection */ + kHIDUsage_GD_ByteCount = 0x3B, /* Dynamic Value */ + kHIDUsage_GD_MotionWakeup = 0x3C, /* One-Shot Control */ + kHIDUsage_GD_Start = 0x3D, /* On/Off Control */ + kHIDUsage_GD_Select = 0x3E, /* On/Off Control */ + /* 0x3F Reserved */ + kHIDUsage_GD_Vx = 0x40, /* Dynamic Value */ + kHIDUsage_GD_Vy = 0x41, /* Dynamic Value */ + kHIDUsage_GD_Vz = 0x42, /* Dynamic Value */ + kHIDUsage_GD_Vbrx = 0x43, /* Dynamic Value */ + kHIDUsage_GD_Vbry = 0x44, /* Dynamic Value */ + kHIDUsage_GD_Vbrz = 0x45, /* Dynamic Value */ + kHIDUsage_GD_Vno = 0x46, /* Dynamic Value */ + /* 0x47 - 0x7F Reserved */ + kHIDUsage_GD_SystemControl = 0x80, /* Application Collection */ + kHIDUsage_GD_SystemPowerDown = 0x81, /* One-Shot Control */ + kHIDUsage_GD_SystemSleep = 0x82, /* One-Shot Control */ + kHIDUsage_GD_SystemWakeUp = 0x83, /* One-Shot Control */ + kHIDUsage_GD_SystemContextMenu = 0x84, /* One-Shot Control */ + kHIDUsage_GD_SystemMainMenu = 0x85, /* One-Shot Control */ + kHIDUsage_GD_SystemAppMenu = 0x86, /* One-Shot Control */ + kHIDUsage_GD_SystemMenuHelp = 0x87, /* One-Shot Control */ + kHIDUsage_GD_SystemMenuExit = 0x88, /* One-Shot Control */ + kHIDUsage_GD_SystemMenu = 0x89, /* Selector */ + kHIDUsage_GD_SystemMenuRight = 0x8A, /* Re-Trigger Control */ + kHIDUsage_GD_SystemMenuLeft = 0x8B, /* Re-Trigger Control */ + kHIDUsage_GD_SystemMenuUp = 0x8C, /* Re-Trigger Control */ + kHIDUsage_GD_SystemMenuDown = 0x8D, /* Re-Trigger Control */ + /* 0x8E - 0x8F Reserved */ + kHIDUsage_GD_DPadUp = 0x90, /* On/Off Control */ + kHIDUsage_GD_DPadDown = 0x91, /* On/Off Control */ + kHIDUsage_GD_DPadRight = 0x92, /* On/Off Control */ + kHIDUsage_GD_DPadLeft = 0x93, /* On/Off Control */ + /* 0x94 - 0xFFFF Reserved */ + kHIDUsage_GD_Reserved = 0xFFFF, +}; + +/* Simulation Page (0x02) */ +/* This section provides detailed descriptions of the usages employed by simulation devices. */ +enum +{ + kHIDUsage_Sim_FlightSimulationDevice = 0x01, /* Application Collection */ + kHIDUsage_Sim_AutomobileSimulationDevice = 0x02, /* Application Collection */ + kHIDUsage_Sim_TankSimulationDevice = 0x03, /* Application Collection */ + kHIDUsage_Sim_SpaceshipSimulationDevice = 0x04, /* Application Collection */ + kHIDUsage_Sim_SubmarineSimulationDevice = 0x05, /* Application Collection */ + kHIDUsage_Sim_SailingSimulationDevice = 0x06, /* Application Collection */ + kHIDUsage_Sim_MotorcycleSimulationDevice = 0x07, /* Application Collection */ + kHIDUsage_Sim_SportsSimulationDevice = 0x08, /* Application Collection */ + kHIDUsage_Sim_AirplaneSimulationDevice = 0x09, /* Application Collection */ + kHIDUsage_Sim_HelicopterSimulationDevice = 0x0A, /* Application Collection */ + kHIDUsage_Sim_MagicCarpetSimulationDevice = 0x0B, /* Application Collection */ + kHIDUsage_Sim_BicycleSimulationDevice = 0x0C, /* Application Collection */ + /* 0x0D - 0x1F Reserved */ + kHIDUsage_Sim_FlightControlStick = 0x20, /* Application Collection */ + kHIDUsage_Sim_FlightStick = 0x21, /* Application Collection */ + kHIDUsage_Sim_CyclicControl = 0x22, /* Physical Collection */ + kHIDUsage_Sim_CyclicTrim = 0x23, /* Physical Collection */ + kHIDUsage_Sim_FlightYoke = 0x24, /* Application Collection */ + kHIDUsage_Sim_TrackControl = 0x25, /* Physical Collection */ + /* 0x26 - 0xAF Reserved */ + kHIDUsage_Sim_Aileron = 0xB0, /* Dynamic Value */ + kHIDUsage_Sim_AileronTrim = 0xB1, /* Dynamic Value */ + kHIDUsage_Sim_AntiTorqueControl = 0xB2, /* Dynamic Value */ + kHIDUsage_Sim_AutopilotEnable = 0xB3, /* On/Off Control */ + kHIDUsage_Sim_ChaffRelease = 0xB4, /* One-Shot Control */ + kHIDUsage_Sim_CollectiveControl = 0xB5, /* Dynamic Value */ + kHIDUsage_Sim_DiveBrake = 0xB6, /* Dynamic Value */ + kHIDUsage_Sim_ElectronicCountermeasures = 0xB7, /* On/Off Control */ + kHIDUsage_Sim_Elevator = 0xB8, /* Dynamic Value */ + kHIDUsage_Sim_ElevatorTrim = 0xB9, /* Dynamic Value */ + kHIDUsage_Sim_Rudder = 0xBA, /* Dynamic Value */ + kHIDUsage_Sim_Throttle = 0xBB, /* Dynamic Value */ + kHIDUsage_Sim_FlightCommunications = 0xBC, /* On/Off Control */ + kHIDUsage_Sim_FlareRelease = 0xBD, /* One-Shot Control */ + kHIDUsage_Sim_LandingGear = 0xBE, /* On/Off Control */ + kHIDUsage_Sim_ToeBrake = 0xBF, /* Dynamic Value */ + kHIDUsage_Sim_Trigger = 0xC0, /* Momentary Control */ + kHIDUsage_Sim_WeaponsArm = 0xC1, /* On/Off Control */ + kHIDUsage_Sim_Weapons = 0xC2, /* Selector */ + kHIDUsage_Sim_WingFlaps = 0xC3, /* Dynamic Value */ + kHIDUsage_Sim_Accelerator = 0xC4, /* Dynamic Value */ + kHIDUsage_Sim_Brake = 0xC5, /* Dynamic Value */ + kHIDUsage_Sim_Clutch = 0xC6, /* Dynamic Value */ + kHIDUsage_Sim_Shifter = 0xC7, /* Dynamic Value */ + kHIDUsage_Sim_Steering = 0xC8, /* Dynamic Value */ + kHIDUsage_Sim_TurretDirection = 0xC9, /* Dynamic Value */ + kHIDUsage_Sim_BarrelElevation = 0xCA, /* Dynamic Value */ + kHIDUsage_Sim_DivePlane = 0xCB, /* Dynamic Value */ + kHIDUsage_Sim_Ballast = 0xCC, /* Dynamic Value */ + kHIDUsage_Sim_BicycleCrank = 0xCD, /* Dynamic Value */ + kHIDUsage_Sim_HandleBars = 0xCE, /* Dynamic Value */ + kHIDUsage_Sim_FrontBrake = 0xCF, /* Dynamic Value */ + kHIDUsage_Sim_RearBrake = 0xD0, /* Dynamic Value */ + /* 0xD1 - 0xFFFF Reserved */ + kHIDUsage_Sim_Reserved = 0xFFFF, +}; + +/* VR Page (0x03) */ +/* Virtual Reality controls depend on designators to identify the individual controls. Most of the following are */ +/* usages are applied to the collections of entities that comprise the actual device. */ +enum +{ + kHIDUsage_VR_Belt = 0x01, /* Application Collection */ + kHIDUsage_VR_BodySuit = 0x02, /* Application Collection */ + kHIDUsage_VR_Flexor = 0x03, /* Physical Collection */ + kHIDUsage_VR_Glove = 0x04, /* Application Collection */ + kHIDUsage_VR_HeadTracker = 0x05, /* Physical Collection */ + kHIDUsage_VR_HeadMountedDisplay = 0x06, /* Application Collection */ + kHIDUsage_VR_HandTracker = 0x07, /* Application Collection */ + kHIDUsage_VR_Oculometer = 0x08, /* Application Collection */ + kHIDUsage_VR_Vest = 0x09, /* Application Collection */ + kHIDUsage_VR_AnimatronicDevice = 0x0A, /* Application Collection */ + /* 0x0B - 0x1F Reserved */ + kHIDUsage_VR_StereoEnable = 0x20, /* On/Off Control */ + kHIDUsage_VR_DisplayEnable = 0x21, /* On/Off Control */ + /* 0x22 - 0xFFFF Reserved */ + kHIDUsage_VR_Reserved = 0xFFFF, +}; + +/* Sport Page (0x04) */ +enum +{ + kHIDUsage_Sprt_BaseballBat = 0x01, /* Application Collection */ + kHIDUsage_Sprt_GolfClub = 0x02, /* Application Collection */ + kHIDUsage_Sprt_RowingMachine = 0x03, /* Application Collection */ + kHIDUsage_Sprt_Treadmill = 0x04, /* Application Collection */ + /* 0x05 - 0x2F Reserved */ + kHIDUsage_Sprt_Oar = 0x30, /* Dynamic Value */ + kHIDUsage_Sprt_Slope = 0x31, /* Dynamic Value */ + kHIDUsage_Sprt_Rate = 0x32, /* Dynamic Value */ + kHIDUsage_Sprt_StickSpeed = 0x33, /* Dynamic Value */ + kHIDUsage_Sprt_StickFaceAngle = 0x34, /* Dynamic Value */ + kHIDUsage_Sprt_StickHeelOrToe = 0x35, /* Dynamic Value */ + kHIDUsage_Sprt_StickFollowThrough = 0x36, /* Dynamic Value */ + kHIDUsage_Sprt_StickTempo = 0x37, /* Dynamic Value */ + kHIDUsage_Sprt_StickType = 0x38, /* Named Array */ + kHIDUsage_Sprt_StickHeight = 0x39, /* Dynamic Value */ + /* 0x3A - 0x4F Reserved */ + kHIDUsage_Sprt_Putter = 0x50, /* Selector */ + kHIDUsage_Sprt_1Iron = 0x51, /* Selector */ + kHIDUsage_Sprt_2Iron = 0x52, /* Selector */ + kHIDUsage_Sprt_3Iron = 0x53, /* Selector */ + kHIDUsage_Sprt_4Iron = 0x54, /* Selector */ + kHIDUsage_Sprt_5Iron = 0x55, /* Selector */ + kHIDUsage_Sprt_6Iron = 0x56, /* Selector */ + kHIDUsage_Sprt_7Iron = 0x57, /* Selector */ + kHIDUsage_Sprt_8Iron = 0x58, /* Selector */ + kHIDUsage_Sprt_9Iron = 0x59, /* Selector */ + kHIDUsage_Sprt_10Iron = 0x5A, /* Selector */ + kHIDUsage_Sprt_11Iron = 0x5B, /* Selector */ + kHIDUsage_Sprt_SandWedge = 0x5C, /* Selector */ + kHIDUsage_Sprt_LoftWedge = 0x5D, /* Selector */ + kHIDUsage_Sprt_PowerWedge = 0x5E, /* Selector */ + kHIDUsage_Sprt_1Wood = 0x5F, /* Selector */ + kHIDUsage_Sprt_3Wood = 0x60, /* Selector */ + kHIDUsage_Sprt_5Wood = 0x61, /* Selector */ + kHIDUsage_Sprt_7Wood = 0x62, /* Selector */ + kHIDUsage_Sprt_9Wood = 0x63, /* Selector */ + /* 0x64 - 0xFFFF Reserved */ + kHIDUsage_Sprt_Reserved = 0xFFFF, +}; + +/* Game Page (0x05) */ +enum +{ + kHIDUsage_Game_3DGameController = 0x01, /* Application Collection */ + kHIDUsage_Game_PinballDevice = 0x02, /* Application Collection */ + kHIDUsage_Game_GunDevice = 0x03, /* Application Collection */ + /* 0x04 - 0x1F Reserved */ + kHIDUsage_Game_PointofView = 0x20, /* Physical Collection */ + kHIDUsage_Game_TurnRightOrLeft = 0x21, /* Dynamic Value */ + kHIDUsage_Game_PitchUpOrDown = 0x22, /* Dynamic Value */ + kHIDUsage_Game_RollRightOrLeft = 0x23, /* Dynamic Value */ + kHIDUsage_Game_MoveRightOrLeft = 0x24, /* Dynamic Value */ + kHIDUsage_Game_MoveForwardOrBackward = 0x25, /* Dynamic Value */ + kHIDUsage_Game_MoveUpOrDown = 0x26, /* Dynamic Value */ + kHIDUsage_Game_LeanRightOrLeft = 0x27, /* Dynamic Value */ + kHIDUsage_Game_LeanForwardOrBackward = 0x28, /* Dynamic Value */ + kHIDUsage_Game_HeightOfPOV = 0x29, /* Dynamic Value */ + kHIDUsage_Game_Flipper = 0x2A, /* Momentary Control */ + kHIDUsage_Game_SecondaryFlipper = 0x2B, /* Momentary Control */ + kHIDUsage_Game_Bump = 0x2C, /* Momentary Control */ + kHIDUsage_Game_NewGame = 0x2D, /* One-Shot Control */ + kHIDUsage_Game_ShootBall = 0x2E, /* One-Shot Control */ + kHIDUsage_Game_Player = 0x2F, /* One-Shot Control */ + kHIDUsage_Game_GunBolt = 0x30, /* On/Off Control */ + kHIDUsage_Game_GunClip = 0x31, /* On/Off Control */ + kHIDUsage_Game_Gun = 0x32, /* Selector */ + kHIDUsage_Game_GunSingleShot = 0x33, /* Selector */ + kHIDUsage_Game_GunBurst = 0x34, /* Selector */ + kHIDUsage_Game_GunAutomatic = 0x35, /* Selector */ + kHIDUsage_Game_GunSafety = 0x36, /* On/Off Control */ + kHIDUsage_Game_GamepadFireOrJump = 0x37, /* Logical Collection */ + kHIDUsage_Game_GamepadTrigger = 0x39, /* Logical Collection */ + /* 0x3A - 0xFFFF Reserved */ + kHIDUsage_Game_Reserved = 0xFFFF, +}; + +/* KeyboardOrKeypad Page (0x07) */ +/* This section is the Usage Page for key codes to be used in implementing a USB keyboard. A Boot Keyboard (84-, 101- or 104-key) should at a minimum support all associated usage codes as indicated in the ÒBootÓ */ +/* column below. */ +/* The usage type of all key codes is Selectors (Sel), except for the modifier keys Keyboard Left Control (0x224) to Keyboard Right GUI (0x231) which are Dynamic Flags (DV). */ +/* Note: A general note on Usages and languages: Due to the variation of keyboards from language to language, it is not feasible to specify exact key mappings for every language. Where this list is not specific for a key function in a language, the closest equivalent key position should be used, so that a keyboard may be modified for a different language by simply printing different keycaps. One example is the Y key on a North American keyboard. In Germany this is typically Z. Rather than changing the keyboard firmware to put the Z Usage into that place in the descriptor list, the vendor should use the Y Usage on both the North American and German keyboards. This continues to be the existing practice in the industry, in order to minimize the number of changes to the electronics to accommodate otherlanguages. */ +enum +{ + kHIDUsage_KeyboardErrorRollOver = 0x01, /* ErrorRollOver */ + kHIDUsage_KeyboardPOSTFail = 0x02, /* POSTFail */ + kHIDUsage_KeyboardErrorUndefined = 0x03, /* ErrorUndefined */ + kHIDUsage_KeyboardA = 0x04, /* a or A */ + kHIDUsage_KeyboardB = 0x05, /* b or B */ + kHIDUsage_KeyboardC = 0x06, /* c or C */ + kHIDUsage_KeyboardD = 0x07, /* d or D */ + kHIDUsage_KeyboardE = 0x08, /* e or E */ + kHIDUsage_KeyboardF = 0x09, /* f or F */ + kHIDUsage_KeyboardG = 0x0A, /* g or G */ + kHIDUsage_KeyboardH = 0x0B, /* h or H */ + kHIDUsage_KeyboardI = 0x0C, /* i or I */ + kHIDUsage_KeyboardJ = 0x0D, /* j or J */ + kHIDUsage_KeyboardK = 0x0E, /* k or K */ + kHIDUsage_KeyboardL = 0x0F, /* l or L */ + kHIDUsage_KeyboardM = 0x10, /* m or M */ + kHIDUsage_KeyboardN = 0x11, /* n or N */ + kHIDUsage_KeyboardO = 0x12, /* o or O */ + kHIDUsage_KeyboardP = 0x13, /* p or P */ + kHIDUsage_KeyboardQ = 0x14, /* q or Q */ + kHIDUsage_KeyboardR = 0x15, /* r or R */ + kHIDUsage_KeyboardS = 0x16, /* s or S */ + kHIDUsage_KeyboardT = 0x17, /* t or T */ + kHIDUsage_KeyboardU = 0x18, /* u or U */ + kHIDUsage_KeyboardV = 0x19, /* v or V */ + kHIDUsage_KeyboardW = 0x1A, /* w or W */ + kHIDUsage_KeyboardX = 0x1B, /* x or X */ + kHIDUsage_KeyboardY = 0x1C, /* y or Y */ + kHIDUsage_KeyboardZ = 0x1D, /* z or Z */ + kHIDUsage_Keyboard1 = 0x1E, /* 1 or ! */ + kHIDUsage_Keyboard2 = 0x1F, /* 2 or @ */ + kHIDUsage_Keyboard3 = 0x20, /* 3 or # */ + kHIDUsage_Keyboard4 = 0x21, /* 4 or $ */ + kHIDUsage_Keyboard5 = 0x22, /* 5 or % */ + kHIDUsage_Keyboard6 = 0x23, /* 6 or ^ */ + kHIDUsage_Keyboard7 = 0x24, /* 7 or & */ + kHIDUsage_Keyboard8 = 0x25, /* 8 or * */ + kHIDUsage_Keyboard9 = 0x26, /* 9 or ( */ + kHIDUsage_Keyboard0 = 0x27, /* 0 or ) */ + kHIDUsage_KeyboardReturnOrEnter = 0x28, /* Return (Enter) */ + kHIDUsage_KeyboardEscape = 0x29, /* Escape */ + kHIDUsage_KeyboardDeleteOrBackspace = 0x2A, /* Delete (Backspace) */ + kHIDUsage_KeyboardTab = 0x2B, /* Tab */ + kHIDUsage_KeyboardSpacebar = 0x2C, /* Spacebar */ + kHIDUsage_KeyboardHyphen = 0x2D, /* - or _ */ + kHIDUsage_KeyboardEqualSign = 0x2E, /* = or + */ + kHIDUsage_KeyboardOpenBracket = 0x2F, /* [ or { */ + kHIDUsage_KeyboardCloseBracket = 0x30, /* ] or } */ + kHIDUsage_KeyboardBackslash = 0x31, /* \ or | */ + kHIDUsage_KeyboardNonUSPound = 0x32, /* Non-US # or _ */ + kHIDUsage_KeyboardSemicolon = 0x33, /* ; or : */ + kHIDUsage_KeyboardQuote = 0x34, /* ' or " */ + kHIDUsage_KeyboardGraveAccentAndTilde = 0x35, /* Grave Accent and Tilde */ + kHIDUsage_KeyboardComma = 0x36, /* , or < */ + kHIDUsage_KeyboardPeriod = 0x37, /* . or > */ + kHIDUsage_KeyboardSlash = 0x38, /* / or ? */ + kHIDUsage_KeyboardCapsLock = 0x39, /* Caps Lock */ + kHIDUsage_KeyboardF1 = 0x3A, /* F1 */ + kHIDUsage_KeyboardF2 = 0x3B, /* F2 */ + kHIDUsage_KeyboardF3 = 0x3C, /* F3 */ + kHIDUsage_KeyboardF4 = 0x3D, /* F4 */ + kHIDUsage_KeyboardF5 = 0x3E, /* F5 */ + kHIDUsage_KeyboardF6 = 0x3F, /* F6 */ + kHIDUsage_KeyboardF7 = 0x40, /* F7 */ + kHIDUsage_KeyboardF8 = 0x41, /* F8 */ + kHIDUsage_KeyboardF9 = 0x42, /* F9 */ + kHIDUsage_KeyboardF10 = 0x43, /* F10 */ + kHIDUsage_KeyboardF11 = 0x44, /* F11 */ + kHIDUsage_KeyboardF12 = 0x45, /* F12 */ + kHIDUsage_KeyboardPrintScreen = 0x46, /* Print Screen */ + kHIDUsage_KeyboardScrollLock = 0x47, /* Scroll Lock */ + kHIDUsage_KeyboardPause = 0x48, /* Pause */ + kHIDUsage_KeyboardInsert = 0x49, /* Insert */ + kHIDUsage_KeyboardHome = 0x4A, /* Home */ + kHIDUsage_KeyboardPageUp = 0x4B, /* Page Up */ + kHIDUsage_KeyboardDeleteForward = 0x4C, /* Delete Forward */ + kHIDUsage_KeyboardEnd = 0x4D, /* End */ + kHIDUsage_KeyboardPageDown = 0x4E, /* Page Down */ + kHIDUsage_KeyboardRightArrow = 0x4F, /* Right Arrow */ + kHIDUsage_KeyboardLeftArrow = 0x50, /* Left Arrow */ + kHIDUsage_KeyboardDownArrow = 0x51, /* Down Arrow */ + kHIDUsage_KeyboardUpArrow = 0x52, /* Up Arrow */ + kHIDUsage_KeypadNumLock = 0x53, /* Keypad NumLock or Clear */ + kHIDUsage_KeypadSlash = 0x54, /* Keypad / */ + kHIDUsage_KeypadAsterisk = 0x55, /* Keypad * */ + kHIDUsage_KeypadHyphen = 0x56, /* Keypad - */ + kHIDUsage_KeypadPlus = 0x57, /* Keypad + */ + kHIDUsage_KeypadEnter = 0x58, /* Keypad Enter */ + kHIDUsage_Keypad1 = 0x59, /* Keypad 1 or End */ + kHIDUsage_Keypad2 = 0x5A, /* Keypad 2 or Down Arrow */ + kHIDUsage_Keypad3 = 0x5B, /* Keypad 3 or Page Down */ + kHIDUsage_Keypad4 = 0x5C, /* Keypad 4 or Left Arrow */ + kHIDUsage_Keypad5 = 0x5D, /* Keypad 5 */ + kHIDUsage_Keypad6 = 0x5E, /* Keypad 6 or Right Arrow */ + kHIDUsage_Keypad7 = 0x5F, /* Keypad 7 or Home */ + kHIDUsage_Keypad8 = 0x60, /* Keypad 8 or Up Arrow */ + kHIDUsage_Keypad9 = 0x61, /* Keypad 9 or Page Up */ + kHIDUsage_Keypad0 = 0x62, /* Keypad 0 or Insert */ + kHIDUsage_KeypadPeriod = 0x63, /* Keypad . or Delete */ + kHIDUsage_KeyboardNonUSBackslash = 0x64, /* Non-US \ or | */ + kHIDUsage_KeyboardApplication = 0x65, /* Application */ + kHIDUsage_KeyboardPower = 0x66, /* Power */ + kHIDUsage_KeypadEqualSign = 0x67, /* Keypad = */ + kHIDUsage_KeyboardF13 = 0x68, /* F13 */ + kHIDUsage_KeyboardF14 = 0x69, /* F14 */ + kHIDUsage_KeyboardF15 = 0x6A, /* F15 */ + kHIDUsage_KeyboardF16 = 0x6B, /* F16 */ + kHIDUsage_KeyboardF17 = 0x6C, /* F17 */ + kHIDUsage_KeyboardF18 = 0x6D, /* F18 */ + kHIDUsage_KeyboardF19 = 0x6E, /* F19 */ + kHIDUsage_KeyboardF20 = 0x6F, /* F20 */ + kHIDUsage_KeyboardF21 = 0x70, /* F21 */ + kHIDUsage_KeyboardF22 = 0x71, /* F22 */ + kHIDUsage_KeyboardF23 = 0x72, /* F23 */ + kHIDUsage_KeyboardF24 = 0x73, /* F24 */ + kHIDUsage_KeyboardExecute = 0x74, /* Execute */ + kHIDUsage_KeyboardHelp = 0x75, /* Help */ + kHIDUsage_KeyboardMenu = 0x76, /* Menu */ + kHIDUsage_KeyboardSelect = 0x77, /* Select */ + kHIDUsage_KeyboardStop = 0x78, /* Stop */ + kHIDUsage_KeyboardAgain = 0x79, /* Again */ + kHIDUsage_KeyboardUndo = 0x7A, /* Undo */ + kHIDUsage_KeyboardCut = 0x7B, /* Cut */ + kHIDUsage_KeyboardCopy = 0x7C, /* Copy */ + kHIDUsage_KeyboardPaste = 0x7D, /* Paste */ + kHIDUsage_KeyboardFind = 0x7E, /* Find */ + kHIDUsage_KeyboardMute = 0x7F, /* Mute */ + kHIDUsage_KeyboardVolumeUp = 0x80, /* Volume Up */ + kHIDUsage_KeyboardVolumeDown = 0x81, /* Volume Down */ + kHIDUsage_KeyboardLockingCapsLock = 0x82, /* Locking Caps Lock */ + kHIDUsage_KeyboardLockingNumLock = 0x83, /* Locking Num Lock */ + kHIDUsage_KeyboardLockingScrollLock = 0x84, /* Locking Scroll Lock */ + kHIDUsage_KeypadComma = 0x85, /* Keypad Comma */ + kHIDUsage_KeypadEqualSignAS400 = 0x86, /* Keypad Equal Sign for AS/400 */ + kHIDUsage_KeyboardInternational1 = 0x87, /* International1 */ + kHIDUsage_KeyboardInternational2 = 0x88, /* International2 */ + kHIDUsage_KeyboardInternational3 = 0x89, /* International3 */ + kHIDUsage_KeyboardInternational4 = 0x8A, /* International4 */ + kHIDUsage_KeyboardInternational5 = 0x8B, /* International5 */ + kHIDUsage_KeyboardInternational6 = 0x8C, /* International6 */ + kHIDUsage_KeyboardInternational7 = 0x8D, /* International7 */ + kHIDUsage_KeyboardInternational8 = 0x8E, /* International8 */ + kHIDUsage_KeyboardInternational9 = 0x8F, /* International9 */ + kHIDUsage_KeyboardLANG1 = 0x90, /* LANG1 */ + kHIDUsage_KeyboardLANG2 = 0x91, /* LANG2 */ + kHIDUsage_KeyboardLANG3 = 0x92, /* LANG3 */ + kHIDUsage_KeyboardLANG4 = 0x93, /* LANG4 */ + kHIDUsage_KeyboardLANG5 = 0x94, /* LANG5 */ + kHIDUsage_KeyboardLANG6 = 0x95, /* LANG6 */ + kHIDUsage_KeyboardLANG7 = 0x96, /* LANG7 */ + kHIDUsage_KeyboardLANG8 = 0x97, /* LANG8 */ + kHIDUsage_KeyboardLANG9 = 0x98, /* LANG9 */ + kHIDUsage_KeyboardAlternateErase = 0x99, /* AlternateErase */ + kHIDUsage_KeyboardSysReqOrAttention = 0x9A, /* SysReq/Attention */ + kHIDUsage_KeyboardCancel = 0x9B, /* Cancel */ + kHIDUsage_KeyboardClear = 0x9C, /* Clear */ + kHIDUsage_KeyboardPrior = 0x9D, /* Prior */ + kHIDUsage_KeyboardReturn = 0x9E, /* Return */ + kHIDUsage_KeyboardSeparator = 0x9F, /* Separator */ + kHIDUsage_KeyboardOut = 0xA0, /* Out */ + kHIDUsage_KeyboardOper = 0xA1, /* Oper */ + kHIDUsage_KeyboardClearOrAgain = 0xA2, /* Clear/Again */ + kHIDUsage_KeyboardCrSelOrProps = 0xA3, /* CrSel/Props */ + kHIDUsage_KeyboardExSel = 0xA4, /* ExSel */ + /* 0xA5-0xDF Reserved */ + kHIDUsage_KeyboardLeftControl = 0xE0, /* Left Control */ + kHIDUsage_KeyboardLeftShift = 0xE1, /* Left Shift */ + kHIDUsage_KeyboardLeftAlt = 0xE2, /* Left Alt */ + kHIDUsage_KeyboardLeftGUI = 0xE3, /* Left GUI */ + kHIDUsage_KeyboardRightControl = 0xE4, /* Right Control */ + kHIDUsage_KeyboardRightShift = 0xE5, /* Right Shift */ + kHIDUsage_KeyboardRightAlt = 0xE6, /* Right Alt */ + kHIDUsage_KeyboardRightGUI = 0xE7, /* Right GUI */ + /* 0xE8-0xFFFF Reserved */ + kHIDUsage_Keyboard_Reserved = 0xFFFF, +}; + +/* LEDs Page (0x08) */ +/* An LED or indicator is implemented as an On/Off Control (OOF) using the ÒSingle button toggleÓ mode, where a value of 1 will turn on the indicator, and a value of 0 will turn it off. The exceptions are described below. */ +enum +{ + kHIDUsage_LED_NumLock = 0x01, /* On/Off Control */ + kHIDUsage_LED_CapsLock = 0x02, /* On/Off Control */ + kHIDUsage_LED_ScrollLock = 0x03, /* On/Off Control */ + kHIDUsage_LED_Compose = 0x04, /* On/Off Control */ + kHIDUsage_LED_Kana = 0x05, /* On/Off Control */ + kHIDUsage_LED_Power = 0x06, /* On/Off Control */ + kHIDUsage_LED_Shift = 0x07, /* On/Off Control */ + kHIDUsage_LED_DoNotDisturb = 0x08, /* On/Off Control */ + kHIDUsage_LED_Mute = 0x09, /* On/Off Control */ + kHIDUsage_LED_ToneEnable = 0x0A, /* On/Off Control */ + kHIDUsage_LED_HighCutFilter = 0x0B, /* On/Off Control */ + kHIDUsage_LED_LowCutFilter = 0x0C, /* On/Off Control */ + kHIDUsage_LED_EqualizerEnable = 0x0D, /* On/Off Control */ + kHIDUsage_LED_SoundFieldOn = 0x0E, /* On/Off Control */ + kHIDUsage_LED_SurroundOn = 0x0F, /* On/Off Control */ + kHIDUsage_LED_Repeat = 0x10, /* On/Off Control */ + kHIDUsage_LED_Stereo = 0x11, /* On/Off Control */ + kHIDUsage_LED_SamplingRateDetect = 0x12, /* On/Off Control */ + kHIDUsage_LED_Spinning = 0x13, /* On/Off Control */ + kHIDUsage_LED_CAV = 0x14, /* On/Off Control */ + kHIDUsage_LED_CLV = 0x15, /* On/Off Control */ + kHIDUsage_LED_RecordingFormatDetect = 0x16, /* On/Off Control */ + kHIDUsage_LED_OffHook = 0x17, /* On/Off Control */ + kHIDUsage_LED_Ring = 0x18, /* On/Off Control */ + kHIDUsage_LED_MessageWaiting = 0x19, /* On/Off Control */ + kHIDUsage_LED_DataMode = 0x1A, /* On/Off Control */ + kHIDUsage_LED_BatteryOperation = 0x1B, /* On/Off Control */ + kHIDUsage_LED_BatteryOK = 0x1C, /* On/Off Control */ + kHIDUsage_LED_BatteryLow = 0x1D, /* On/Off Control */ + kHIDUsage_LED_Speaker = 0x1E, /* On/Off Control */ + kHIDUsage_LED_HeadSet = 0x1F, /* On/Off Control */ + kHIDUsage_LED_Hold = 0x20, /* On/Off Control */ + kHIDUsage_LED_Microphone = 0x21, /* On/Off Control */ + kHIDUsage_LED_Coverage = 0x22, /* On/Off Control */ + kHIDUsage_LED_NightMode = 0x23, /* On/Off Control */ + kHIDUsage_LED_SendCalls = 0x24, /* On/Off Control */ + kHIDUsage_LED_CallPickup = 0x25, /* On/Off Control */ + kHIDUsage_LED_Conference = 0x26, /* On/Off Control */ + kHIDUsage_LED_StandBy = 0x27, /* On/Off Control */ + kHIDUsage_LED_CameraOn = 0x28, /* On/Off Control */ + kHIDUsage_LED_CameraOff = 0x29, /* On/Off Control */ + kHIDUsage_LED_OnLine = 0x2A, /* On/Off Control */ + kHIDUsage_LED_OffLine = 0x2B, /* On/Off Control */ + kHIDUsage_LED_Busy = 0x2C, /* On/Off Control */ + kHIDUsage_LED_Ready = 0x2D, /* On/Off Control */ + kHIDUsage_LED_PaperOut = 0x2E, /* On/Off Control */ + kHIDUsage_LED_PaperJam = 0x2F, /* On/Off Control */ + kHIDUsage_LED_Remote = 0x30, /* On/Off Control */ + kHIDUsage_LED_Forward = 0x31, /* On/Off Control */ + kHIDUsage_LED_Reverse = 0x32, /* On/Off Control */ + kHIDUsage_LED_Stop = 0x33, /* On/Off Control */ + kHIDUsage_LED_Rewind = 0x34, /* On/Off Control */ + kHIDUsage_LED_FastForward = 0x35, /* On/Off Control */ + kHIDUsage_LED_Play = 0x36, /* On/Off Control */ + kHIDUsage_LED_Pause = 0x37, /* On/Off Control */ + kHIDUsage_LED_Record = 0x38, /* On/Off Control */ + kHIDUsage_LED_Error = 0x39, /* On/Off Control */ + kHIDUsage_LED_Usage = 0x3A, /* Selector */ + kHIDUsage_LED_UsageInUseIndicator = 0x3B, /* Usage Switch */ + kHIDUsage_LED_UsageMultiModeIndicator = 0x3C, /* Usage Modifier */ + kHIDUsage_LED_IndicatorOn = 0x3D, /* Selector */ + kHIDUsage_LED_IndicatorFlash = 0x3E, /* Selector */ + kHIDUsage_LED_IndicatorSlowBlink = 0x3F, /* Selector */ + kHIDUsage_LED_IndicatorFastBlink = 0x40, /* Selector */ + kHIDUsage_LED_IndicatorOff = 0x41, /* Selector */ + kHIDUsage_LED_FlashOnTime = 0x42, /* Dynamic Value */ + kHIDUsage_LED_SlowBlinkOnTime = 0x43, /* Dynamic Value */ + kHIDUsage_LED_SlowBlinkOffTime = 0x44, /* Dynamic Value */ + kHIDUsage_LED_FastBlinkOnTime = 0x45, /* Dynamic Value */ + kHIDUsage_LED_FastBlinkOffTime = 0x46, /* Dynamic Value */ + kHIDUsage_LED_UsageIndicatorColor = 0x47, /* Usage Modifier */ + kHIDUsage_LED_IndicatorRed = 0x48, /* Selector */ + kHIDUsage_LED_IndicatorGreen = 0x49, /* Selector */ + kHIDUsage_LED_IndicatorAmber = 0x4A, /* Selector */ + kHIDUsage_LED_GenericIndicator = 0x4B, /* On/Off Control */ + kHIDUsage_LED_SystemSuspend = 0x4C, /* On/Off Control */ + kHIDUsage_LED_ExternalPowerConnected = 0x4D, /* On/Off Control */ + /* 0x4E - 0xFFFF Reserved */ + kHIDUsage_LED_Reserved = 0xFFFF, +}; + +/* Button Page (0x09) */ +/* The Button page is the first place an application should look for user selection controls. System graphical user interfaces typically employ a pointer and a set of hierarchical selectors to select, move and otherwise manipulate their environment. For these purposes the following assignment of significance can be applied to the Button usages: */ +/* ¥ Button 1, Primary Button. Used for object selecting, dragging, and double click activation. On MacOS, this is the only button. Microsoft operating systems call this a logical left button, because it */ +/* is not necessarily physically located on the left of the pointing device. */ +/* ¥ Button 2, Secondary Button. Used by newer graphical user interfaces to browse object properties. Exposed by systems to applications that typically assign application-specific functionality. */ +/* ¥ Button 3, Tertiary Button. Optional control. Exposed to applications, but seldom assigned functionality due to prevalence of two- and one-button devices. */ +/* ¥ Buttons 4 -55. As the button number increases, its significance as a selector decreases. */ +/* In many ways the assignment of button numbers is similar to the assignment of Effort in Physical descriptors. Button 1 would be used to define the button a finger rests on when the hand is in the Òat restÓ position, that is, virtually no effort is required by the user to activate the button. Button values increment as the finger has to stretch to reach a control. See Section 6.2.3, ÒPhysical Descriptors,Ó in the HID Specification for methods of further qualifying buttons. */ +enum +{ + kHIDUsage_Button_1 = 0x01, /* (primary/trigger) */ + kHIDUsage_Button_2 = 0x02, /* (secondary) */ + kHIDUsage_Button_3 = 0x03, /* (tertiary) */ + kHIDUsage_Button_4 = 0x04, /* 4th button */ + /* ... */ + kHIDUsage_Button_65535 = 0xFFFF, +}; + +/* Ordinal Page (0x0A) */ +/* The Ordinal page allows multiple instances of a control or sets of controls to be declared without requiring individual enumeration in the native usage page. For example, it is not necessary to declare usages of Pointer 1, Pointer 2, and so forth on the Generic Desktop page. When parsed, the ordinal instance number is, in essence, concatenated to the usages attached to the encompassing collection to create Pointer 1, Pointer 2, and so forth. */ +/* For an example, see Section A.5, ÒMultiple Instances of a Control,Ó in Appendix A, ÒUsage Examples.Ó By convention, an Ordinal collection is placed inside the collection for which it is declaring multiple instances. */ +/* Instances do not have to be identical. */ +enum +{ + /* 0x00 Reserved */ + kHIDUsage_Ord_Instance1 = 0x01, /* Usage Modifier */ + kHIDUsage_Ord_Instance2 = 0x02, /* Usage Modifier */ + kHIDUsage_Ord_Instance3 = 0x03, /* Usage Modifier */ + kHIDUsage_Ord_Instance4 = 0x04, /* Usage Modifier */ + kHIDUsage_Ord_Instance65535 = 0xFFFF, /* Usage Modifier */ +}; + +/* Telephony Page (0x0B) */ +/* This usage page defines the keytop and control usages for telephony devices. */ +/* Indicators on a phone are handled by wrapping them in LED: Usage In Use Indicator and LED: Usage Selected Indicator usages. For example, a message-indicator LED would be identified by a Telephony: Message usage declared as a Feature or Output in a LED: Usage In Use Indicator collection. */ +/* See Section 14, ÒConsumer Page (0x0C),Ó for audio volume and tone controls. */ +enum +{ + kHIDUsage_Tfon_Phone = 0x01, /* Application Collection */ + kHIDUsage_Tfon_AnsweringMachine = 0x02, /* Application Collection */ + kHIDUsage_Tfon_MessageControls = 0x03, /* Logical Collection */ + kHIDUsage_Tfon_Handset = 0x04, /* Logical Collection */ + kHIDUsage_Tfon_Headset = 0x05, /* Logical Collection */ + kHIDUsage_Tfon_TelephonyKeyPad = 0x06, /* Named Array */ + kHIDUsage_Tfon_ProgrammableButton = 0x07, /* Named Array */ + /* 0x08 - 0x1F Reserved */ + kHIDUsage_Tfon_HookSwitch = 0x20, /* On/Off Control */ + kHIDUsage_Tfon_Flash = 0x21, /* Momentary Control */ + kHIDUsage_Tfon_Feature = 0x22, /* One-Shot Control */ + kHIDUsage_Tfon_Hold = 0x23, /* On/Off Control */ + kHIDUsage_Tfon_Redial = 0x24, /* One-Shot Control */ + kHIDUsage_Tfon_Transfer = 0x25, /* One-Shot Control */ + kHIDUsage_Tfon_Drop = 0x26, /* One-Shot Control */ + kHIDUsage_Tfon_Park = 0x27, /* On/Off Control */ + kHIDUsage_Tfon_ForwardCalls = 0x28, /* On/Off Control */ + kHIDUsage_Tfon_AlternateFunction = 0x29, /* Momentary Control */ + kHIDUsage_Tfon_Line = 0x2A, /* One-Shot Control */ + kHIDUsage_Tfon_SpeakerPhone = 0x2B, /* On/Off Control */ + kHIDUsage_Tfon_Conference = 0x2C, /* On/Off Control */ + kHIDUsage_Tfon_RingEnable = 0x2D, /* On/Off Control */ + kHIDUsage_Tfon_Ring = 0x2E, /* Selector */ + kHIDUsage_Tfon_PhoneMute = 0x2F, /* On/Off Control */ + kHIDUsage_Tfon_CallerID = 0x30, /* Momentary Control */ + /* 0x31 - 0x4F Reserved */ + kHIDUsage_Tfon_SpeedDial = 0x50, /* One-Shot Control */ + kHIDUsage_Tfon_StoreNumber = 0x51, /* One-Shot Control */ + kHIDUsage_Tfon_RecallNumber = 0x52, /* One-Shot Control */ + kHIDUsage_Tfon_PhoneDirectory = 0x53, /* On/Off Control */ + /* 0x54 - 0x6F Reserved */ + kHIDUsage_Tfon_VoiceMail = 0x70, /* On/Off Control */ + kHIDUsage_Tfon_ScreenCalls = 0x71, /* On/Off Control */ + kHIDUsage_Tfon_DoNotDisturb = 0x72, /* On/Off Control */ + kHIDUsage_Tfon_Message = 0x73, /* One-Shot Control */ + kHIDUsage_Tfon_AnswerOnOrOff = 0x74, /* On/Off Control */ + /* 0x75 - 0x8F Reserved */ + kHIDUsage_Tfon_InsideDialTone = 0x90, /* Momentary Control */ + kHIDUsage_Tfon_OutsideDialTone = 0x91, /* Momentary Control */ + kHIDUsage_Tfon_InsideRingTone = 0x92, /* Momentary Control */ + kHIDUsage_Tfon_OutsideRingTone = 0x93, /* Momentary Control */ + kHIDUsage_Tfon_PriorityRingTone = 0x94, /* Momentary Control */ + kHIDUsage_Tfon_InsideRingback = 0x95, /* Momentary Control */ + kHIDUsage_Tfon_PriorityRingback = 0x96, /* Momentary Control */ + kHIDUsage_Tfon_LineBusyTone = 0x97, /* Momentary Control */ + kHIDUsage_Tfon_ReorderTone = 0x98, /* Momentary Control */ + kHIDUsage_Tfon_CallWaitingTone = 0x99, /* Momentary Control */ + kHIDUsage_Tfon_ConfirmationTone1 = 0x9A, /* Momentary Control */ + kHIDUsage_Tfon_ConfirmationTone2 = 0x9B, /* Momentary Control */ + kHIDUsage_Tfon_TonesOff = 0x9C, /* On/Off Control */ + kHIDUsage_Tfon_OutsideRingback = 0x9D, /* Momentary Control */ + /* 0x9E - 0xAF Reserved */ + kHIDUsage_Tfon_PhoneKey0 = 0xB0, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey1 = 0xB1, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey2 = 0xB2, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey3 = 0xB3, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey4 = 0xB4, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey5 = 0xB5, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey6 = 0xB6, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey7 = 0xB7, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey8 = 0xB8, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKey9 = 0xB9, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyStar = 0xBA, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyPound = 0xBB, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyA = 0xBC, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyB = 0xBD, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyC = 0xBE, /* Selector/One-Shot Control */ + kHIDUsage_Tfon_PhoneKeyD = 0xBF, /* Selector/One-Shot Control */ + /* 0xC0 - 0xFFFF Reserved */ + kHIDUsage_TFon_Reserved = 0xFFFF, +}; + +/* Consumer Page (0x0C) */ +/* All controls on the Consumer page are application-specific. That is, they affect a specific device, not the system as a whole. */ +enum +{ + kHIDUsage_Csmr_ConsumerControl = 0x01, /* Application Collection */ + kHIDUsage_Csmr_NumericKeyPad = 0x02, /* Named Array */ + kHIDUsage_Csmr_ProgrammableButtons = 0x03, /* Named Array */ + /* 0x03 - 0x1F Reserved */ + kHIDUsage_Csmr_Plus10 = 0x20, /* One-Shot Control */ + kHIDUsage_Csmr_Plus100 = 0x21, /* One-Shot Control */ + kHIDUsage_Csmr_AMOrPM = 0x22, /* One-Shot Control */ + /* 0x23 - 0x3F Reserved */ + kHIDUsage_Csmr_Power = 0x30, /* On/Off Control */ + kHIDUsage_Csmr_Reset = 0x31, /* One-Shot Control */ + kHIDUsage_Csmr_Sleep = 0x32, /* One-Shot Control */ + kHIDUsage_Csmr_SleepAfter = 0x33, /* One-Shot Control */ + kHIDUsage_Csmr_SleepMode = 0x34, /* Re-Trigger Control */ + kHIDUsage_Csmr_Illumination = 0x35, /* On/Off Control */ + kHIDUsage_Csmr_FunctionButtons = 0x36, /* Named Array */ + /* 0x37 - 0x3F Reserved */ + kHIDUsage_Csmr_Menu = 0x40, /* On/Off Control */ + kHIDUsage_Csmr_MenuPick = 0x41, /* One-Shot Control */ + kHIDUsage_Csmr_MenuUp = 0x42, /* One-Shot Control */ + kHIDUsage_Csmr_MenuDown = 0x43, /* One-Shot Control */ + kHIDUsage_Csmr_MenuLeft = 0x44, /* One-Shot Control */ + kHIDUsage_Csmr_MenuRight = 0x45, /* One-Shot Control */ + kHIDUsage_Csmr_MenuEscape = 0x46, /* One-Shot Control */ + kHIDUsage_Csmr_MenuValueIncrease = 0x47, /* One-Shot Control */ + kHIDUsage_Csmr_MenuValueDecrease = 0x48, /* One-Shot Control */ + /* 0x49 - 0x5F Reserved */ + kHIDUsage_Csmr_DataOnScreen = 0x60, /* On/Off Control */ + kHIDUsage_Csmr_ClosedCaption = 0x61, /* On/Off Control */ + kHIDUsage_Csmr_ClosedCaptionSelect = 0x62, /* Selector */ + kHIDUsage_Csmr_VCROrTV = 0x63, /* On/Off Control */ + kHIDUsage_Csmr_BroadcastMode = 0x64, /* One-Shot Control */ + kHIDUsage_Csmr_Snapshot = 0x65, /* One-Shot Control */ + kHIDUsage_Csmr_Still = 0x66, /* One-Shot Control */ + /* 0x67 - 0x7F Reserved */ + kHIDUsage_Csmr_Selection = 0x80, /* Named Array */ + kHIDUsage_Csmr_Assign = 0x81, /* Selector */ + kHIDUsage_Csmr_ModeStep = 0x82, /* One-Shot Control */ + kHIDUsage_Csmr_RecallLast = 0x83, /* One-Shot Control */ + kHIDUsage_Csmr_EnterChannel = 0x84, /* One-Shot Control */ + kHIDUsage_Csmr_OrderMovie = 0x85, /* One-Shot Control */ + kHIDUsage_Csmr_Channel = 0x86, /* Linear Control */ + kHIDUsage_Csmr_MediaSelection = 0x87, /* Selector */ + kHIDUsage_Csmr_MediaSelectComputer = 0x88, /* Selector */ + kHIDUsage_Csmr_MediaSelectTV = 0x89, /* Selector */ + kHIDUsage_Csmr_MediaSelectWWW = 0x8A, /* Selector */ + kHIDUsage_Csmr_MediaSelectDVD = 0x8B, /* Selector */ + kHIDUsage_Csmr_MediaSelectTelephone = 0x8C, /* Selector */ + kHIDUsage_Csmr_MediaSelectProgramGuide = 0x8D, /* Selector */ + kHIDUsage_Csmr_MediaSelectVideoPhone = 0x8E, /* Selector */ + kHIDUsage_Csmr_MediaSelectGames = 0x8F, /* Selector */ + kHIDUsage_Csmr_MediaSelectMessages = 0x90, /* Selector */ + kHIDUsage_Csmr_MediaSelectCD = 0x91, /* Selector */ + kHIDUsage_Csmr_MediaSelectVCR = 0x92, /* Selector */ + kHIDUsage_Csmr_MediaSelectTuner = 0x93, /* Selector */ + kHIDUsage_Csmr_Quit = 0x94, /* One-Shot Control */ + kHIDUsage_Csmr_Help = 0x95, /* On/Off Control */ + kHIDUsage_Csmr_MediaSelectTape = 0x96, /* Selector */ + kHIDUsage_Csmr_MediaSelectCable = 0x97, /* Selector */ + kHIDUsage_Csmr_MediaSelectSatellite = 0x98, /* Selector */ + kHIDUsage_Csmr_MediaSelectSecurity = 0x99, /* Selector */ + kHIDUsage_Csmr_MediaSelectHome = 0x9A, /* Selector */ + kHIDUsage_Csmr_MediaSelectCall = 0x9B, /* Selector */ + kHIDUsage_Csmr_ChannelIncrement = 0x9C, /* One-Shot Control */ + kHIDUsage_Csmr_ChannelDecrement = 0x9D, /* One-Shot Control */ + kHIDUsage_Csmr_Media = 0x9E, /* Selector */ + /* 0x9F Reserved */ + kHIDUsage_Csmr_VCRPlus = 0xA0, /* One-Shot Control */ + kHIDUsage_Csmr_Once = 0xA1, /* One-Shot Control */ + kHIDUsage_Csmr_Daily = 0xA2, /* One-Shot Control */ + kHIDUsage_Csmr_Weekly = 0xA3, /* One-Shot Control */ + kHIDUsage_Csmr_Monthly = 0xA4, /* One-Shot Control */ + /* 0xA5 - 0xAF Reserved */ + kHIDUsage_Csmr_Play = 0xB0, /* On/Off Control */ + kHIDUsage_Csmr_Pause = 0xB1, /* On/Off Control */ + kHIDUsage_Csmr_Record = 0xB2, /* On/Off Control */ + kHIDUsage_Csmr_FastForward = 0xB3, /* On/Off Control */ + kHIDUsage_Csmr_Rewind = 0xB4, /* On/Off Control */ + kHIDUsage_Csmr_ScanNextTrack = 0xB5, /* One-Shot Control */ + kHIDUsage_Csmr_ScanPreviousTrack = 0xB6, /* One-Shot Control */ + kHIDUsage_Csmr_Stop = 0xB7, /* One-Shot Control */ + kHIDUsage_Csmr_Eject = 0xB8, /* One-Shot Control */ + kHIDUsage_Csmr_RandomPlay = 0xB9, /* On/Off Control */ + kHIDUsage_Csmr_SelectDisc = 0xBA, /* Named Array */ + kHIDUsage_Csmr_EnterDisc = 0xBB, /* Momentary Control */ + kHIDUsage_Csmr_Repeat = 0xBC, /* One-Shot Control */ + kHIDUsage_Csmr_Tracking = 0xBD, /* Linear Control */ + kHIDUsage_Csmr_TrackNormal = 0xBE, /* One-Shot Control */ + kHIDUsage_Csmr_SlowTracking = 0xBF, /* Linear Control */ + kHIDUsage_Csmr_FrameForward = 0xC0, /* Re-Trigger Control */ + kHIDUsage_Csmr_FrameBack = 0xC1, /* Re-Trigger Control */ + kHIDUsage_Csmr_Mark = 0xC2, /* One-Shot Control */ + kHIDUsage_Csmr_ClearMark = 0xC3, /* One-Shot Control */ + kHIDUsage_Csmr_RepeatFromMark = 0xC4, /* On/Off Control */ + kHIDUsage_Csmr_ReturnToMark = 0xC5, /* One-Shot Control */ + kHIDUsage_Csmr_SearchMarkForward = 0xC6, /* One-Shot Control */ + kHIDUsage_Csmr_SearchMarkBackwards = 0xC7, /* One-Shot Control */ + kHIDUsage_Csmr_CounterReset = 0xC8, /* One-Shot Control */ + kHIDUsage_Csmr_ShowCounter = 0xC9, /* One-Shot Control */ + kHIDUsage_Csmr_TrackingIncrement = 0xCA, /* Re-Trigger Control */ + kHIDUsage_Csmr_TrackingDecrement = 0xCB, /* Re-Trigger Control */ + kHIDUsage_Csmr_StopOrEject = 0xCC, /* One-Shot Control */ + kHIDUsage_Csmr_PlayOrPause = 0xCD, /* One-Shot Control */ + kHIDUsage_Csmr_PlayOrSkip = 0xCE, /* One-Shot Control */ + /* 0xCF - 0xDF Reserved */ + kHIDUsage_Csmr_Volume = 0xE0, /* Linear Control */ + kHIDUsage_Csmr_Balance = 0xE1, /* Linear Control */ + kHIDUsage_Csmr_Mute = 0xE2, /* On/Off Control */ + kHIDUsage_Csmr_Bass = 0xE3, /* Linear Control */ + kHIDUsage_Csmr_Treble = 0xE4, /* Linear Control */ + kHIDUsage_Csmr_BassBoost = 0xE5, /* On/Off Control */ + kHIDUsage_Csmr_SurroundMode = 0xE6, /* One-Shot Control */ + kHIDUsage_Csmr_Loudness = 0xE7, /* On/Off Control */ + kHIDUsage_Csmr_MPX = 0xE8, /* On/Off Control */ + kHIDUsage_Csmr_VolumeIncrement = 0xE9, /* Re-Trigger Control */ + kHIDUsage_Csmr_VolumeDecrement = 0xEA, /* Re-Trigger Control */ + /* 0xEB - 0xEF Reserved */ + kHIDUsage_Csmr_Speed = 0xF0, /* Selector */ + kHIDUsage_Csmr_PlaybackSpeed = 0xF1, /* Named Array */ + kHIDUsage_Csmr_StandardPlay = 0xF2, /* Selector */ + kHIDUsage_Csmr_LongPlay = 0xF3, /* Selector */ + kHIDUsage_Csmr_ExtendedPlay = 0xF4, /* Selector */ + kHIDUsage_Csmr_Slow = 0xF5, /* One-Shot Control */ + /* 0xF6 - 0xFF Reserved */ + kHIDUsage_Csmr_FanEnable = 0x100, /* On/Off Control */ + kHIDUsage_Csmr_FanSpeed = 0x101, /* Linear Control */ + kHIDUsage_Csmr_LightEnable = 0x102, /* On/Off Control */ + kHIDUsage_Csmr_LightIlluminationLevel = 0x103, /* Linear Control */ + kHIDUsage_Csmr_ClimateControlEnable = 0x104, /* On/Off Control */ + kHIDUsage_Csmr_RoomTemperature = 0x105, /* Linear Control */ + kHIDUsage_Csmr_SecurityEnable = 0x106, /* On/Off Control */ + kHIDUsage_Csmr_FireAlarm = 0x107, /* One-Shot Control */ + kHIDUsage_Csmr_PoliceAlarm = 0x108, /* One-Shot Control */ + /* 0x109 - 0x14F Reserved */ + kHIDUsage_Csmr_BalanceRight = 0x150, /* Re-Trigger Control */ + kHIDUsage_Csmr_BalanceLeft = 0x151, /* Re-Trigger Control */ + kHIDUsage_Csmr_BassIncrement = 0x152, /* Re-Trigger Control */ + kHIDUsage_Csmr_BassDecrement = 0x153, /* Re-Trigger Control */ + kHIDUsage_Csmr_TrebleIncrement = 0x154, /* Re-Trigger Control */ + kHIDUsage_Csmr_TrebleDecrement = 0x155, /* Re-Trigger Control */ + /* 0x156 - 0x15F Reserved */ + kHIDUsage_Csmr_SpeakerSystem = 0x160, /* Logical Collection */ + kHIDUsage_Csmr_ChannelLeft = 0x161, /* Logical Collection */ + kHIDUsage_Csmr_ChannelRight = 0x162, /* Logical Collection */ + kHIDUsage_Csmr_ChannelCenter = 0x163, /* Logical Collection */ + kHIDUsage_Csmr_ChannelFront = 0x164, /* Logical Collection */ + kHIDUsage_Csmr_ChannelCenterFront = 0x165, /* Logical Collection */ + kHIDUsage_Csmr_ChannelSide = 0x166, /* Logical Collection */ + kHIDUsage_Csmr_ChannelSurround = 0x167, /* Logical Collection */ + kHIDUsage_Csmr_ChannelLowFrequencyEnhancement = 0x168, /* Logical Collection */ + kHIDUsage_Csmr_ChannelTop = 0x169, /* Logical Collection */ + kHIDUsage_Csmr_ChannelUnknown = 0x16A, /* Logical Collection */ + /* 0x16B - 0x16F Reserved */ + kHIDUsage_Csmr_SubChannel = 0x170, /* Linear Control */ + kHIDUsage_Csmr_SubChannelIncrement = 0x171, /* One-Shot Control */ + kHIDUsage_Csmr_SubChannelDecrement = 0x172, /* One-Shot Control */ + kHIDUsage_Csmr_AlternateAudioIncrement = 0x173, /* One-Shot Control */ + kHIDUsage_Csmr_AlternateAudioDecrement = 0x174, /* One-Shot Control */ + /* 0x175 - 0x17F Reserved */ + kHIDUsage_Csmr_ApplicationLaunchButtons = 0x180, /* Named Array */ + kHIDUsage_Csmr_ALLaunchButtonConfigurationTool = 0x181, /* Selector */ + kHIDUsage_Csmr_ALProgrammableButtonConfiguration = 0x182, /* Selector */ + kHIDUsage_Csmr_ALConsumerControlConfiguration = 0x183, /* Selector */ + kHIDUsage_Csmr_ALWordProcessor = 0x184, /* Selector */ + kHIDUsage_Csmr_ALTextEditor = 0x185, /* Selector */ + kHIDUsage_Csmr_ALSpreadsheet = 0x186, /* Selector */ + kHIDUsage_Csmr_ALGraphicsEditor = 0x187, /* Selector */ + kHIDUsage_Csmr_ALPresentationApp = 0x188, /* Selector */ + kHIDUsage_Csmr_ALDatabaseApp = 0x189, /* Selector */ + kHIDUsage_Csmr_ALEmailReader = 0x18A, /* Selector */ + kHIDUsage_Csmr_ALNewsreader = 0x18B, /* Selector */ + kHIDUsage_Csmr_ALVoicemail = 0x18C, /* Selector */ + kHIDUsage_Csmr_ALContactsOrAddressBook = 0x18D, /* Selector */ + kHIDUsage_Csmr_ALCalendarOrSchedule = 0x18E, /* Selector */ + kHIDUsage_Csmr_ALTaskOrProjectManager = 0x18F, /* Selector */ + kHIDUsage_Csmr_ALLogOrJournalOrTimecard = 0x190, /* Selector */ + kHIDUsage_Csmr_ALCheckbookOrFinance = 0x191, /* Selector */ + kHIDUsage_Csmr_ALCalculator = 0x192, /* Selector */ + kHIDUsage_Csmr_ALAOrVCaptureOrPlayback = 0x193, /* Selector */ + kHIDUsage_Csmr_ALLocalMachineBrowser = 0x194, /* Selector */ + kHIDUsage_Csmr_ALLANOrWANBrowser = 0x195, /* Selector */ + kHIDUsage_Csmr_ALInternetBrowser = 0x196, /* Selector */ + kHIDUsage_Csmr_ALRemoteNetworkingOrISPConnect = 0x197, /* Selector */ + kHIDUsage_Csmr_ALNetworkConference = 0x198, /* Selector */ + kHIDUsage_Csmr_ALNetworkChat = 0x199, /* Selector */ + kHIDUsage_Csmr_ALTelephonyOrDialer = 0x19A, /* Selector */ + kHIDUsage_Csmr_ALLogon = 0x19B, /* Selector */ + kHIDUsage_Csmr_ALLogoff = 0x19C, /* Selector */ + kHIDUsage_Csmr_ALLogonOrLogoff = 0x19D, /* Selector */ + kHIDUsage_Csmr_ALTerminalLockOrScreensaver = 0x19E, /* Selector */ + kHIDUsage_Csmr_ALControlPanel = 0x19F, /* Selector */ + kHIDUsage_Csmr_ALCommandLineProcessorOrRun = 0x1A0, /* Selector */ + kHIDUsage_Csmr_ALProcessOrTaskManager = 0x1A1, /* Selector */ + kHIDUsage_Csmr_AL = 0x1A2, /* Selector */ + kHIDUsage_Csmr_ALNextTaskOrApplication = 0x143, /* Selector */ + kHIDUsage_Csmr_ALPreviousTaskOrApplication = 0x1A4, /* Selector */ + kHIDUsage_Csmr_ALPreemptiveHaltTaskOrApplication = 0x1A5, /* Selector */ + /* 0x1A6 - 0x1FF Reserved */ + kHIDUsage_Csmr_GenericGUIApplicationControls = 0x200, /* Named Array */ + kHIDUsage_Csmr_ACNew = 0x201, /* Selector */ + kHIDUsage_Csmr_ACOpen = 0x202, /* Selector */ + kHIDUsage_Csmr_ACClose = 0x203, /* Selector */ + kHIDUsage_Csmr_ACExit = 0x204, /* Selector */ + kHIDUsage_Csmr_ACMaximize = 0x205, /* Selector */ + kHIDUsage_Csmr_ACMinimize = 0x206, /* Selector */ + kHIDUsage_Csmr_ACSave = 0x207, /* Selector */ + kHIDUsage_Csmr_ACPrint = 0x208, /* Selector */ + kHIDUsage_Csmr_ACProperties = 0x209, /* Selector */ + kHIDUsage_Csmr_ACUndo = 0x21A, /* Selector */ + kHIDUsage_Csmr_ACCopy = 0x21B, /* Selector */ + kHIDUsage_Csmr_ACCut = 0x21C, /* Selector */ + kHIDUsage_Csmr_ACPaste = 0x21D, /* Selector */ + kHIDUsage_Csmr_AC = 0x21E, /* Selector */ + kHIDUsage_Csmr_ACFind = 0x21F, /* Selector */ + kHIDUsage_Csmr_ACFindandReplace = 0x220, /* Selector */ + kHIDUsage_Csmr_ACSearch = 0x221, /* Selector */ + kHIDUsage_Csmr_ACGoTo = 0x222, /* Selector */ + kHIDUsage_Csmr_ACHome = 0x223, /* Selector */ + kHIDUsage_Csmr_ACBack = 0x224, /* Selector */ + kHIDUsage_Csmr_ACForward = 0x225, /* Selector */ + kHIDUsage_Csmr_ACStop = 0x226, /* Selector */ + kHIDUsage_Csmr_ACRefresh = 0x227, /* Selector */ + kHIDUsage_Csmr_ACPreviousLink = 0x228, /* Selector */ + kHIDUsage_Csmr_ACNextLink = 0x229, /* Selector */ + kHIDUsage_Csmr_ACBookmarks = 0x22A, /* Selector */ + kHIDUsage_Csmr_ACHistory = 0x22B, /* Selector */ + kHIDUsage_Csmr_ACSubscriptions = 0x22C, /* Selector */ + kHIDUsage_Csmr_ACZoomIn = 0x22D, /* Selector */ + kHIDUsage_Csmr_ACZoomOut = 0x22E, /* Selector */ + kHIDUsage_Csmr_ACZoom = 0x22F, /* Selector */ + kHIDUsage_Csmr_ACFullScreenView = 0x230, /* Selector */ + kHIDUsage_Csmr_ACNormalView = 0x231, /* Selector */ + kHIDUsage_Csmr_ACViewToggle = 0x232, /* Selector */ + kHIDUsage_Csmr_ACScrollUp = 0x233, /* Selector */ + kHIDUsage_Csmr_ACScrollDown = 0x234, /* Selector */ + kHIDUsage_Csmr_ACScroll = 0x235, /* Selector */ + kHIDUsage_Csmr_ACPanLeft = 0x236, /* Selector */ + kHIDUsage_Csmr_ACPanRight = 0x237, /* Selector */ + kHIDUsage_Csmr_ACPan = 0x238, /* Selector */ + kHIDUsage_Csmr_ACNewWindow = 0x239, /* Selector */ + kHIDUsage_Csmr_ACTileHorizontally = 0x23A, /* Selector */ + kHIDUsage_Csmr_ACTileVertically = 0x23B, /* Selector */ + kHIDUsage_Csmr_ACFormat = 0x23C, /* Selector */ + /* 0x23D - 0xFFFF Reserved */ + kHIDUsage_Csmr_Reserved = 0xFFFF, +}; + +/* Digitizer Page (0x0D) */ +/* This section provides detailed descriptions of the usages employed by Digitizer Devices. */ +enum +{ + kHIDUsage_Dig_Digitizer = 0x01, /* Application Collection */ + kHIDUsage_Dig_Pen = 0x02, /* Application Collection */ + kHIDUsage_Dig_LightPen = 0x03, /* Application Collection */ + kHIDUsage_Dig_TouchScreen = 0x04, /* Application Collection */ + kHIDUsage_Dig_TouchPad = 0x05, /* Application Collection */ + kHIDUsage_Dig_WhiteBoard = 0x06, /* Application Collection */ + kHIDUsage_Dig_CoordinateMeasuringMachine = 0x07, /* Application Collection */ + kHIDUsage_Dig_3DDigitizer = 0x08, /* Application Collection */ + kHIDUsage_Dig_StereoPlotter = 0x09, /* Application Collection */ + kHIDUsage_Dig_ArticulatedArm = 0x0A, /* Application Collection */ + kHIDUsage_Dig_Armature = 0x0B, /* Application Collection */ + kHIDUsage_Dig_MultiplePointDigitizer = 0x0C, /* Application Collection */ + kHIDUsage_Dig_FreeSpaceWand = 0x0D, /* Application Collection */ + /* 0x0E - 0x1F Reserved */ + kHIDUsage_Dig_Stylus = 0x20, /* Logical Collection */ + kHIDUsage_Dig_Puck = 0x21, /* Logical Collection */ + kHIDUsage_Dig_Finger = 0x22, /* Logical Collection */ + /* 0x23 - 0x2F Reserved */ + kHIDUsage_Dig_TipPressure = 0x30, /* Dynamic Value */ + kHIDUsage_Dig_BarrelPressure = 0x31, /* Dynamic Value */ + kHIDUsage_Dig_InRange = 0x32, /* Momentary Control */ + kHIDUsage_Dig_Touch = 0x33, /* Momentary Control */ + kHIDUsage_Dig_Untouch = 0x34, /* One-Shot Control */ + kHIDUsage_Dig_Tap = 0x35, /* One-Shot Control */ + kHIDUsage_Dig_Quality = 0x36, /* Dynamic Value */ + kHIDUsage_Dig_DataValid = 0x37, /* Momentary Control */ + kHIDUsage_Dig_TransducerIndex = 0x38, /* Dynamic Value */ + kHIDUsage_Dig_TabletFunctionKeys = 0x39, /* Logical Collection */ + kHIDUsage_Dig_ProgramChangeKeys = 0x3A, /* Logical Collection */ + kHIDUsage_Dig_BatteryStrength = 0x3B, /* Dynamic Value */ + kHIDUsage_Dig_Invert = 0x3C, /* Momentary Control */ + kHIDUsage_Dig_XTilt = 0x3D, /* Dynamic Value */ + kHIDUsage_Dig_YTilt = 0x3E, /* Dynamic Value */ + kHIDUsage_Dig_Azimuth = 0x3F, /* Dynamic Value */ + kHIDUsage_Dig_Altitude = 0x40, /* Dynamic Value */ + kHIDUsage_Dig_Twist = 0x41, /* Dynamic Value */ + kHIDUsage_Dig_TipSwitch = 0x42, /* Momentary Control */ + kHIDUsage_Dig_SecondaryTipSwitch = 0x43, /* Momentary Control */ + kHIDUsage_Dig_BarrelSwitch = 0x44, /* Momentary Control */ + kHIDUsage_Dig_Eraser = 0x45, /* Momentary Control */ + kHIDUsage_Dig_TabletPick = 0x46, /* Momentary Control */ + /* 0x47 - 0xFFFF Reserved */ + kHIDUsage_Dig_Reserved = 0xFFFF, +}; + +/* AlphanumericDisplay Page (0x14) */ +/* The Alphanumeric Display page is intended for use by simple alphanumeric displays that are used on consumer devices. */ +enum +{ + kHIDUsage_AD_AlphanumericDisplay = 0x01, /* Application Collection */ + /* 0x02 - 0x1F Reserved */ + kHIDUsage_AD_DisplayAttributesReport = 0x20, /* Logical Collection */ + kHIDUsage_AD_ASCIICharacterSet = 0x21, /* Static Flag */ + kHIDUsage_AD_DataReadBack = 0x22, /* Static Flag */ + kHIDUsage_AD_FontReadBack = 0x23, /* Static Flag */ + kHIDUsage_AD_DisplayControlReport = 0x24, /* Logical Collection */ + kHIDUsage_AD_ClearDisplay = 0x25, /* Dynamic Flag */ + kHIDUsage_AD_DisplayEnable = 0x26, /* Dynamic Flag */ + kHIDUsage_AD_ScreenSaverDelay = 0x27, /* Static Value */ + kHIDUsage_AD_ScreenSaverEnable = 0x28, /* Dynamic Flag */ + kHIDUsage_AD_VerticalScroll = 0x29, /* Static Flag */ + kHIDUsage_AD_HorizontalScroll = 0x2A, /* Static Flag */ + kHIDUsage_AD_CharacterReport = 0x2B, /* Logical Collection */ + kHIDUsage_AD_DisplayData = 0x2C, /* Dynamic Value */ + kHIDUsage_AD_DisplayStatus = 0x2D, /* Logical Collection */ + kHIDUsage_AD_StatNotReady = 0x2E, /* Selector */ + kHIDUsage_AD_StatReady = 0x2F, /* Selector */ + kHIDUsage_AD_ErrNotaloadablecharacter = 0x30, /* Selector */ + kHIDUsage_AD_ErrFontdatacannotberead = 0x31, /* Selector */ + kHIDUsage_AD_CursorPositionReport = 0x32, /* Logical Collection */ + kHIDUsage_AD_Row = 0x33, /* Dynamic Value */ + kHIDUsage_AD_Column = 0x34, /* Dynamic Value */ + kHIDUsage_AD_Rows = 0x35, /* Static Value */ + kHIDUsage_AD_Columns = 0x36, /* Static Value */ + kHIDUsage_AD_CursorPixelPositioning = 0x37, /* Static Flag */ + kHIDUsage_AD_CursorMode = 0x38, /* Dynamic Flag */ + kHIDUsage_AD_CursorEnable = 0x39, /* Dynamic Flag */ + kHIDUsage_AD_CursorBlink = 0x3A, /* Dynamic Flag */ + kHIDUsage_AD_FontReport = 0x3B, /* Logical Collection */ + kHIDUsage_AD_FontData = 0x3C, /* Buffered Byte */ + kHIDUsage_AD_CharacterWidth = 0x3D, /* Static Value */ + kHIDUsage_AD_CharacterHeight = 0x3E, /* Static Value */ + kHIDUsage_AD_CharacterSpacingHorizontal = 0x3F, /* Static Value */ + kHIDUsage_AD_CharacterSpacingVertical = 0x40, /* Static Value */ + kHIDUsage_AD_UnicodeCharacterSet = 0x41, /* Static Flag */ + /* 0x42 - 0xFFFF Reserved */ + kHIDUsage_AD_Reserved = 0xFFFF, +}; + +#endif /* _IOHIDUSAGETABLES_H */ diff --git a/AppRunMan/server/IPhoneHertbeat.h b/AppRunMan/server/IPhoneHertbeat.h new file mode 100755 index 0000000..e7a30c6 --- /dev/null +++ b/AppRunMan/server/IPhoneHertbeat.h @@ -0,0 +1,26 @@ +// +// IPthoneHertbeat.h +// NotNil +// +// Created by mac on 2024/6/13. +// +#import + +@interface IPhoneHertbeat : NSObject + + +@property (strong, nonatomic) NSString *name; +@property (strong, nonatomic) NSString *deviceId; +@property (strong, nonatomic) NSString *ip; +@property (strong, nonatomic) NSString *appId; +@property (strong, nonatomic) NSArray *apps; +@property (strong, nonatomic) NSString *message; +@property (strong, nonatomic) NSString *status; +@property (strong, nonatomic) NSString *diskSize; +@property (strong, nonatomic) NSString *remoteIp; + +- (void)start; + ++(instancetype)sharedInstance; + +@end diff --git a/AppRunMan/server/IPhoneHertbeat.m b/AppRunMan/server/IPhoneHertbeat.m new file mode 100755 index 0000000..f9b3fb5 --- /dev/null +++ b/AppRunMan/server/IPhoneHertbeat.m @@ -0,0 +1,346 @@ +// +// IPhoneHertbeat.m +// NotNil +// +// Created by mac on 2024/6/13. +// +#import "IPhoneHertbeat.h" + +#import + +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" +#import "XSHelper.h" +#import "XSHackIos.h" +#import "XSHttpHelper.h" +#import "XSIosTouch.h" +#import "MyAdServer.h" +#import "MyAdTask2.h" + +@interface IPhoneHertbeat () +{ +@private + XSPhoneConfig *iphone; + NSTimeInterval _lastCheckTaskTime; + XSHttpHelper *http; + NSDate *lastStop; + dispatch_source_t _timer; // 替换 NSTimer + dispatch_queue_t _workQueue; +} + +@property (nonatomic, assign) NSTimeInterval lastTouchTime; +@property (nonatomic, assign) BOOL isProcessingTouch; +@property (nonatomic, strong) dispatch_queue_t touchQueue; +@property (nonatomic, assign) NSTimeInterval lastCheckTaskTime; +@property (nonatomic, strong) dispatch_source_t touchTimer; + +@end + +@implementation IPhoneHertbeat + ++(instancetype)sharedInstance +{ + static IPhoneHertbeat* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[IPhoneHertbeat alloc] init]; + }); + return _sharedInstance; +} + +-(instancetype)init { + if (self = [super init]) { + self->iphone = [XSPhoneConfig sharedInstance]; + // self.apps = [self getApps]; + self->_lastCheckTaskTime = [XSHelper getCurTime]; + self->http = [[XSHttpHelper alloc] init]; + self.status = @"已停止"; + self->lastStop = [NSDate date]; + return self; + } + return nil; +} + + +- (void)stop { + if (_timer) { + dispatch_source_cancel(_timer); + _timer = nil; + } +} + +- (void)dealloc { + [self stop]; + [self cancelCurrentTask]; +} + + + +- (void) start { + if (_timer) return; + + _workQueue = dispatch_queue_create("com.iphone.heartbeat.queue", DISPATCH_QUEUE_SERIAL); + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue); + dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 5 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC); + + __weak typeof(self) weakSelf = self; + dispatch_source_set_event_handler(_timer, ^{ + @autoreleasepool { + [weakSelf ping]; + } + }); + + dispatch_resume(_timer); +} + +- (void) checkxxx { + NSDate *last = [[XSPhoneConfig sharedInstance] GetLastOverTime]; + NSDate *date2 = [NSDate date]; + // 获取相差的秒数 + NSTimeInterval seconds = [date2 timeIntervalSinceDate:last]; + + if (seconds > 5 * 24 * 60 * 60) { + NSDate *currentDate = [NSDate date]; + NSDate *fiveDaysLater = [currentDate dateByAddingTimeInterval:-4 * 24 * 60 * 60 - 3600]; + [[XSPhoneConfig sharedInstance] SetLastOverTime:fiveDaysLater]; + // XSReboot(); + } +} + + +- (void) ping { + @try { + if (!self->iphone || !self->http) return; + + NSString *server = self->iphone.ServerURL; + if (!server.length) { + NSLog(@"Invalid server URL"); + return; + } + + NSString *url = [NSString stringWithFormat:@"%@/ios/top_selection/heartbeat", server]; + + /** + { + "deviceId": "string", + "ip": "string", + "appId": "string", + "apps": [ + "string" + ], + "name": "string", + "message": "string", + "status": "string", + "life": true + } + */ + //self.status = [[XSConsole sharedInstance] status]; + //self.appId = [[XSJsGlobalContext sharedInstance] get:@"ad_appid"]; + @synchronized (self) { + if ([self.status isEqualToString:@"运行中"]) { + self->lastStop = [NSDate date]; + } + + // 检查自动重启 + NSDate *curRunTime = [NSDate date]; + NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastStop]; + if (elapsed > 60 * 10 && !myadTaskManualStop) { + self->lastStop = [NSDate date]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[MyAdTask2Mangger sharedInstance] start]; + }); + } + } + + self.name = self->iphone.IPhoneName; + self.deviceId = self->iphone.DeviceId; + self.ip = [[XSPhoneInfo sharedInstance] IPAddress]; + self.remoteIp = [[XSPhoneInfo sharedInstance] remoteIp]; + self.diskSize = [[XSPhoneInfo sharedInstance] IPhoneStatus]; + self.message = @"250612"; + // 构建请求数据 + NSDictionary *heartbeatData = [self constructHeartbeatData]; + if (!heartbeatData) { + NSLog(@"Failed to construct heartbeat data"); + return; + } + + /* + pushInfo(1, + [XSHelper dic2Json:dic], + ^(NSString *data) { + if (data) { + NSLog(@"XS- log: %@", data); + [[XSPhoneConfig sharedInstance] SetLastOverTime: [NSDate date]]; + } else { + NSLog(@"XS- heart beat error"); + //[self checkxxx]; + } + },^(NSError *err) { + NSLog(@"XS- %@", err); + //[self checkxxx]; + }); + */ + + // 发送请求 + [self sendHeartbeat:heartbeatData toURL:url]; + // 检查任务 + // [self checkAndPerformTasks]; + + } @catch (NSException *exception) { + NSLog(@"XS- app run man ping error: %@", exception); + } @finally { + NSLog(@"XS- ping end"); + } + +} + +- (void)sendHeartbeat:(NSDictionary *)data toURL:(NSString *)url { + [self->http doPOST:url json:[XSHelper dic2Json:data] withCallback:^(NSData *responseData) { + if (responseData) { + NSLog(@"Heartbeat success: %@", [XSHelper data2str:responseData]); + } else { + NSLog(@"Empty heartbeat response"); + } + } withError:^(NSError *err) { + NSLog(@"Heartbeat error: %@", err); + }]; +} + +- (NSDictionary *)constructHeartbeatData { + @try { + return @{ + @"deviceId": self.deviceId ?: @"", + @"ip": self.ip ?: @"", + @"appId": self.appId ?: @"", + @"apps": self.apps ?: @[], + @"name": self.name ?: @"", + @"message": self.message ?: @"", + @"status": self.status ?: @"", + @"disk": self.diskSize ?: @"", + @"remoteIp": self.remoteIp ?: @"" + }; + } @catch (NSException *exception) { + NSLog(@"Error constructing heartbeat data: %@", exception); + return nil; + } +} + +- (void)checkAndPerformTasks { + NSTimeInterval currentTime = [XSHelper getCurTime]; + + // 检查任务执行间隔 + if (currentTime - self.lastCheckTaskTime <= 240) { + return; + } + + // 更新最后检查时间 + self.lastCheckTaskTime = currentTime; + __weak typeof(self) weakSelf = self; + // 使用专门的触摸队列 + dispatch_async(self.touchQueue, ^{ + @try { + [weakSelf safePerformTouchEvents]; + } @catch (NSException *exception) { + NSLog(@"Error performing touch events: %@", exception); + } + }); +} + +- (void)safePerformTouchEvents { + // 检查触摸状态 + if (self.isProcessingTouch) { + NSLog(@"Already processing touch events"); + return; + } + + // 获取前台应用 + NSString *appId = XSFrontMostAppId(); + if (!appId.length) { + NSLog(@"No foreground app detected"); + return; + } + + // 获取触摸实例 + XSIosTouch *touch = [XSIosTouch sharedInstance]; + if (!touch) { + NSLog(@"Touch instance not available"); + return; + } + + // 标记开始处理触摸 + self.isProcessingTouch = YES; + __weak typeof(self) weakSelf = self; + // 执行第一次点击 + dispatch_async(dispatch_get_main_queue(), ^{ + @try { + // 检查最小触摸间隔 + NSTimeInterval currentTime = [XSHelper getCurTime]; + if (currentTime - weakSelf.lastTouchTime < 0.05) { // 50ms最小间隔 + return; + } + + weakSelf.lastTouchTime = currentTime; + [touch Tap:1 x:244 y:766]; + + // 延迟执行第二次点击 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + @try { + // 再次检查前台应用 + NSString *currentAppId = XSFrontMostAppId(); + if (!currentAppId.length) { + NSLog(@"App not in foreground for second tap"); + return; + } + + // 检查最小触摸间隔 + NSTimeInterval newCurrentTime = [XSHelper getCurTime]; + if (newCurrentTime - weakSelf.lastTouchTime < 0.05) { + return; + } + + weakSelf.lastTouchTime = newCurrentTime; + [touch Tap:1 x:382 y:766]; + + } @catch (NSException *exception) { + NSLog(@"Error in second tap: %@", exception); + } @finally { + // 确保处理状态被重置 + weakSelf.isProcessingTouch = NO; + } + }); + + } @catch (NSException *exception) { + NSLog(@"Error in first tap: %@", exception); + weakSelf.isProcessingTouch = NO; + } + }); +} + +// 添加清理方法 +- (void)cleanup { + self.isProcessingTouch = NO; + self.lastTouchTime = 0; +} + +// 添加取消当前任务的方法 +- (void)cancelCurrentTask { + if (self.touchTimer) { + dispatch_source_cancel(self.touchTimer); + self.touchTimer = nil; + } + [self cleanup]; +} + +// 添加重置方法 +- (void)reset { + [self cancelCurrentTask]; + [self cleanup]; +} + + + +@end + + diff --git a/AppRunMan/server/IosSystemCmd.h b/AppRunMan/server/IosSystemCmd.h new file mode 100644 index 0000000..cf860bf --- /dev/null +++ b/AppRunMan/server/IosSystemCmd.h @@ -0,0 +1,15 @@ +// +// IosSystemCmd.h +// nochange +// +// Created by mac on 2024/8/27. +// + +#import + +@interface IosSystemCmd : NSObject + + ++ (instancetype)sharedInstance; +- (void) start; +@end diff --git a/AppRunMan/server/IosSystemCmd.m b/AppRunMan/server/IosSystemCmd.m new file mode 100644 index 0000000..bb8dfdb --- /dev/null +++ b/AppRunMan/server/IosSystemCmd.m @@ -0,0 +1,363 @@ +// +// IosSystemCmd.m +// nochange +// +// Created by mac on 2024/8/27. +// + + +#import "IosSystemCmd.h" +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" +#import "XSHelper.h" +#import "XSHackIos.h" +#import "MyScriptTask.h" +#import "MyEventBus.h" +#import "XSIosTouch.h" +#import "XSHttpHelper.h" +#import "MyAdTask2.h" +#import "MyAdServer.h" + +#define CMD_RES @"/ios/top_selection/system_cmd_response" +#define CMD @"/ios/top_selection/system_cmds" + +@implementation IosSystemCmd +{ +@private + XSPhoneConfig *_config; + XSHttpHelper *http; + dispatch_source_t _timer; // 替换 NSTimer + dispatch_queue_t _workQueue; +} + ++ (instancetype)sharedInstance { + static IosSystemCmd *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self->_config = [XSPhoneConfig sharedInstance]; + self->http = [[XSHttpHelper alloc] init]; + } + return self; +} + +- (NSString *)cmdUrl { + return [NSString stringWithFormat:@"%@%@", _config.ServerURL, CMD]; +} +- (NSString *)cmdResUrl { + return [NSString stringWithFormat:@"%@%@", _config.ServerURL, CMD_RES]; +} + +- (void) start { + if (_timer) return; + _workQueue = dispatch_queue_create("com.iossystemcmd.queue", DISPATCH_QUEUE_SERIAL); + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue); + dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 2 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC); + + __weak typeof(self) weakSelf = self; + dispatch_source_set_event_handler(_timer, ^{ + @autoreleasepool { + [weakSelf runTask]; + } + }); + + dispatch_resume(_timer); +} + +- (void) runTask { + NSLog(@"XC- run system task..."); + NSString *deviceId = [_config DeviceId]; + NSString *ip = [[XSPhoneInfo sharedInstance] IPAddress]; + NSString *name = [_config IPhoneName]; + NSDictionary *dic = @{ + @"deviceId": deviceId, + @"ip": ip, + @"iphoneId": name + }; + /* + pushInfo(2, + [XSHelper dic2Json:dic], + ^(NSString *data) { + if(data){ + NSDictionary *dic = [XSHelper json2Dictionary:data]; + [self executeTask:dic]; + } else { + NSLog(@"XC- get system cmd error"); + } + }, ^(NSError *err) { + NSLog(@"XC- get system cmd error:%@",err); + }); + */ + __weak typeof(self) weakSelf = self; + [self->http doPOST:[self cmdUrl] json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) { + if (data) { + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + if (dic && [dic objectForKey:@"data"]) { + id data = dic[@"data"]; + if (data && data != [NSNull null]) { + [weakSelf executeTask:data]; + } + } + } else { + NSLog(@"XC- get system cmd error"); + } + + } withError:^(NSError *err) { + NSLog(@"XC- get system cmd error:%@",err); + }]; + +} + +- (void) executeTask: (NSDictionary*)dic { + if ([dic objectForKey:@"cmd"]) { + NSString *cmd = dic[@"cmd"]; + NSString *taskId = dic[@"taskId"]; + if ([cmd isEqual:@"EDIT_NAME"]) { + [self executeEditName:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"UPLOAD_APPS"]) { + [self executeUploadApps:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"START"]) { + [self executeStart:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"STOP"]) { + [self executeStop:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"SCREENSHOT"]) { + [self executeScreenshot:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"UNLOCK"]) { + [self executeUnlock:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"RESTART_SYSTEM"]) { + [self executeRestart:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"RESTART"]) { + [self executeReboot:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"TOUCH"]) { + [self executeTouch:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"KEY"]) { + [self executeKey:taskId data:dic[@"cmdData"]]; + return; + } + if ([cmd isEqual:@"UPDATE_KEY"]) { + [self executeUpdateKey:taskId data:dic[@"cmdData"]]; + return; + } + } +} + +- (void) putTask: (NSString*)taskId error: (NSString*)error data:(NSString*)data { + NSDictionary *dic = @{ + @"taskId": taskId, + @"data": data, + @"error": error + }; + /* + pushInfo(3, [XSHelper dic2Json:dic], ^(NSString *data) { + if(data) { + NSLog(@"XS- %@", data); + } + }, ^(NSError *err) { + NSLog(@"XS- %@", err); + }); + */ + + [self->http doPOST:[self cmdResUrl] json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) { + if (data) { + NSLog(@"XS- %@", [XSHelper data2str:data]); + } + } withError:^(NSError *err) { + NSLog(@"XS- %@", err); + }]; + +} + +- (void) executeEditName: (NSString*)taskId data:(NSString*)data { + if (data) { + BOOL setSs = [_config SetIPhoneName:data]; + [[MyEventBus sharedInstance] postEvent:@"UpdateName" withObject:data]; + NSString *r = [NSString stringWithFormat:@"set:%@", setSs == YES ?@ "YES": @"NO"]; + [self putTask:taskId error:r data:data]; + } +} + +- (void) executeUploadApps: (NSString*)taskId data:(NSString*)data { + NSArray *apps = [self getMyApps]; + NSData *appsData = [XSHelper obj2JsonData:apps]; + if (appsData) { + [self putTask:taskId error:@"" data:[XSHelper data2str:appsData]]; + } else { + NSLog(@"upload apps error"); + } +} + +- (void) executeStart: (NSString*)taskId data:(NSString*)data { + //[[XSConsole sharedInstance] restart]; + [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)]; + [[MyAdTask2Mangger sharedInstance] start]; + [self putTask:taskId error:@"" data:data]; +} + +- (void) executeStop: (NSString*)taskId data:(NSString*)data { + //[[XSConsole sharedInstance] stop]; + [[MyAdTask2Mangger sharedInstance] stop]; + [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)]; + [self putTask:taskId error:@"" data:data]; +} + +- (void) executeScreenshot:(NSString*)taskId data:(NSString*)data { + @try { + dispatch_async(dispatch_get_main_queue(), ^{ + NSLog(@"executeScreenshot;%@;%@",taskId, data); + UIImage *img = XSCcaptureScreen2(); + NSString *base64 = [XSHelper base64StringFromJpgImage:img]; + if (base64) { + [self putTask:taskId error:@"" data:base64]; + } else { + [self putTask:taskId error:@"截屏失败" data:data]; + } + }); + } @catch (NSException *exception) { + [self putTask:taskId error:@"截屏失败" data:data]; + } +} + +- (void) executeUnlock: (NSString*) taskId data:(NSString*)data { + @try { + + //[[[XSJsApi alloc] init] unlock]; + dispatch_async(dispatch_get_main_queue(), ^{ + XSRemoteUnlock(); + }); + + } @catch (NSException *exception) { + + } +} +- (void) executeRestart: (NSString*) taskId data:(NSString*)data { + @try { + dispatch_async(dispatch_get_main_queue(), ^{ + XSKillApp(@"SpringBoard"); + }); + } @catch (NSException *exception) { + + } +} +- (void) executeReboot: (NSString*) taskId data:(NSString*)data { + @try { + dispatch_async(dispatch_get_main_queue(), ^{ + XSReboot(); + }); + } @catch (NSException *exception) { + + } +} + +- (void) executeTouch: (NSString*) taskId data:(NSString*)data { + @try { + dispatch_async(dispatch_get_main_queue(), ^{ + if(data && ![data isEqual:[NSNull null]]) { + NSDictionary *dic = [XSHelper json2Dictionary:data]; + if (dic && ![dic isEqual:[NSNull null]]) { + NSNumber *x = dic[@"x"]; + NSNumber *y = dic[@"y"]; + float nx = [x floatValue]; + float ny = [y floatValue]; + //[[[XSJsApi alloc] init] tap:10 x:nx y:ny]; + [[XSIosTouch sharedInstance] Tap:10 x:nx y:ny]; + } + } + }); + } @catch (NSException *exception) { + + } +} + +- (void) executeUpdateKey: (NSString*) taskId data:(NSString*)data { + [[XSPhoneConfig sharedInstance] SetApiKey:data]; +} + +- (void) executeKey: (NSString*) taskId data:(NSString*)data { + @try { + dispatch_async(dispatch_get_main_queue(), ^{ + if(data && ![data isEqual:[NSNull null]]) { + NSDictionary *dic = [XSHelper json2Dictionary:data]; + if (dic && ![dic isEqual:[NSNull null]]) { + NSNumber *k = dic[@"key"]; + long key = [k longValue]; + XSIosTouch *touch = [[XSIosTouch alloc] init]; + [touch KeyDown:key]; + usleep(5000); + [touch KeyDown:key]; + } + } + }); + } @catch (NSException *exception) { + + } +} + + +- (NSArray*) getMyApps { + NSArray *apps = XSGetApps(); + NSMutableArray *resApps = [[NSMutableArray alloc] init]; + [apps enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (obj) { + NSDictionary *oldDic = obj; + NSString *appId = oldDic[@"bundleId"]; + if ([appId hasPrefix:@"com.apple."]) { + + } else { + NSString *icon = @""; + if ([oldDic objectForKey:@"icon"]) { + if (oldDic[@"icon"] && oldDic[@"icon"] != [NSNull null]) { + icon = [XSHelper base64StringFromJpgImage:oldDic[@"icon"]]; + } + } + NSDictionary *dic = @{ + @"bundleId": oldDic[@"bundleId"], + @"name":oldDic[@"name"], + @"containerPath": oldDic[@"containerPath"], + @"version": oldDic[@"version"], + @"shortVersion": oldDic[@"shortVersion"], + @"icon": icon, + }; + [resApps addObject:dic]; + } + } + }]; + return resApps; +} + +- (void)stop { + if (_timer) { + dispatch_source_cancel(_timer); + _timer = nil; + } +} + +- (void)dealloc { + [self stop]; +} + +@end diff --git a/AppRunMan/server/MyAdServer.h b/AppRunMan/server/MyAdServer.h new file mode 100644 index 0000000..ae44a32 --- /dev/null +++ b/AppRunMan/server/MyAdServer.h @@ -0,0 +1,49 @@ +// +// MyAdServer.h +// nochange +// +// Created by mac on 2024/7/26. +// + +#ifndef MyAdServer_h +#define MyAdServer_h + +#import +#import "XSHttpHelper.h" + +typedef struct { + NSNumber *loads; + NSNumber *adTouchBeforeMs; + NSNumber *adTouchAfterMs; + NSNumber *adTime; + NSNumber *adTimeout; + NSNumber *touchRate; +} AdLoadInfo; + +typedef void (^ChangeDataSaveCallback)(NSDictionary* dic); +typedef void (^AdLoadInfoCallback)(AdLoadInfo* info); +typedef void (^LowEcpmCallback)(NSNumber* ecpm); + +typedef struct { + NSString *taskId; + NSString *title; + NSString *message; + NSString *idfa; + NSString *appid; + NSString *adid; + NSString *iphoneId; + NSString *ipAddr; + NSNumber *ecpm; + int level; +} AdTaskLogData; +void getChangeInfo(NSString* idfa, ChangeDataSaveCallback callback, error_callback errorCallback); +BOOL saveChangeDataFile (NSDictionary * data); +void pushAdTaskLog(AdTaskLogData *data); +void pushInfo(int type, NSString *data, rt_str_callback callback,error_callback errorCallback); +AdLoadInfo getAdLoadInfo(NSDictionary *request); +void pushIphoneLog(NSString *data); +void registerSignalHandler(void); +void saveAdTaskLog(NSDictionary *dic); +void getLowEcpm(LowEcpmCallback callback); +BOOL needAdContinue(NSString *appid, NSString *idfa, NSNumber *maxEcpm); +#endif /* MyAdServer_h */ diff --git a/AppRunMan/server/MyAdServer.m b/AppRunMan/server/MyAdServer.m new file mode 100644 index 0000000..b4b6a8c --- /dev/null +++ b/AppRunMan/server/MyAdServer.m @@ -0,0 +1,379 @@ +// +// MyAdServer.m +// nochange +// +// Created by mac on 2024/7/26. +// + +#import +#import +#import + +#import "XSHelper.h" +#import "MyAdServer.h" +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" + + + +void pushAdTaskLog(AdTaskLogData *data) { + NSDictionary *dic = @{ + @"taskId": data->taskId, + @"title": data->title, + @"message": data->message, + @"idfa": data->idfa, + @"appid": data->appid, + @"adid": data->adid, + @"level": @(data->level), + @"ecpm": data->ecpm ? : @0.0, + @"iphoneId": data->iphoneId, + @"ipAddr": data->ipAddr + }; + saveAdTaskLog(dic); +} + +void saveAdTaskLog(NSDictionary *dic) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [config GetFullServerURL:@"ios/top_selection/push_ad_task_log"]; + NSString *json = [XSHelper dic2Json:dic]; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doPOST:url json:json withCallback:^(NSData *res) { + NSLog(@"-ad log- push:\n %@", [XSHelper data2str:res]); + } withError:^(NSError *err) { + NSLog(@"XS- %@", err); + }]; +} + +void getLowEcpm(LowEcpmCallback callback) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [NSString stringWithFormat:@"ios/top_selection/low_ecpm?iphoneId=%@", config.IPhoneName]; + NSLog(@"XS- getLowEcpm url %@", url); + NSString *fullurl = [config GetFullServerURL:url]; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doGET:fullurl withCallback:^(NSData *data) { + if(data && ![data isEqual:[NSNull null]]) { + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + NSLog(@"XS- getLowEcpm data %@", dic); + NSNumber *ecpm = dic[@"data"]; + if (ecpm) { + callback(ecpm); + } else { + callback(ecpm); + } + } else { + callback(@(0.0001)); + } + } withError:^(NSError *err) { + callback(@(0.0001)); + }]; + +} + +BOOL needAdContinue(NSString *appid, NSString *idfa, NSNumber *maxEcpm) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *fullurl = [config GetFullServerURL: @"ios/top_selection/get_need_continue"]; + NSDictionary *postData = @{ + @"id": config.IPhoneName, + @"appid": appid, + @"idfa": idfa, + @"maxEcpm": maxEcpm + }; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + NSData *data = [http doPOST:fullurl json:[XSHelper dic2Json:postData]]; + if(data == nil || [data isEqual:[NSNull null]]) { + return NO; + } + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + NSLog(@"XS- needAdContinue data %@", dic); + return [dic[@"data"] isEqual:@(true)]; +} + + +void getChangeInfo(NSString *idfa, ChangeDataSaveCallback callback, error_callback errorCallback) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [config GetFullServerURL:[NSString stringWithFormat:@"ios/top_selection/get_change_data?id=%@&idfa=%@", [config IPhoneName], idfa ?: @""]]; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doGET:url withCallback:^(NSData *jsonData) { + NSDictionary *data = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; + if (data && [data objectForKey:@"data"]) { + NSDictionary *_data = data[@"data"]; + if(_data && ![_data isEqual:[NSNull null]]) { + callback(_data); + } + } else { + if(errorCallback) { + errorCallback(nil); + } + + } + } withError:^(NSError *err) { + NSLog(@"XS- log- get data: %@", err); + if(errorCallback) { + errorCallback(err); + } + }]; + +} + +void _newgetChangeInfo(NSString *idfa, ChangeDataSaveCallback callback, error_callback errorCallback) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [config GetFullServerURL:[NSString stringWithFormat:@"ios/top_selection/change_data?id=%@&idfa=%@", [config IPhoneName], idfa ?: @""]]; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doGET:url withCallback:^(NSData *jsonData) { + NSDictionary *data = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; + if (data && [data objectForKey:@"data"]) { + NSString *aesData = data[@"data"]; + NSString *decData = @""; + if(aesData && ![aesData isEqual:[NSNull null]] && ![aesData isEqual:@""]) { + decData = [aesData aesDecrypt:AES_KEY iv:AES_IV]; + } + // NSString *decData = [aesData aesDecrypt:AES_KEY iv:AES_IV]; + NSLog(@"XS- changeData: %@", decData); + NSDictionary *dt = [XSHelper json2Dictionary:decData]; + callback(dt); + } else { + if(errorCallback) { + errorCallback(nil); + } + + } + } withError:^(NSError *err) { + NSLog(@"XS- log- get data: %@", err); + if(errorCallback) { + errorCallback(err); + } + }]; + +} + +BOOL saveChangeDataFile(NSDictionary *data) { + if (!data || ![data isKindOfClass:[NSDictionary class]]) { + NSLog(@"Invalid data input"); + return NO; + } + + @try { + NSString *bundleId = @"org.xyzshell.NotNil"; + NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; + + // 使用同步锁保证线程安全 + @synchronized(NSFileManager.defaultManager) { + NSMutableDictionary *tempDic = [NSMutableDictionary new]; + + // 安全地遍历字典 + [data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if (![key isKindOfClass:[NSString class]]) return; + + if (obj == [NSNull null]) { + tempDic[key] = nil; + } else if ([obj isKindOfClass:[NSDictionary class]]) { + NSMutableDictionary *newDic = [NSMutableDictionary new]; + [(NSDictionary *)obj enumerateKeysAndObjectsUsingBlock:^(id key1, id obj1, BOOL *stop1) { + if (![key1 isKindOfClass:[NSString class]]) return; + newDic[key1] = (obj1 == [NSNull null]) ? nil : obj1; + }]; + tempDic[key] = [newDic copy]; + } else { + tempDic[key] = obj; + } + }]; + + // 创建目录 + NSError *error; + NSString *dirPath = [plistPath stringByDeletingLastPathComponent]; + if (![NSFileManager.defaultManager fileExistsAtPath:dirPath]) { + if (![NSFileManager.defaultManager createDirectoryAtPath:dirPath + withIntermediateDirectories:YES + attributes:nil + error:&error]) { + NSLog(@"Failed to create directory: %@", error); + return NO; + } + } + + // 写入文件 + BOOL y = [tempDic writeToFile:plistPath atomically:YES]; + NSLog(@"XS- save change file: %@", @(y)); + return y; + } + } @catch (NSException *exception) { + NSLog(@"Error saving change data: %@", exception); + return NO; + } +} + +AdLoadInfo getAdLoadInfo(NSDictionary *request) { + AdLoadInfo info = {0}; // 初始化所有字段为0 + + if (!request || ![request isKindOfClass:[NSDictionary class]]) { + NSLog(@"Invalid request"); + return info; + } + + @try { + NSString *apiUrl = [[XSPhoneConfig sharedInstance] GetFullServerURL:@"ios/top_selection/ad_can_show"]; + if (!apiUrl.length) { + NSLog(@"Invalid API URL"); + return info; + } + + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + NSData *data = [http doPOST:apiUrl json:[XSHelper dic2Json:request]]; + + if (!data) { + NSLog(@"No response data"); + return info; + } + + NSError *jsonError; + NSDictionary *res = [NSJSONSerialization JSONObjectWithData:data + options:0 + error:&jsonError]; + + if (jsonError || ![res isKindOfClass:[NSDictionary class]]) { + NSLog(@"JSON parsing error: %@", jsonError); + return info; + } + + NSDictionary *resData = res[@"data"]; + if (![resData isKindOfClass:[NSDictionary class]]) { + NSLog(@"Invalid response data format"); + return info; + } + + // 安全地获取值 + info.loads = [resData[@"loads"] isKindOfClass:[NSNumber class]] ? resData[@"loads"] : @0; + info.adTime = [resData[@"adTime"] isKindOfClass:[NSNumber class]] ? resData[@"adTime"] : @0; + info.adTimeout = [resData[@"adTimeout"] isKindOfClass:[NSNumber class]] ? resData[@"adTimeout"] : @0; + info.adTouchAfterMs = [resData[@"adTouchAfterMs"] isKindOfClass:[NSNumber class]] ? resData[@"adTouchAfterMs"] : @0; + info.adTouchBeforeMs = [resData[@"adTouchBeforeMs"] isKindOfClass:[NSNumber class]] ? resData[@"adTouchBeforeMs"] : @0; + info.touchRate = [resData[@"touchRate"] isKindOfClass:[NSNumber class]] ? resData[@"touchRate"] : @0; + + } @catch (NSException *exception) { + NSLog(@"Error getting ad load info: %@", exception); + } + + return info; +} + +void pushInfo(int type, NSString *data, rt_str_callback callback,error_callback errorCallback) { + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [config GetMainServerURL:@"ios/top_selection/_putinfo"]; + NSString *aesData = [data aesEncrypt:AES_KEY iv:AES_IV]; + NSDictionary *dic = @{ + @"data": aesData, + @"type": @(type) + }; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doPOST:url json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) { + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + if (dic && dic[@"data"]) { + NSString *strData = dic[@"data"]; + NSLog(@"XS- aes data:%@", strData); + NSString *json = @""; + if(strData && ![strData isEqual:[NSNull null]]) { + json = [strData aesDecrypt:AES_KEY iv:AES_IV]; + } + callback(json); + } + } withError:errorCallback]; +} + +void pushIphoneLog(NSString *data) { + /* + logs.ipAddr = log.ipAddr; + logs.created = log.created; + logs.data = log.decryptData(); + logs.type = log.type; + logs.pkgName = log.pkgName; + logs.version = log.version; + */ + NSString *aesData = [data aesEncrypt:AES_KEY iv:AES_IV]; + NSString *ipAddr = [[XSPhoneInfo sharedInstance] IPAddress]; + NSString *pkgName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; + NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + NSDictionary *dic = @{ + @"ipAddr": ipAddr, + @"data": aesData, + @"type": @(2), + @"pkgName": pkgName, + @"version": version + }; + + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *url = [config GetMainServerURL:@"ios/top_selection/save_iphone_logs"]; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doPOST:url json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) { + NSString *log = [XSHelper data2str:data]; + NSLog(@"pushIphoneLog %@", log); + } withError:^(NSError *err) { + NSLog(@"pushIphoneLog %@", err); + }]; +} + +void logMessage(NSString *message) { + NSString *documentsDirectory = @"/var/logs/"; + NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:@"app_log.txt"]; + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *timestamp = [dateFormatter stringFromDate:[NSDate date]]; + + NSString *logEntry = [NSString stringWithFormat:@"%@: %@\n", timestamp, message]; + + if (![[NSFileManager defaultManager] fileExistsAtPath:logFilePath]) { + [logEntry writeToFile:logFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; + } else { + NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath]; + [fileHandle seekToEndOfFile]; + [fileHandle writeData:[logEntry dataUsingEncoding:NSUTF8StringEncoding]]; + [fileHandle closeFile]; + } +} + + +void uncaughtExceptionHandler(NSException *exception) { + NSArray *callStack = [exception callStackSymbols]; + NSString *reason = [exception reason]; + NSString *name = [exception name]; + + NSString *urlString = [NSString stringWithFormat:@"crash://%@", name]; + NSString *userInfo = [NSString stringWithFormat:@"%@\nreason:\n%@\ncallStackSymbols:\n%@", + urlString, reason, [callStack componentsJoinedByString:@"\n"]]; + + NSLog(@"Crash: %@", userInfo); + logMessage(userInfo); + // 这里你可以将崩溃信息保存到文件或发送到服务器 + pushIphoneLog(userInfo); +} + +void signalHandler(int signal) { + NSMutableString *crashLog = [NSMutableString string]; + [crashLog appendFormat:@"Signal %d was raised.\n", signal]; + + void* callstack[128]; + int frames = backtrace(callstack, 128); + char **strs = backtrace_symbols(callstack, frames); + + for (int i = 0; i < frames; ++i) { + [crashLog appendFormat:@"%s\n", strs[i]]; + } + + free(strs); + + NSLog(@"Crash: %@", crashLog); + logMessage(crashLog); + // 这里你可以将崩溃信息保存到文件或发送到服务器 + + pushIphoneLog(crashLog); +} + +void registerSignalHandler(void) { + signal(SIGABRT, signalHandler); + signal(SIGILL, signalHandler); + signal(SIGSEGV, signalHandler); + signal(SIGFPE, signalHandler); + signal(SIGBUS, signalHandler); + signal(SIGPIPE, signalHandler); + NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); +} diff --git a/AppRunMan/server/MyAdTask2.h b/AppRunMan/server/MyAdTask2.h new file mode 100644 index 0000000..a4d08c0 --- /dev/null +++ b/AppRunMan/server/MyAdTask2.h @@ -0,0 +1,29 @@ +// +// MyAdTask2.h +// nochange +// +// Created by mac on 2024/11/6. +// + +#ifndef MyAdTask2_h +#define MyAdTask2_h + +extern BOOL myadTaskManualStop; + +typedef void (^OnEndCallback)(void); + +typedef void (^OnIpGetCallback)(NSString *ip, NSString *code); + +@interface MyAdTask2Mangger : NSObject ++(instancetype)sharedInstance; + +@property (nonatomic, strong) dispatch_queue_t manQueue; + +- (int) onShow: (NSDictionary *)dic; +- (BOOL) onEnd: (NSDictionary *)dic; +- (void) start; +- (void) stop; +- (NSString *)toggle; +@end + +#endif /* MyAdTask2_h */ diff --git a/AppRunMan/server/MyAdTask2.m b/AppRunMan/server/MyAdTask2.m new file mode 100644 index 0000000..3312edf --- /dev/null +++ b/AppRunMan/server/MyAdTask2.m @@ -0,0 +1,596 @@ +// +// MyAdTask2.m +// nochange +// +// Created by mac on 2024/11/6. +// + +#import +#import "IPhoneHertbeat.h" +#import "XSHackIos.h" +#import "XSIosTouch.h" +#import "XSHelper.h" +#import "XSPhoneInfo.h" +#import "XSPhoneConfig.h" +#import "MyAdServer.h" +#import "MyAdTask2.h" +#import "MyEventBus.h" + + +BOOL myadTaskManualStop = NO; + + +@interface MyAdTask2Mangger() +{ +@private + BOOL running; + // NSTimer *timer; + dispatch_source_t _timer; // 使用GCD timer替代NSTimer + NSDate *lastRun; + NSDate *lastGetCountry; + NSString *_lastIdfa; + NSString *taskId; + NSString *taskAppId; + int workType; + int screen_w; + int screen_h; + int adAfter; + NSString *linkId; + NSString *dataId; + NSString *remoteIp; + NSString *country; +} + +@end + +@implementation MyAdTask2Mangger + ++(instancetype)sharedInstance { + static MyAdTask2Mangger* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[MyAdTask2Mangger alloc] init]; + }); + return _sharedInstance; +} +-(instancetype)init { + if (self = [super init]) { + self->running = NO; + self->_lastIdfa = @""; + self.manQueue = dispatch_queue_create("com.xyzshell.myadtask", DISPATCH_QUEUE_SERIAL); + CGFloat screen_scale = [[UIScreen mainScreen] scale]; + CGFloat device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale; + CGFloat device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale; + self->screen_w = device_screen_width; + self->screen_h = device_screen_height; + self->adAfter = 1000; + return self; + } + return nil; +} + +- (int) onShow: (NSDictionary *)dic { + if(dic == nil || [dic isEqual:[NSNull null]] || [dic count] <= 0) { + return 4000; + } + NSString *t_appid = [self getStr:@"appid" dic:dic]; + NSString *t_idfa = [self getStr:@"idfa" dic:dic]; + NSString *t_adId = [self getStr:@"id" dic:dic]; + NSNumber *t_ecpm = [self getNum:@"ecpm" dic:dic]; + BOOL ad = dic[@"ad"]; + NSString *iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName]; + // NSString *ipAddr = [[XSPhoneInfo sharedInstance] IPAddress]; + + /* + saveAdTaskLog(@{ + @"title": @"广告展示", + @"message": [XSHelper dic2Json:dic], + @"level": @(1), + @"appid": t_appid, + @"idfa":t_idfa, + @"adid": t_adId, + @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm], + @"taskId": self->taskId, + @"iphoneId":iphoneId, + @"ipAddr":ipAddr + + }); + */ + + /* -- + if (self->current > -1 && self->current < (NSInteger)self->tasks.count) { + cur = self->tasks[self->current]; + } + */ + if(!ad) { + NSLog(@"XS- no ad show"); + return 0; + } + int close = 4000; + //--new + AdLoadInfo adloadInfo = getAdLoadInfo(@{ + @"idfa": t_idfa ?: @"", + @"adId": t_adId ?: @"", + @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm], + @"appId": t_appid ?: @"", + @"deviceId":iphoneId ?: @"" + }); + + // cur.loads = adloadInfo.loads; + //cur.adTouchBeforeMs = adloadInfo.adTouchBeforeMs; + // cur.adTime= adloadInfo.adTime; + + + close = [adloadInfo.adTime intValue]; + int before = [adloadInfo.adTouchBeforeMs intValue]; + if (before >= close) { + before = 1000; + } + int after = [adloadInfo.adTouchAfterMs intValue]; + if(after > 1000) { + self->adAfter = after; + } else { + self->adAfter = 1000; + } + + NSInteger random1 = arc4random_uniform(101); // 0-100 + NSInteger tr = [adloadInfo.touchRate intValue]; + if (tr > random1) { + [self touchAppTask: before / 1000]; + } + return close; +} + +- (void) showStatus: (NSString *)data { + [[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data]; +} + +- (void) setRemoteInfo { + NSString *url = @"https://ipapi.co/json/"; + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + __weak typeof(self) weakSelf = self; + [http doGET:url withCallback:^(NSData *data) { + if(!data) { + NSLog(@"!setRemoteInfo 1data"); + [weakSelf showStatus:@"!setRemoteInfo 1data"]; + return; + } + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + if (!dic) { + NSLog(@"!setRemoteInfo dic"); + [weakSelf showStatus:@"!setRemoteInfo dic"]; + return; + } + NSString *isoCode = dic[@"country_code"]; + NSString *ip = dic[@"ip"]; + // callback(ip, isoCode); + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf->remoteIp = [ip copy]; + strongSelf->country = [isoCode copy]; + [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip]; + [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp]; + } withError:^(NSError *err) { + NSLog(@"!setRemoteInfo err:%@",err); + [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]]; + }]; +} + +- (void) setRemoteInfo1 { + NSString *url = [[XSPhoneConfig sharedInstance] GetRemoteIPURL]; + [self showStatus:url]; + if (!url) { + NSLog(@"!setRemoteInfo url"); + return; + } + __weak typeof(self) weakSelf = self; + + XSHttpHelper *http = [[XSHttpHelper alloc] init]; + [http doGET:url withCallback:^(NSData *data) { + if(!data) { + NSLog(@"!setRemoteInfo 1data"); + [weakSelf showStatus:@"!setRemoteInfo 1data"]; + return; + } + NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; + if (!dic) { + NSLog(@"!setRemoteInfo dic"); + [weakSelf showStatus:@"!setRemoteInfo dic"]; + return; + } + NSDictionary *_data = dic[@"data"]; + if(!_data) { + NSLog(@"!setRemoteInfo data"); + [weakSelf showStatus:@"!setRemoteInfo data"]; + return; + } + NSString *isoCode = _data[@"isoCode"]; + NSString *ip = _data[@"ip"]; + NSLog(@"setRemoteInfo:%@", _data); + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf->remoteIp = [ip copy]; + + strongSelf->country = [isoCode copy]; + [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip]; + [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp]; + } withError:^(NSError *err) { + NSLog(@"!setRemoteInfo err:%@",err); + [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]]; + }]; + + + +} + + +- (BOOL) onEnd: (NSDictionary *)dic { + NSNumber *maxEcpm = dic[@"max_ecpm"]; + int sec = self->adAfter / 1000; + __weak typeof(self) weakSelf = self; + if([maxEcpm doubleValue] <= 0.0) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{ + @autoreleasepool { + [weakSelf startApp]; + } + }); + return NO; + } + BOOL res = needAdContinue(self->taskAppId, self->_lastIdfa, maxEcpm); + if(res) { + return YES; + } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{ + @autoreleasepool { + [weakSelf startApp]; + } + }); + + return NO; +} + +- (void) startApp { + @autoreleasepool { + if(!self->running){ + return; + } + self->lastRun = [NSDate date]; + if (self->country == nil || [self->country isEqual:NULL] || [self->country isEqual:@""]) { + [self setRemoteInfo]; + self->lastGetCountry = [NSDate date]; + } else { + NSDate *curRunTime = [NSDate date]; + NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastGetCountry]; + if (elapsed >= 300) { + [self setRemoteInfo]; + self->lastGetCountry = [NSDate date]; + } + } + + /* + if(![@"US" isEqual:self->country]) { + [self showStatus:[NSString stringWithFormat:@"%@:%@, Not US", self->country, self->remoteIp]]; + return; + } + */ + __weak typeof(self) weakSelf = self; + getChangeInfo(self->_lastIdfa, ^(NSDictionary *dic) { + dispatch_async(weakSelf.manQueue, ^{ + // 耗时操作 + [weakSelf onChangeInfo: dic]; + }); + + }, ^(NSError *err) { + NSLog(@"XS- startTask NSError is null, %@", err); + }); + } +} + +- (void) start { + self->running = YES; + myadTaskManualStop = NO; + [[IPhoneHertbeat sharedInstance] setStatus: @"运行中"]; + [self startApp]; + __weak typeof(self) weakSelf = self; + // 使用 dispatch_source 创建timer + if (!_timer) { + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue); + dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 10 * NSEC_PER_SEC, 1 * NSEC_PER_SEC); + dispatch_source_set_event_handler(_timer, ^{ + @autoreleasepool { + [weakSelf proc]; + } + }); + dispatch_resume(_timer); + } + [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)]; +} + +- (void) proc { + if (!self->running) { + return; + } + + NSLog(@"XS- MyAdTaskManager proc"); + NSDate* curRunTime = [NSDate date]; + NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastRun]; + + if (elapsed >= 120) { + //[self onStop]; + [self start]; + + } else { + NSString* appId = [ self frontMostAppId]; + + if (![appId isEqual: self->taskAppId]) { + [self appKill:appId]; + sleep(1); + [self appRun:self->taskAppId]; + } + } + +} + +- (NSString *)toggle { + if(self->running) { + [self stop]; + } else { + [self start]; + } + return [IPhoneHertbeat sharedInstance].status; +} + +- (void) stop { + myadTaskManualStop = YES; + self->running = NO; + [IPhoneHertbeat sharedInstance].status = @"已停止"; + if (_timer) { + dispatch_source_cancel(_timer); + _timer = nil; + } + [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)]; +} + + +- (void) onChangeInfo: (NSDictionary *)dic { + NSString* t_idfa = [self getStr: @"idfa" dic:dic]; + if (![XSHelper strIsEmpty:t_idfa]) { + self->_lastIdfa = [t_idfa copy]; + } else { + NSLog(@"XS- startTask t_idfa is null"); + + return; + } + + NSString *_linkId = [self getStr:@"linkId" dic:dic]; + if (![XSHelper strIsEmpty:_linkId]) { + self->linkId = [_linkId copy]; + } + NSString *_dataId = [self getStr:@"dataId" dic:dic]; + if (![XSHelper strIsEmpty:_dataId]) { + self->dataId = [_dataId copy]; + } + + + NSString* t_taskId = [self getStr:@"id" dic:dic]; + if (![XSHelper strIsEmpty:t_taskId]) { + self->taskId = [t_taskId copy]; + } else { + NSLog(@"XS- startTask t_taskId is null"); + + return; + } + NSString* t_taskAppId = [self getStr:@"appId" dic:dic]; + if (![XSHelper strIsEmpty:t_taskAppId]) { + self->taskAppId = [t_taskAppId copy]; + [IPhoneHertbeat sharedInstance].appId = self->taskAppId; + } else { + NSLog(@"XS- startTask t_taskAppId is null"); + + return; + } + + NSDictionary *workerInfo = dic[@"workerInfo"]; + if(workerInfo && ![workerInfo isEqual:[NSNull null]]) { + + } else { + NSLog(@"XS- startTask workerInfo is null"); + + return; + } + + int t_workType = [self getInt:@"workType" dic:workerInfo]; + if (t_workType > -99) { + self->workType = t_workType; + } else { + NSLog(@"XS- startTask workType is null"); + + } + [self restart:^{ + saveChangeDataFile(dic); + self->running = YES; + sleep(1); + [self appRun:self->taskAppId]; + }]; + //sleep(1); +} + + +- (void) appKill: (NSString*) app { + NSLog(@"XS- appKill"); + XSKillAppByName(app); +} +- (void) unlock { + NSLog(@"XS- unlock"); + dispatch_async(dispatch_get_main_queue(), ^{ + XSRemoteUnlock(); + }); +} +- (void) resetApp: (NSString*) appId callback:(OnEndCallback) callback { + NSLog(@"XS- JSApi resetApp"); + NSString *appInfoPath = XSGetAppInfoPath(appId); + NSDictionary *appInfo = XSGetAppInfo(appInfoPath); + id bfaceDictKey = appInfo[@"bfaceDictKey"]; + NSMutableDictionary *tempBfaceDictKey = nil; + if(bfaceDictKey) { + tempBfaceDictKey = [NSMutableDictionary dictionaryWithDictionary:bfaceDictKey]; + } else { + tempBfaceDictKey = [[NSMutableDictionary alloc] init]; + } + NSString *serverUrl = [[XSPhoneConfig sharedInstance] ServerURL]; + + [tempBfaceDictKey setValue:@"http://127.0.0.1:6000" forKey:@"adbrush_local_url"]; + [tempBfaceDictKey setValue:serverUrl forKey:@"adbrush_base_url"]; + __weak typeof(self) weakSelf = self; + getLowEcpm(^(NSNumber *lowEcpm) { + __strong typeof(weakSelf) strongSelf = weakSelf; + BOOL washParam = strongSelf->workType == 0 ? YES : NO; + [tempBfaceDictKey setValue:@(washParam) forKey:@"washParam"]; + [tempBfaceDictKey setValue:lowEcpm forKey:@"adbrush_ecpm"]; + if(strongSelf->linkId) { + [tempBfaceDictKey setValue:strongSelf->linkId forKey:@"linkId"]; + } else { + NSString *linkId = [[NSUUID UUID] UUIDString]; + [tempBfaceDictKey setValue:linkId forKey:@"linkId"]; + } + + if(strongSelf->dataId) { + [tempBfaceDictKey setValue:strongSelf->dataId forKey:@"dataId"]; + } else { + NSString *dataId = @"0"; + [tempBfaceDictKey setValue:dataId forKey:@"dataId"]; + } + if(strongSelf->remoteIp) { + [tempBfaceDictKey setValue:strongSelf->remoteIp forKey:@"remouteIP"]; + } + + NSLog(@"XS- resetApp 1"); + NSMutableDictionary *tempAppInfo = [[NSMutableDictionary alloc] init]; + [tempAppInfo setValue:tempBfaceDictKey forKey:@"bfaceDictKey"]; + + XSClearAll(appId); + + XSSaveAppInfo(tempAppInfo, appInfoPath); + callback(); + }); +} +- (NSString *) frontMostAppId { + return XSFrontMostAppId(); +} +- (void) appRun:(NSString *)appId { + if ([XSHelper strIsEmpty:appId]) return; + + dispatch_async(dispatch_get_main_queue(), ^{ + @try { + bringAppToForeground(appId); + } @catch (NSException *exception) { + NSLog(@"Error bringing app to foreground: %@", exception); + } + }); +} + +- (void) tap: (int) i x:(int)x y:(int)y { + dispatch_async(dispatch_get_main_queue(), ^{ + XSIosTouch *touch = [XSIosTouch sharedInstance]; + [touch Tap:i x:x y:y]; + }); +} + +- (void) restart: (OnEndCallback) callback { + __weak typeof(self) weakSelf = self; + dispatch_async(self.manQueue, ^{ + @try { + __strong typeof(weakSelf) strongSelf = weakSelf; + [weakSelf appKill:@"com.apple.AppStore"]; + [weakSelf appKill:@"com.apple.mobilesafari"]; + if (strongSelf->taskAppId && ![strongSelf->taskAppId isEqual:[NSNull null]] && [strongSelf->taskAppId length] > 0) { + [weakSelf appKill:strongSelf->taskAppId]; + [weakSelf unlock]; + sleep(1); + [weakSelf unlock]; + [weakSelf resetApp:strongSelf->taskAppId callback:callback]; + } + } @catch (NSException *exception) { + NSLog(@"Error in restart: %@", exception); + } + }); +} + + +- (void) rndTouchApp { + int times = [XSHelper random:2 and:4]; + for (int i = 1; i <= times; i++) { + int x = [XSHelper random:40 and:screen_w - 20]; + int y = [XSHelper random:50 and:screen_h - 240]; + NSString* appId = [self frontMostAppId]; + if ([appId isEqual:self->taskAppId]) { + [self tap:1 x:x y:y]; + usleep(2000); + } else { + break; + } + } + +} + +- (void) touchAppTask: (int) beforeTouch { + if (beforeTouch > 0) { + sleep(beforeTouch); + } + [self rndTouchApp]; + sleep(2); + + int x = [XSHelper random:40 and:screen_w - 20]; + int y = [XSHelper random:50 and:screen_h - 240]; + [self tap:1 x:x y:y]; + + NSString* appId = [ self frontMostAppId]; + + if (![appId isEqual: self->taskAppId]) { + // [self appKill:appId]; + sleep(1); + } + + [self appRun:self->taskAppId]; +} +- (NSString*) getStr: (NSString *) key dic: (NSDictionary*) dic { + NSLog(@"getStr: %@", key); + id t_idfa = dic[key]; + if (t_idfa && ![t_idfa isEqual:[NSNull null]] && ![t_idfa isEqual:@""]) { + return [NSString stringWithFormat:@"%@", t_idfa]; + } else { + NSLog(@"XS- dic %@ is null", key); + return @""; + } +} +- (NSNumber*) getNum: (NSString *) key dic: (NSDictionary*) dic { + NSLog(@"getNum: %@", key); + id t_idfa = dic[key]; + NSString *ecpm_str = [NSString stringWithFormat:@"%@" , t_idfa]; + + NSNumber *ecpm = @0.0; + + if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) { + ecpm = [XSHelper str2num: ecpm_str]; + } + return ecpm; + +} + +- (int) getInt: (NSString *) key dic: (NSDictionary*) dic { + NSLog(@"getInt: %@", key); + id t_idfa = dic[key]; + NSString *ecpm_str = [NSString stringWithFormat:@"%@" , t_idfa]; + + NSNumber *ecpm = @(-99); + + if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) { + ecpm = [XSHelper str2num: ecpm_str]; + } + return [ecpm intValue]; +} + +- (void)dealloc { + [self stop]; +} + +@end + diff --git a/AppRunMan/server/MyEventBus.h b/AppRunMan/server/MyEventBus.h new file mode 100644 index 0000000..1cad10f --- /dev/null +++ b/AppRunMan/server/MyEventBus.h @@ -0,0 +1,33 @@ +// +// MyEventBus.h +// nochange +// +// Created by mac on 2024/7/30. +// + +#ifndef MyEventBus_h +#define MyEventBus_h + +#import + +typedef struct { + NSString *name; + NSDictionary *data; +} EventMessage; + +typedef void (^SubscriberCallback) (EventMessage *msg); + +@interface MyEventBus : NSObject +{ + +} + ++ (instancetype)sharedInstance; + +- (void)registerSubscriber:(id)subscriber; +- (void)unregisterSubscriber:(id)subscriber; +- (void)postEvent:(NSString *)eventName withObject:(id)object; + +@end + +#endif /* MyEventBus_h */ diff --git a/AppRunMan/server/MyEventBus.m b/AppRunMan/server/MyEventBus.m new file mode 100644 index 0000000..cb8b96c --- /dev/null +++ b/AppRunMan/server/MyEventBus.m @@ -0,0 +1,79 @@ +// +// MyEventBus.m +// nochange +// +// Created by mac on 2024/7/30. +// + +#import "MyEventBus.h" +#import + + +@interface MyEventBus() +{ + +} + +@property (nonatomic, strong) NSMutableDictionary *subscribers; + +@end + +@implementation MyEventBus + ++ (instancetype)sharedInstance { + static MyEventBus *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _subscribers = [NSMutableDictionary dictionary]; + } + return self; +} + +- (void)registerSubscriber:(id)subscriber { + unsigned int methodCount = 0; + Method *methods = class_copyMethodList([subscriber class], &methodCount); + + for (unsigned int i = 0; i < methodCount; i++) { + SEL selector = method_getName(methods[i]); + NSString *selectorName = NSStringFromSelector(selector); + + if ([selectorName hasPrefix:@"onEvent"]) { + NSString *eventName = [selectorName substringFromIndex:7]; + if (![self.subscribers objectForKey:eventName]) { + [self.subscribers setObject:[NSMutableArray array] forKey:eventName]; + } + [[self.subscribers objectForKey:eventName] addObject:subscriber]; + } + } + + free(methods); +} + +- (void)unregisterSubscriber:(id)subscriber { + [self.subscribers enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSMutableArray *obj, BOOL *stop) { + [obj removeObject:subscriber]; + }]; +} + +- (void)postEvent:(NSString *)eventName withObject:(id)object { + NSMutableArray *eventSubscribers = [self.subscribers objectForKey:[NSString stringWithFormat:@"%@:", eventName]]; + for (id subscriber in eventSubscribers) { + SEL selector = NSSelectorFromString([NSString stringWithFormat:@"onEvent%@:", eventName]); + if ([subscriber respondsToSelector:selector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [subscriber performSelector:selector withObject:object]; +#pragma clang diagnostic pop + } + } +} + +@end diff --git a/AppRunMan/server/MyScriptTask.h b/AppRunMan/server/MyScriptTask.h new file mode 100644 index 0000000..6595193 --- /dev/null +++ b/AppRunMan/server/MyScriptTask.h @@ -0,0 +1,67 @@ +// +// MyScriptTask.h +// nochange +// +// Created by mac on 2024/7/23. +// + +#ifndef MyScriptTask_h +#define MyScriptTask_h + +#import +#import +#import "MyAdServer.h" + +typedef struct { + int64_t _id; + int type; + NSString *appId; + NSString *idfa; + FixedPoint *btnLoc; + NSString *adId; + bool ad; +} ScriptTask; + +typedef void (^ScriptRunOverCallback)(NSString* res); +typedef void (^ScriptReplaceCallback)(NSMutableString *newScript); + +#define SCRIPT_START_TPL @"start.tpl.lua" +#define SCRIPT_START @"start.lua" +#define SCRIPT_TOUCH_BTN_TPL @"touch_btn.tpl.lua" +#define SCRIPT_TOUCH_BTN @"touch_btn.lua" +#define SCRIPT_TOUCH_AD_TPL @"touch_ad.tpl.lua" +#define SCRIPT_TOUCH_AD @"touch_ad.lua" +#define SCRIPT_KILL_ALL_TPL @"kill_all.tpl.lua" +#define SCRIPT_KILL_ALL @"kill_all.lua" + + +@interface MyScriptTask : NSObject +{ + +} + +@property (nonatomic, assign) int64_t currentId; +@property (strong, nonatomic) NSTimer *timer; + + +- (int) enqueue:(id)item; +- (id) dequeue; +- (void) run; +- (void) stop; +- (void) start; +- (void) adClosed: (ScriptTask *)task; +- (BOOL) isRun; +- (void) saveAdTaskLog: (AdTaskLogData *)data; + +- (int) runAdTouchScript: (ScriptTask *) taskData; + +- (NSString*) statusStr; +- (NSString*) appid; +- (void) loadIncrCount; +- (void) completeTask; ++(instancetype)sharedInstance; + + +@end + +#endif /* MyScriptTask_h */ diff --git a/AppRunMan/server/MyScriptTask.m b/AppRunMan/server/MyScriptTask.m new file mode 100644 index 0000000..5616350 --- /dev/null +++ b/AppRunMan/server/MyScriptTask.m @@ -0,0 +1,651 @@ +// +// MyScriptTask.m +// nochange +// +// Created by mac on 2024/7/23. +// + +#import "MyScriptTask.h" + +#import "XSHelper.h" +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" + +#import "MyEventBus.h" +#import "XSHackIos.h" +#import "XSIosTouch.h" + + +#define total_ad_click 3 + +@interface MyScriptTask() +{ + @private + // 单次app任务 + NSString* _taskId; + NSString* _appId; + BOOL _lastAppTaskComplete; + NSTimeInterval _lastAppTaskTime; + NSTimeInterval _lastOcrTime; + int _lastAppTaskCount; + int _total; + BOOL _stop; + int _taskTimeout; + int _workType; + + BOOL _lastTaskComplete; // 一个点击任务是否完成,按钮点击,广告展示,广告点击,广告回到页面 + NSTimeInterval _lastTaskTime; + int _step; // 0 等待点击 1: 点击完成,2: 点击广告;3:广告点击完成, + + int _adTouchBefore; + + + int _count; + int _safeTop; + + NSMutableDictionary *_adShows; + NSString *_idfa; + CGFloat device_screen_width; + CGFloat device_screen_height; + + int _loadCount; +} + +@property (nonatomic, strong) NSMutableArray *inStack; +@property (nonatomic, strong) NSMutableArray *outStack; +@property (nonatomic, strong) dispatch_queue_t concurrentQueue; + +@end + +@implementation MyScriptTask + +- (instancetype)init { + self = [super init]; + if (self) { + _currentId = 0; + _concurrentQueue = dispatch_queue_create("com.xyzshell.adtask.queue", DISPATCH_QUEUE_CONCURRENT); + _inStack = [NSMutableArray array]; + _outStack = [NSMutableArray array]; + _adShows = [[NSMutableDictionary alloc] init]; + + _taskTimeout = 30; + _workType = 1; + + _lastTaskComplete = YES; + _stop = NO; + _total = 0; + _count = 0; + _lastAppTaskComplete = YES; + _lastAppTaskTime = [self getCurTime]; + _lastAppTaskCount = 0; + _safeTop = 20; + _adTouchBefore = 3; + _taskId = @"0"; + _appId = @""; + _loadCount = 0; + _lastOcrTime = [self getCurTime]; + NSLog(@"OhNo Server Start %@", [[XSPhoneConfig sharedInstance] IPhoneName]); + CGFloat screen_scale = [[UIScreen mainScreen] scale]; + self->device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale; + self->device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale; + } + return self; +} + +- (void) showStatus: (NSString *)data { + [[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data]; +} + +- (void) start { + _stop = NO; + + [self runStartApp]; +} + +- (void) stop { + _stop = YES; +} + +- (int64_t)nextId { + @synchronized (self) { + self.currentId++; + return self.currentId; + } +} + +- (int)enqueue:(id)item { + int load = 0; + dispatch_barrier_async(self.concurrentQueue, ^{ + NSDictionary *dic = item; + NSLog(@"-ad log- add task:\n %@", dic); + NSMutableDictionary *taskDic = [[NSMutableDictionary alloc] initWithDictionary:dic]; + [taskDic setValue:@([self nextId]) forKey:@"_id"]; + [self->_adShows setValue: dic[@"ad_time"] forKey:dic[@"adId"]]; + self ->_adTouchBefore = [dic[@"ad_touchBeforeMs"] intValue]; + [self.inStack addObject:taskDic]; + self->_count++; + [self showStatus:[NSString stringWithFormat: @"队列任务数量:%d, loads:%@", self->_count, dic[@"ad_loads"]]]; + }); + return load; +} + +- (id)dequeue { + __block id result = nil; + dispatch_barrier_sync(self.concurrentQueue, ^{ + if ([self.outStack count] == 0) { + NSUInteger count = [self.inStack count]; + while (count > 0) { + [self.outStack addObject:[self.inStack lastObject]]; + [self.inStack removeLastObject]; + count--; + } + } + + if ([self.outStack count] > 0) { + result = [self.outStack lastObject]; + [self.outStack removeLastObject]; + } + }); + return result; +} + +- (void) reset { + _lastTaskComplete = YES; + _lastTaskTime = [self getCurTime]; +} + + + +- (BOOL) isRun { + return !_stop;; +} + +- (void) run { + dispatch_queue_t queue = dispatch_get_global_queue(0,0); + dispatch_async(queue, ^{ + self.timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(proc) userInfo:nil repeats:YES]; + //timer 加入runloop + [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode]; + //开启runloop + [[NSRunLoop currentRunLoop] run]; + }); +} + +- (void) completeTask { + _lastTaskComplete = YES; + _lastTaskTime = [self getCurTime]; + _lastAppTaskCount++; +} + +- (void) adClosed: (ScriptTask *)task { + [self showStatus:[NSString stringWithFormat:@"关闭:%@", task->adId]]; + [self completeTask]; +} + +- (void) loadIncrCount { + self->_loadCount = self->_loadCount + 1; +} + +-(void) restart { + dispatch_barrier_sync(self.concurrentQueue, ^{ + _loadCount = 0; + _lastTaskComplete = YES; + _lastTaskTime = [self getCurTime]; + _lastAppTaskComplete = YES; + _lastAppTaskTime = [self getCurTime]; + _lastAppTaskCount = 0; + [self.outStack removeAllObjects]; + [self.inStack removeAllObjects]; + [_adShows removeAllObjects]; + _count = 0; + }); +} + +- (void) killApp: (NSString *)pkgName { + XSKillAppByName(pkgName); +} + +- (void) runStartApp { + [self restart]; + NSLog(@"-ad log- runStartApp"); + getChangeInfo(_idfa, ^(NSDictionary *dic) { + if (!dic || [dic isEqual: [NSNull null]]) { + NSLog(@"get change info dic is null"); + return; + } + NSDictionary *workInfo = dic[@"workerInfo"]; + if (!workInfo || [workInfo isEqual:[NSNull null]]) { + NSLog(@"-ad log- not have task"); + return; + } + NSNumber *workType = workInfo[@"workType"]; + self->_workType = [workType intValue]; + if (self->_workType <= -1) { + NSLog(@"-ad log- not have task"); + return; + } + self->_taskId = dic[@"id"]; + self->_idfa = dic[@"idfa"]; + + saveChangeDataFile(dic); + // NSNumber *taskTimeout = workInfo[@"taskTimeout"]; + + self->_appId = dic[@"appId"]; + NSLog(@"-ad log- change %@", self->_appId); + NSDictionary *safeAreaInsets = dic[@"safeAreaInsets"]; + if (safeAreaInsets) { + NSString *top = safeAreaInsets[@"top"]; + if (top) { + self->_safeTop = [top intValue]; + } + } + // 获取任务,开始启动 + //ScriptTask oldtask = { + // .appId = self->_appId + //}; + [self killApp:self->_appId]; + // [self runStopScript:&oldtask]; + + // 获取任务,开始启动 + //ScriptTask task = { + // .appId = self->_appId, + //}; + dispatch_async(dispatch_get_main_queue(), ^{ + XSRemoteUnlock(); + usleep(5000); + XSRemoteUnlock(); + }); + + //[self runSystemRestartScript]; + + // TODO: 备份数据 + NSString *appInfoPath = XSGetAppInfoPath(self->_appId); + NSDictionary *appInfo = XSGetAppInfo(appInfoPath); + + XSClearAll(self->_appId); + + XSSaveAppInfo(appInfo, appInfoPath); + + + // 1.截图 ocr识别弹窗,并关闭 + if([self getCurTime] - self->_lastOcrTime > 20) { + dispatch_async(dispatch_get_main_queue(), ^{ + @autoreleasepool { + self->_lastOcrTime = [self getCurTime]; + UIImage *img = XSCcaptureScreen2(); + UIImage *jpg = [XSHelper png2jpg:img]; + if (jpg.CGImage) { + UIImage *tempImg = [UIImage imageWithCGImage:jpg.CGImage]; + [XSHelper performOCROnImage:tempImg callback:^(NSString *text) { + if (text == nil || [text isEqual:[NSNull null]] || [text length] <= 0) { + NSLog(@"ocr text is null"); + } else { + if ([text containsString:@"Apple ID Required"]) { + XSIosTouch *touch = [[XSIosTouch alloc] init]; + [touch Tap:2 x:244 y:766]; + } else if([text containsString:@"This accessory may"]) { + XSIosTouch *touch = [[XSIosTouch alloc] init]; + [touch Tap:2 x:382 y:746]; + } + } + }]; + } + jpg = nil; + img = nil; + } + }); + } + + [[UIApplication sharedApplication] performSelectorOnMainThread:@selector(beginIgnoringInteractionEvents) withObject:nil waitUntilDone:YES]; + [[UIApplication sharedApplication] performSelectorOnMainThread:@selector(endIgnoringInteractionEvents) withObject:nil waitUntilDone:YES]; + + //[self runStartScript:&task]; + XSBringAppForeground(self->_appId); + }, ^(NSError *err) { + + }); + +} +- (void) proc { + @try { + [self _proc]; + } @catch (NSException *exception) { + NSLog(@"-ad- erro"); + } +} +- (void) _proc { + if (_stop) { + return; + } + NSLog(@"start proc task........"); + + if (_workType < 1) { + if (_count > 1 && ([self getCurTime] - _lastAppTaskTime) > 6) { + [self runStartApp]; + } else if (([self getCurTime] - _lastAppTaskTime) > 20){ + [self runStartApp]; + } + + return; + } + if (_workType == 4) { + if (_lastTaskComplete == YES) { + _lastTaskComplete = NO; + _lastTaskTime = [self getCurTime]; + ScriptTask sctask = { + .idfa = _idfa, + .appId = _appId, + .ad = true, + .adId = @"" + }; + AdTaskLogData logData = { + .title = @"广告展示", + .idfa = _idfa, + .appid = _appId, + .adid = @"", + .message = @"", + .level = 1, + .ecpm = @(0) + }; + self->_adTouchBefore = 10000; + [[MyScriptTask sharedInstance] saveAdTaskLog:&logData]; + [[MyScriptTask sharedInstance] runAdTouchScript:&sctask]; + return; + } else { + if (([self getCurTime] - _lastTaskTime) > 18) { + [self runStartApp]; + return; + } + } + } + + + if (self->_loadCount > 0) { + if (_lastAppTaskCount >= self->_loadCount) { + sleep(2); + [self runStartApp]; + return; + } + } + + if (([self getCurTime] - _lastAppTaskTime) > 80) { + [self runStartApp]; + return; + } + if (_lastTaskComplete == NO) { + // 上次任务没有执行完,30秒不等待,继续下一个任务 + if (_lastTaskTime && ([self getCurTime] - _lastTaskTime) < _taskTimeout) { + NSLog(@"last task running"); + return; + } + } + + @try { + id task = [self dequeue]; + if (task) { + _lastTaskComplete = NO; + if (_lastAppTaskComplete == YES) { + _lastAppTaskComplete = NO; + } + // 处理任务 + _lastTaskTime = [self getCurTime]; + NSMutableDictionary *taskData = task; + NSLog(@"pad roc task: \n%@", taskData); + NSString *type = taskData[@"type"]; + if ([type isEqual:@"click_btn"]) { + NSLog(@"ad proc task: click_btn - begin"); + [self showStatus:[NSString stringWithFormat:@"点击:%@", taskData[@"adId"]]]; + NSNumber *x = taskData[@"x"]; + NSNumber *y = taskData[@"y"]; + FixedPoint point = { + .x = [x intValue], + .y = [y intValue] + }; + ScriptTask st = { .btnLoc = &point, .appId=_appId }; + [self runAdShowScript:&st]; + } + } else { + if (_lastTaskTime && ([self getCurTime] - _lastTaskTime) > 20) { + [self runStartApp]; + return; + } + } + } + @catch (NSException *exception) { + NSLog(@"ad proc ex name: %@", exception.name); + NSLog(@"ad proc ex reason: %@", exception.reason); + [self completeTask]; + } + @finally { + NSLog(@"ad proc end"); + } +} + +- (BOOL) replaceScript: (NSString *)tplName scriptName: (NSString *)scriptName callback: (ScriptReplaceCallback)callback { + NSString *scriptTpl = [self readScript:tplName]; + if (scriptTpl == nil) { + NSLog(@"ad read script is nil"); + return NO; + } + NSLog(@"ad tpl script: %@", tplName); + NSMutableString *newScript = [NSMutableString stringWithString:scriptTpl]; + callback(newScript); + // NSLog(@"ad new script: %@", newScript); + return [self saveScript:[newScript copy] name:scriptName]; +} + +- (void) runAdShowScript: (ScriptTask *) taskData { + // 1. 写入按钮点击脚本 + NSLog(@"ad runAdShowScript"); + + NSString *curApp = XSFrontMostAppId(); + if(![self->_appId isEqual:curApp]) { + XSBringAppForeground(self->_appId); + sleep(2); + } + usleep(5000); + int x = taskData->btnLoc->x * 2; + int y = taskData->btnLoc->y; + int ny = y * 2 + (self->_safeTop / 2) - 10; + [[XSIosTouch sharedInstance] Tap:1 x:x y:ny]; + + + /* + BOOL flag = [self replaceScript:SCRIPT_TOUCH_BTN_TPL scriptName:SCRIPT_TOUCH_BTN callback:^(NSMutableString *newScript) { + + + [MyHelper replaceMulStr:newScript oldStr:@"local btn_x = __BTN_X__" newStr:[NSString stringWithFormat:@"local btn_x = %d", x]]; + [MyHelper replaceMulStr:newScript oldStr:@"local btn_y = __BTN_Y__" newStr:[NSString stringWithFormat:@"local btn_y = %d", ny]]; + [MyHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId]; + + }]; + + + // 2. 运行脚本 + if (flag) { + NSLog(@"save script ok: %@", SCRIPT_TOUCH_BTN); + NSString *res = [self runScript:SCRIPT_TOUCH_BTN]; + if (res) { + NSLog(@"ad run script success: %@", SCRIPT_TOUCH_BTN); + [self showStatus:[NSString stringWithFormat:@"运行点击按钮成功,%@",res]]; + } else { + [self showStatus:[NSString stringWithFormat:@"运行点击按钮失败,%@",res]]; + } + + } else { + NSLog(@"save script error: %@", SCRIPT_TOUCH_BTN); + [self showStatus:@"保存按钮点击脚本失败"]; + } + //*/ +} + +- (void) runStopScript: (ScriptTask *) taskData { + + BOOL flag = [self replaceScript:SCRIPT_KILL_ALL_TPL scriptName:SCRIPT_KILL_ALL callback:^(NSMutableString *newScript) { + [XSHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId]; + }]; + if (flag) { + // 结束所有相关app + NSString *res = [self runScript:SCRIPT_KILL_ALL]; + if (res) { + NSLog(@"-ad -log %@",res); + } + } + +} + +- (int) runAdTouchScript: (ScriptTask *) taskData { + if (!taskData->ad) { + // 没有广告展示 + NSLog(@"-ad log- touch btn No ad"); + [self completeTask]; + [self showStatus: [NSString stringWithFormat:@"广告展示失败:%@", taskData->adId]]; + return 0; + } + _lastTaskTime = [self getCurTime]; + /* + NSLog(@"-ad log- run ad touch script: %@", SCRIPT_TOUCH_AD); + BOOL flag = [self replaceScript:SCRIPT_TOUCH_AD_TPL scriptName:SCRIPT_TOUCH_AD callback:^(NSMutableString *newScript) { + [MyHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId]; + [MyHelper replaceMulStr:newScript oldStr:@"__BEFORE__" newStr:[NSString stringWithFormat:@"%d", self->_adTouchBefore]]; + }]; + if (flag) { + NSString *res = [self runScript:SCRIPT_TOUCH_AD]; + if (res) { + NSLog(@"sc res: %@", res); + } + + } + */ + [self runTouchAdJs:self->_adTouchBefore]; + int show_ms = 5000; + if ([_adShows objectForKey:taskData->adId]) { + NSNumber *shows = _adShows[taskData->adId]; + show_ms = [shows intValue]; + } + [self showStatus: [NSString stringWithFormat:@"广告展,%@", taskData->adId]]; + // 点击广告 + return show_ms; +} + +- (void) runStartScript: (ScriptTask *) taskData { + // 启动app 开始任务 + // 清除队列里面所有任务, 重置状态 + [self showStatus:@"start new task"]; + _lastTaskTime = [self getCurTime]; + + BOOL flag = [self replaceScript:SCRIPT_START_TPL scriptName:SCRIPT_START callback:^(NSMutableString *newScript) { + [XSHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId]; + }]; + if (flag) { + NSString *res = [self runScript:SCRIPT_START]; + if (res) { + NSLog(@"-ad- start task:%@", res); + } + } +} + +- (void) runSystemRestartScript { + NSString *res = [self runScript:@"close_not_now.lua"]; + if (res) { + NSLog(@"kill a all"); + } +} + +- (NSString *) runScript: (NSString *)script { + /* + NSString *url = [NSString stringWithFormat:@"http://127.0.0.1:8080/control/start_playing?path=/%@", script]; + [XSHelper doGET:url withCallback:^(NSData* _data) { + if (_data) { + NSString *res = [MyHelper data2str:_data]; + [self showStatus:[NSString stringWithFormat: @"运行脚本成功,%@", res]]; + } + } withError:^(NSError *err) { + NSLog(@"run autouch script error"); + }]; + + NSLog(@"run autouch script error"); + */ + return nil; +} + +- (NSString *) stopScript: (NSString *)script { + /* + NSString *url = [NSString stringWithFormat:@"http://127.0.0.1:8080/control/stop_playing?path=/%@", script]; + [_http doGET:url callback:^(NSData* _data) { + if (_data) { + NSString *res = [MyHelper data2str:_data]; + [self showStatus:[NSString stringWithFormat: @"停止脚本成功,%@", res]]; + } + }]; + NSLog(@"run autouch script error"); + */ + return nil; +} + +- (NSString *) readScript: (NSString *)name { + NSString *scriptPath = [self getScriptPath:name]; + return [XSHelper readFileText:scriptPath]; +} + +- (BOOL) saveScript: (NSString *)script name:(NSString *)name { + NSString *scriptPath = [self getScriptPath:name]; + return [XSHelper saveFile:scriptPath text:script]; +} + +- (NSString *) getScriptPath: (NSString *) name { + return [NSString stringWithFormat:@"/var/mobile/Library/AutoTouch/Scripts/%@", name]; +} + +- (NSTimeInterval) getCurTime { + // 获取当前日期和时间 + NSDate *now = [NSDate date]; + return [now timeIntervalSince1970]; +} + +- (void) logServer: (NSString *) info title: (NSString *)title { + +} + +- (void) saveAdTaskLog: (AdTaskLogData *)data { + data->taskId = _taskId; + data->iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName]; + data->ipAddr = [[XSPhoneInfo sharedInstance] IPAddress]; + pushAdTaskLog(data); +} + +- (NSString*) statusStr { + NSString *runStatusStr = _stop ? @"已停止": @"运行中"; + return [NSString stringWithFormat:@"%@", runStatusStr]; +} +- (NSString*) appid { + return _appId; +} + +- (void) runTouchAdJs: (NSInteger) befor { + /* + JsRunner *runner = [[JsRunner alloc] init]; + NSString *tmpCode = @"var beforeTouch = %@;" + "var cur_app_id = \"%@\";" + "var screen_w = %@;" + "var screen_h = %@;"; + NSString *code = [NSString stringWithFormat:tmpCode, @(befor / 1000), [self appid], @(self->device_screen_width), @(self->device_screen_height)]; + NSLog(@"runTouchAdJs:%@", code); + [runner runCode:code]; + [runner runJS:@"/var/mobile/Library/AutoTouch/Scripts/touch_ad.js" timeout:50 completion:^(JSValue *result, BOOL timedOut) { + NSLog(@"runTouchAdJs end"); + }]; + */ +} + ++(instancetype)sharedInstance +{ + static MyScriptTask* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[MyScriptTask alloc] init]; + }); + return _sharedInstance; +} + +@end diff --git a/AppRunMan/server/MySimpleServer.h b/AppRunMan/server/MySimpleServer.h new file mode 100644 index 0000000..5ccf14a --- /dev/null +++ b/AppRunMan/server/MySimpleServer.h @@ -0,0 +1,31 @@ +// +// MySimpleServer.h +// nochange +// +// Created by mac on 2024/7/21. +// + +#ifndef MySimpleServer_h +#define MySimpleServer_h + +#include +#include +#include +#include + + + +void startSimpleServer(void); + +void cleanupServer(void); + + +@interface MessagePortServer : NSObject +- (void)startServer; +- (void)stopServer; +@end + + + + +#endif /* MySimpleServer_h */ diff --git a/AppRunMan/server/MySimpleServer.m b/AppRunMan/server/MySimpleServer.m new file mode 100644 index 0000000..c565f1e --- /dev/null +++ b/AppRunMan/server/MySimpleServer.m @@ -0,0 +1,76 @@ +// +// MySimpleServer.m +// nochange +// +// Created by mac on 2024/7/21. +// + +#import + + +#import "MyScriptTask.h" +#import "XSHelper.h" +#import +#import "IPhoneHertbeat.h" + +#import "MySimpleServer.h" +#import "IosSystemCmd.h" +#import "MyAdServer.h" +#import "XSIosTouch.h" +#import "XSHackIos.h" +#import "MyAdTask2.h" +#import "XUDPServer.h" + + + +void startSimpleServer(void) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // 初始化信号处理 + registerSignalHandler(); + NSLog(@"XS- start server"); + + // 创建专用的串行队列 + dispatch_queue_t serverQueue = dispatch_queue_create("com.xzyshell.serverqueue", DISPATCH_QUEUE_SERIAL); + + // 在主队列初始化关键服务 + dispatch_async(dispatch_get_main_queue(), ^{ + [[IPhoneHertbeat sharedInstance] start]; + [[IosSystemCmd sharedInstance] start]; + }); + + // 在服务器队列中处理服务器相关操作 + dispatch_async(serverQueue, ^{ + @autoreleasepool { + // 初始化发送者ID + XSInitGetSenderId(); + + // 启动日志 + pushIphoneLog(@"on start simple server!!!"); + + + + // 完成日志 + pushIphoneLog(@"on start simple server -ok"); + + // 服务器端 + // MessagePortServer *server = [[MessagePortServer alloc] init]; + // [server startServer]; + XUDPServer *udpserver = [XUDPServer sharedInstance]; + [udpserver start]; + // 创建运行循环 + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + + // 添加一个端口来保持运行循环活跃 + [runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; + + // 运行循环 + [runLoop run]; + } + }); + }); +} + + + + diff --git a/AppRunMan/server/UDPHandler.h b/AppRunMan/server/UDPHandler.h new file mode 100644 index 0000000..974566a --- /dev/null +++ b/AppRunMan/server/UDPHandler.h @@ -0,0 +1,17 @@ +// +// UDPHandler.h +// nochange +// +// Created by mac on 2025/2/20. +// + +#ifndef UDPHandler_h +#define UDPHandler_h + +@interface UDPHandler : NSObject ++(instancetype)sharedInstance; +- (NSString *) handle: (NSString*) data; + +@end + +#endif /* UDPHandler_h */ diff --git a/AppRunMan/server/UDPHandler.m b/AppRunMan/server/UDPHandler.m new file mode 100644 index 0000000..c6757a3 --- /dev/null +++ b/AppRunMan/server/UDPHandler.m @@ -0,0 +1,89 @@ +// +// UDPHandler.m +// nochange +// +// Created by mac on 2025/2/20. +// + +#import +#import "XSHelper.h" +#import "XSHackIos.h" +#import "MyAdTask2.h" + +#import "UDPHandler.h" + +@interface UDPHandler () { + +} + +@end + +@implementation UDPHandler + ++(instancetype)sharedInstance +{ + static UDPHandler* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[UDPHandler alloc] init]; + }); + return _sharedInstance; +} + +-(instancetype)init { + if (self = [super init]) { + return self; + } + return nil; +} + +- (NSString *)handle:(NSString *)data { + NSDictionary *dic = [XSHelper json2Dictionary: data]; + NSString *path = dic[@"url"]; + NSString *res = @"err"; + NSMutableDictionary *resData = [[NSMutableDictionary alloc] init]; + [resData setValue:@"Success" forKey:@"status"]; + if ([XSHelper isMatch:@"^/health" test:path]) { + return [XSHelper dic2Json:resData]; + } + else if ([XSHelper isMatch:@"^/unlock" test:path]) { + dispatch_async(dispatch_get_main_queue(), ^{ + XSRemoteUnlock(); + }); + return [XSHelper dic2Json:resData]; + } + else if ([XSHelper isMatch:@"^/start" test:path]) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + MyAdTask2Mangger *ad = [MyAdTask2Mangger sharedInstance]; + [ad start]; + }); + + return [XSHelper dic2Json:resData]; + } + else if ([XSHelper isMatch:@"^/stop" test:path]) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + MyAdTask2Mangger *ad = [MyAdTask2Mangger sharedInstance]; + [ad stop]; + }); + return [XSHelper dic2Json:resData]; + } + else if([XSHelper isMatch:@"^/adtask/show" test:path]) { + MyAdTask2Mangger *ad = [MyAdTask2Mangger sharedInstance]; + NSDictionary *rq = dic[@"body"]; + int close = [ad onShow:rq]; + [resData setValue:@(close) forKey:@"close"]; + return [XSHelper dic2Json:resData]; + } + else if([XSHelper isMatch:@"^/adtask/end" test:path]) { + MyAdTask2Mangger *ad = [MyAdTask2Mangger sharedInstance]; + NSDictionary *rq = dic[@"body"]; + BOOL r = [ad onEnd:rq]; + [resData setValue:@(r) forKey:@"restart"]; + return [XSHelper dic2Json:resData]; + } + return res; +} + +@end + + diff --git a/AppRunMan/server/UIView+Toast.h b/AppRunMan/server/UIView+Toast.h new file mode 100755 index 0000000..c0e2154 --- /dev/null +++ b/AppRunMan/server/UIView+Toast.h @@ -0,0 +1,446 @@ +// +// UIView+Toast.h +// Toast +// +// Copyright (c) 2011-2024 Charles Scalesse. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#import + +extern const NSString * CSToastPositionTop; +extern const NSString * CSToastPositionCenter; +extern const NSString * CSToastPositionBottom; + +@class CSToastStyle; + +/** + Toast is an Objective-C category that adds toast notifications to the UIView + object class. It is intended to be simple, lightweight, and easy to use. Most + toast notifications can be triggered with a single line of code. + + The `makeToast:` methods create a new view and then display it as toast. + + The `showToast:` methods display any view as toast. + + */ +@interface UIView (Toast) + +/** + Creates and presents a new toast view with a message and displays it with the + default duration and position. Styled using the shared style. + + @param message The message to be displayed + */ +- (void)makeToast:(NSString *)message; + +/** + Creates and presents a new toast view with a message. Duration and position + can be set explicitly. Styled using the shared style. + + @param message The message to be displayed + @param duration The toast duration + @param position The toast's center point. Can be one of the predefined CSToastPosition + constants or a `CGPoint` wrapped in an `NSValue` object. + */ +- (void)makeToast:(NSString *)message + duration:(NSTimeInterval)duration + position:(id)position; + +/** + Creates and presents a new toast view with a message. Duration, position, and + style can be set explicitly. + + @param message The message to be displayed + @param duration The toast duration + @param position The toast's center point. Can be one of the predefined CSToastPosition + constants or a `CGPoint` wrapped in an `NSValue` object. + @param style The style. The shared style will be used when nil + */ +- (void)makeToast:(NSString *)message + duration:(NSTimeInterval)duration + position:(id)position + style:(CSToastStyle *)style; + +/** + Creates and presents a new toast view with a message, title, and image. Duration, + position, and style can be set explicitly. The completion block executes when the + toast view completes. `didTap` will be `YES` if the toast view was dismissed from + a tap. + + @param message The message to be displayed + @param duration The toast duration + @param position The toast's center point. Can be one of the predefined CSToastPosition + constants or a `CGPoint` wrapped in an `NSValue` object. + @param title The title + @param image The image + @param style The style. The shared style will be used when nil + @param completion The completion block, executed after the toast view disappears. + didTap will be `YES` if the toast view was dismissed from a tap. + */ +- (void)makeToast:(NSString *)message + duration:(NSTimeInterval)duration + position:(id)position + title:(NSString *)title + image:(UIImage *)image + style:(CSToastStyle *)style + completion:(void(^)(BOOL didTap))completion; + +/** + Creates a new toast view with any combination of message, title, and image. + The look and feel is configured via the style. Unlike the `makeToast:` methods, + this method does not present the toast view automatically. One of the showToast: + methods must be used to present the resulting view. + + @warning if message, title, and image are all nil, this method will return nil. + + @param message The message to be displayed + @param title The title + @param image The image + @param style The style. The shared style will be used when nil + @return The newly created toast view + */ +- (UIView *)toastViewForMessage:(NSString *)message + title:(NSString *)title + image:(UIImage *)image + style:(CSToastStyle *)style; + +/** + Hides the active toast. If there are multiple toasts active in a view, this method + hides the oldest toast (the first of the toasts to have been presented). + + @see `hideAllToasts` to remove all active toasts from a view. + + @warning This method has no effect on activity toasts. Use `hideToastActivity` to + hide activity toasts. + */ +- (void)hideToast; + +/** + Hides an active toast. + + @param toast The active toast view to dismiss. Any toast that is currently being displayed + on the screen is considered active. + + @warning this does not clear a toast view that is currently waiting in the queue. + */ +- (void)hideToast:(UIView *)toast; + +/** + Hides all active toast views and clears the queue. + */ +- (void)hideAllToasts; + +/** + Hides all active toast views, with options to hide activity and clear the queue. + + @param includeActivity If `true`, toast activity will also be hidden. Default is `false`. + @param clearQueue If `true`, removes all toast views from the queue. Default is `true`. + */ +- (void)hideAllToasts:(BOOL)includeActivity clearQueue:(BOOL)clearQueue; + +/** + Removes all toast views from the queue. This has no effect on toast views that are + active. Use `hideAllToasts` to hide the active toasts views and clear the queue. + */ +- (void)clearToastQueue; + +/** + Creates and displays a new toast activity indicator view at a specified position. + + @warning Only one toast activity indicator view can be presented per superview. Subsequent + calls to `makeToastActivity:` will be ignored until hideToastActivity is called. + + @warning `makeToastActivity:` works independently of the showToast: methods. Toast activity + views can be presented and dismissed while toast views are being displayed. `makeToastActivity:` + has no effect on the queueing behavior of the showToast: methods. + + @param position The toast's center point. Can be one of the predefined CSToastPosition + constants or a `CGPoint` wrapped in an `NSValue` object. + */ +- (void)makeToastActivity:(id)position; + +/** + Dismisses the active toast activity indicator view. + */ +- (void)hideToastActivity; + +/** + Displays any view as toast using the default duration and position. + + @param toast The view to be displayed as toast + */ +- (void)showToast:(UIView *)toast; + +/** + Displays any view as toast at a provided position and duration. The completion block + executes when the toast view completes. `didTap` will be `YES` if the toast view was + dismissed from a tap. + + @param toast The view to be displayed as toast + @param duration The notification duration + @param position The toast's center point. Can be one of the predefined CSToastPosition + constants or a `CGPoint` wrapped in an `NSValue` object. + @param completion The completion block, executed after the toast view disappears. + didTap will be `YES` if the toast view was dismissed from a tap. + */ +- (void)showToast:(UIView *)toast + duration:(NSTimeInterval)duration + position:(id)position + completion:(void(^)(BOOL didTap))completion; + +@end + +/** + `CSToastStyle` instances define the look and feel for toast views created via the + `makeToast:` methods as well for toast views created directly with + `toastViewForMessage:title:image:style:`. + + @warning `CSToastStyle` offers relatively simple styling options for the default + toast view. If you require a toast view with more complex UI, it probably makes more + sense to create your own custom UIView subclass and present it with the `showToast:` + methods. + */ +@interface CSToastStyle : NSObject + +/** + The background color. Default is `[UIColor blackColor]` at 80% opacity. + */ +@property (strong, nonatomic) UIColor *backgroundColor; + +/** + The title color. Default is `[UIColor whiteColor]`. + */ +@property (strong, nonatomic) UIColor *titleColor; + +/** + The message color. Default is `[UIColor whiteColor]`. + */ +@property (strong, nonatomic) UIColor *messageColor; + +/** + A percentage value from 0.0 to 1.0, representing the maximum width of the toast + view relative to it's superview. Default is 0.8 (80% of the superview's width). + */ +@property (assign, nonatomic) CGFloat maxWidthPercentage; + +/** + A percentage value from 0.0 to 1.0, representing the maximum height of the toast + view relative to it's superview. Default is 0.8 (80% of the superview's height). + */ +@property (assign, nonatomic) CGFloat maxHeightPercentage; + +/** + The spacing from the horizontal edge of the toast view to the content. When an image + is present, this is also used as the padding between the image and the text. + Default is 10.0. + */ +@property (assign, nonatomic) CGFloat horizontalPadding; + +/** + The spacing from the vertical edge of the toast view to the content. When a title + is present, this is also used as the padding between the title and the message. + Default is 10.0. + */ +@property (assign, nonatomic) CGFloat verticalPadding; + +/** + The corner radius. Default is 10.0. + */ +@property (assign, nonatomic) CGFloat cornerRadius; + +/** + The title font. Default is `[UIFont boldSystemFontOfSize:16.0]`. + */ +@property (strong, nonatomic) UIFont *titleFont; + +/** + The message font. Default is `[UIFont systemFontOfSize:16.0]`. + */ +@property (strong, nonatomic) UIFont *messageFont; + +/** + The title text alignment. Default is `NSTextAlignmentLeft`. + */ +@property (assign, nonatomic) NSTextAlignment titleAlignment; + +/** + The message text alignment. Default is `NSTextAlignmentLeft`. + */ +@property (assign, nonatomic) NSTextAlignment messageAlignment; + +/** + The maximum number of lines for the title. The default is 0 (no limit). + */ +@property (assign, nonatomic) NSInteger titleNumberOfLines; + +/** + The maximum number of lines for the message. The default is 0 (no limit). + */ +@property (assign, nonatomic) NSInteger messageNumberOfLines; + +/** + Enable or disable a shadow on the toast view. Default is `NO`. + */ +@property (assign, nonatomic) BOOL displayShadow; + +/** + The shadow color. Default is `[UIColor blackColor]`. + */ +@property (strong, nonatomic) UIColor *shadowColor; + +/** + A value from 0.0 to 1.0, representing the opacity of the shadow. + Default is 0.8 (80% opacity). + */ +@property (assign, nonatomic) CGFloat shadowOpacity; + +/** + The shadow radius. Default is 6.0. + */ +@property (assign, nonatomic) CGFloat shadowRadius; + +/** + The shadow offset. The default is `CGSizeMake(4.0, 4.0)`. + */ +@property (assign, nonatomic) CGSize shadowOffset; + +/** + The image size. The default is `CGSizeMake(80.0, 80.0)`. + */ +@property (assign, nonatomic) CGSize imageSize; + +/** + The size of the toast activity view when `makeToastActivity:` is called. + Default is `CGSizeMake(100.0, 100.0)`. + */ +@property (assign, nonatomic) CGSize activitySize; + +/** + The fade in/out animation duration. Default is 0.2. + */ +@property (assign, nonatomic) NSTimeInterval fadeDuration; + +/** + Creates a new instance of `CSToastStyle` with all the default values set. + */ +- (instancetype)initWithDefaultStyle NS_DESIGNATED_INITIALIZER; + +/** + @warning Only the designated initializer should be used to create + an instance of `CSToastStyle`. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +/** + `CSToastManager` provides general configuration options for all toast + notifications. Backed by a singleton instance. + */ +@interface CSToastManager : NSObject + +/** + Sets the shared style on the singleton. The shared style is used whenever + a `makeToast:` method (or `toastViewForMessage:title:image:style:`) is called + with with a nil style. By default, this is set to `CSToastStyle`'s default + style. + + @param sharedStyle the shared style + */ ++ (void)setSharedStyle:(CSToastStyle *)sharedStyle; + +/** + Gets the shared style from the singlton. By default, this is + `CSToastStyle`'s default style. + + @return the shared style + */ ++ (CSToastStyle *)sharedStyle; + +/** + Enables or disables tap to dismiss on toast views. Default is `YES`. + + @param tapToDismissEnabled YES or NO + */ ++ (void)setTapToDismissEnabled:(BOOL)tapToDismissEnabled; + +/** + Returns `YES` if tap to dismiss is enabled, otherwise `NO`. + Default is `YES`. + + @return BOOL YES or NO + */ ++ (BOOL)isTapToDismissEnabled; + +/** + Enables or disables queueing behavior for toast views. When `YES`, + toast views will appear one after the other. When `NO`, multiple Toast + views will appear at the same time (potentially overlapping depending + on their positions). This has no effect on the toast activity view, + which operates independently of normal toast views. Default is `NO`. + + @param queueEnabled YES or NO + */ ++ (void)setQueueEnabled:(BOOL)queueEnabled; + +/** + Returns `YES` if the queue is enabled, otherwise `NO`. + Default is `NO`. + + @return BOOL + */ ++ (BOOL)isQueueEnabled; + +/** + Sets the default duration. Used for the `makeToast:` and + `showToast:` methods that don't require an explicit duration. + Default is 3.0. + + @param duration The toast duration + */ ++ (void)setDefaultDuration:(NSTimeInterval)duration; + +/** + Returns the default duration. Default is 3.0. + + @return duration The toast duration +*/ ++ (NSTimeInterval)defaultDuration; + +/** + Sets the default position. Used for the `makeToast:` and + `showToast:` methods that don't require an explicit position. + Default is `CSToastPositionBottom`. + + @param position The default center point. Can be one of the predefined + CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. + */ ++ (void)setDefaultPosition:(id)position; + +/** + Returns the default toast position. Default is `CSToastPositionBottom`. + + @return position The default center point. Will be one of the predefined + CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object. + */ ++ (id)defaultPosition; + +@end diff --git a/AppRunMan/server/UIView+Toast.m b/AppRunMan/server/UIView+Toast.m new file mode 100755 index 0000000..e355019 --- /dev/null +++ b/AppRunMan/server/UIView+Toast.m @@ -0,0 +1,586 @@ +// +// UIView+Toast.m +// Toast +// +// Copyright (c) 2011-2024 Charles Scalesse. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#import "UIView+Toast.h" +#import +#import + +// Positions +NSString * CSToastPositionTop = @"CSToastPositionTop"; +NSString * CSToastPositionCenter = @"CSToastPositionCenter"; +NSString * CSToastPositionBottom = @"CSToastPositionBottom"; + +// Keys for values associated with toast views +static const NSString * CSToastTimerKey = @"CSToastTimerKey"; +static const NSString * CSToastDurationKey = @"CSToastDurationKey"; +static const NSString * CSToastPositionKey = @"CSToastPositionKey"; +static const NSString * CSToastCompletionKey = @"CSToastCompletionKey"; + +// Keys for values associated with self +static const NSString * CSToastActiveKey = @"CSToastActiveKey"; +static const NSString * CSToastActivityViewKey = @"CSToastActivityViewKey"; +static const NSString * CSToastQueueKey = @"CSToastQueueKey"; + +@interface UIView (ToastPrivate) + +/** + These private methods are being prefixed with "cs_" to reduce the likelihood of non-obvious + naming conflicts with other UIView methods. + + @discussion Should the public API also use the cs_ prefix? Technically it should, but it + results in code that is less legible. The current public method names seem unlikely to cause + conflicts so I think we should favor the cleaner API for now. + */ +- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position; +- (void)cs_hideToast:(UIView *)toast; +- (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap; +- (void)cs_toastTimerDidFinish:(NSTimer *)timer; +- (void)cs_handleToastTapped:(UITapGestureRecognizer *)recognizer; +- (CGPoint)cs_centerPointForPosition:(id)position withToast:(UIView *)toast; +- (NSMutableArray *)cs_toastQueue; + +@end + +@implementation UIView (Toast) + +#pragma mark - Make Toast Methods + +- (void)makeToast:(NSString *)message { + [self makeToast:message duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] style:nil]; +} + +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position { + [self makeToast:message duration:duration position:position style:nil]; +} + +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position style:(CSToastStyle *)style { + UIView *toast = [self toastViewForMessage:message title:nil image:nil style:style]; + [self showToast:toast duration:duration position:position completion:nil]; +} + +- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style completion:(void(^)(BOOL didTap))completion { + UIView *toast = [self toastViewForMessage:message title:title image:image style:style]; + [self showToast:toast duration:duration position:position completion:completion]; +} + +#pragma mark - Show Toast Methods + +- (void)showToast:(UIView *)toast { + [self showToast:toast duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] completion:nil]; +} + +- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position completion:(void(^)(BOOL didTap))completion { + // sanity + if (toast == nil) return; + + // store the completion block on the toast view + objc_setAssociatedObject(toast, &CSToastCompletionKey, completion, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + if ([CSToastManager isQueueEnabled] && [self.cs_activeToasts count] > 0) { + // we're about to queue this toast view so we need to store the duration and position as well + objc_setAssociatedObject(toast, &CSToastDurationKey, @(duration), OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(toast, &CSToastPositionKey, position, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + // enqueue + [self.cs_toastQueue addObject:toast]; + } else { + // present + [self cs_showToast:toast duration:duration position:position]; + } +} + +#pragma mark - Hide Toast Methods + +- (void)hideToast { + [self hideToast:[[self cs_activeToasts] firstObject]]; +} + +- (void)hideToast:(UIView *)toast { + // sanity + if (!toast || ![[self cs_activeToasts] containsObject:toast]) return; + + [self cs_hideToast:toast]; +} + +- (void)hideAllToasts { + [self hideAllToasts:NO clearQueue:YES]; +} + +- (void)hideAllToasts:(BOOL)includeActivity clearQueue:(BOOL)clearQueue { + if (clearQueue) { + [self clearToastQueue]; + } + + for (UIView *toast in [self cs_activeToasts]) { + [self hideToast:toast]; + } + + if (includeActivity) { + [self hideToastActivity]; + } +} + +- (void)clearToastQueue { + [[self cs_toastQueue] removeAllObjects]; +} + +#pragma mark - Private Show/Hide Methods + +- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position { + toast.center = [self cs_centerPointForPosition:position withToast:toast]; + toast.alpha = 0.0; + + if ([CSToastManager isTapToDismissEnabled]) { + UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cs_handleToastTapped:)]; + [toast addGestureRecognizer:recognizer]; + toast.userInteractionEnabled = YES; + toast.exclusiveTouch = YES; + } + + [[self cs_activeToasts] addObject:toast]; + + [self addSubview:toast]; + + [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration] + delay:0.0 + options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) + animations:^{ + toast.alpha = 1.0; + } completion:^(BOOL finished) { + NSTimer *timer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(cs_toastTimerDidFinish:) userInfo:toast repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + objc_setAssociatedObject(toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + }]; +} + +- (void)cs_hideToast:(UIView *)toast { + [self cs_hideToast:toast fromTap:NO]; +} + +- (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap { + NSTimer *timer = (NSTimer *)objc_getAssociatedObject(toast, &CSToastTimerKey); + [timer invalidate]; + + [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration] + delay:0.0 + options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) + animations:^{ + toast.alpha = 0.0; + } completion:^(BOOL finished) { + [toast removeFromSuperview]; + + // remove + [[self cs_activeToasts] removeObject:toast]; + + // execute the completion block, if necessary + void (^completion)(BOOL didTap) = objc_getAssociatedObject(toast, &CSToastCompletionKey); + if (completion) { + completion(fromTap); + } + + if ([self.cs_toastQueue count] > 0) { + // dequeue + UIView *nextToast = [[self cs_toastQueue] firstObject]; + [[self cs_toastQueue] removeObjectAtIndex:0]; + + // present the next toast + NSTimeInterval duration = [objc_getAssociatedObject(nextToast, &CSToastDurationKey) doubleValue]; + id position = objc_getAssociatedObject(nextToast, &CSToastPositionKey); + [self cs_showToast:nextToast duration:duration position:position]; + } + }]; +} + +#pragma mark - View Construction + +- (UIView *)toastViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style { + // sanity + if (message == nil && title == nil && image == nil) return nil; + + // default to the shared style + if (style == nil) { + style = [CSToastManager sharedStyle]; + } + + // dynamically build a toast view with any combination of message, title, & image + UILabel *messageLabel = nil; + UILabel *titleLabel = nil; + UIImageView *imageView = nil; + + UIView *wrapperView = [[UIView alloc] init]; + wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); + wrapperView.layer.cornerRadius = style.cornerRadius; + + if (style.displayShadow) { + wrapperView.layer.shadowColor = style.shadowColor.CGColor; + wrapperView.layer.shadowOpacity = style.shadowOpacity; + wrapperView.layer.shadowRadius = style.shadowRadius; + wrapperView.layer.shadowOffset = style.shadowOffset; + } + + wrapperView.backgroundColor = style.backgroundColor; + + if(image != nil) { + imageView = [[UIImageView alloc] initWithImage:image]; + imageView.contentMode = UIViewContentModeScaleAspectFit; + imageView.frame = CGRectMake(style.horizontalPadding, style.verticalPadding, style.imageSize.width, style.imageSize.height); + } + + CGRect imageRect = CGRectZero; + + if(imageView != nil) { + imageRect.origin.x = style.horizontalPadding; + imageRect.origin.y = style.verticalPadding; + imageRect.size.width = imageView.bounds.size.width; + imageRect.size.height = imageView.bounds.size.height; + } + + if (title != nil) { + titleLabel = [[UILabel alloc] init]; + titleLabel.numberOfLines = style.titleNumberOfLines; + titleLabel.font = style.titleFont; + titleLabel.textAlignment = style.titleAlignment; + titleLabel.lineBreakMode = NSLineBreakByTruncatingTail; + titleLabel.textColor = style.titleColor; + titleLabel.backgroundColor = [UIColor clearColor]; + titleLabel.alpha = 1.0; + titleLabel.text = title; + + // size the title label according to the length of the text + CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage); + CGSize expectedSizeTitle = [titleLabel sizeThatFits:maxSizeTitle]; + // UILabel can return a size larger than the max size when the number of lines is 1 + expectedSizeTitle = CGSizeMake(MIN(maxSizeTitle.width, expectedSizeTitle.width), MIN(maxSizeTitle.height, expectedSizeTitle.height)); + titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height); + } + + if (message != nil) { + messageLabel = [[UILabel alloc] init]; + messageLabel.numberOfLines = style.messageNumberOfLines; + messageLabel.font = style.messageFont; + messageLabel.textAlignment = style.messageAlignment; + messageLabel.lineBreakMode = NSLineBreakByTruncatingTail; + messageLabel.textColor = style.messageColor; + messageLabel.backgroundColor = [UIColor clearColor]; + messageLabel.alpha = 1.0; + messageLabel.text = message; + + CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage); + CGSize expectedSizeMessage = [messageLabel sizeThatFits:maxSizeMessage]; + // UILabel can return a size larger than the max size when the number of lines is 1 + expectedSizeMessage = CGSizeMake(MIN(maxSizeMessage.width, expectedSizeMessage.width), MIN(maxSizeMessage.height, expectedSizeMessage.height)); + messageLabel.frame = CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height); + } + + CGRect titleRect = CGRectZero; + + if(titleLabel != nil) { + titleRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding; + titleRect.origin.y = style.verticalPadding; + titleRect.size.width = titleLabel.bounds.size.width; + titleRect.size.height = titleLabel.bounds.size.height; + } + + CGRect messageRect = CGRectZero; + + if(messageLabel != nil) { + messageRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding; + messageRect.origin.y = titleRect.origin.y + titleRect.size.height + style.verticalPadding; + messageRect.size.width = messageLabel.bounds.size.width; + messageRect.size.height = messageLabel.bounds.size.height; + } + + CGFloat longerWidth = MAX(titleRect.size.width, messageRect.size.width); + CGFloat longerX = MAX(titleRect.origin.x, messageRect.origin.x); + + // Wrapper width uses the longerWidth or the image width, whatever is larger. Same logic applies to the wrapper height. + CGFloat wrapperWidth = MAX((imageRect.size.width + (style.horizontalPadding * 2.0)), (longerX + longerWidth + style.horizontalPadding)); + CGFloat wrapperHeight = MAX((messageRect.origin.y + messageRect.size.height + style.verticalPadding), (imageRect.size.height + (style.verticalPadding * 2.0))); + + wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight); + + if(titleLabel != nil) { + titleLabel.frame = titleRect; + [wrapperView addSubview:titleLabel]; + } + + if(messageLabel != nil) { + messageLabel.frame = messageRect; + [wrapperView addSubview:messageLabel]; + } + + if(imageView != nil) { + [wrapperView addSubview:imageView]; + } + + return wrapperView; +} + +#pragma mark - Storage + +- (NSMutableArray *)cs_activeToasts { + NSMutableArray *cs_activeToasts = objc_getAssociatedObject(self, &CSToastActiveKey); + if (cs_activeToasts == nil) { + cs_activeToasts = [[NSMutableArray alloc] init]; + objc_setAssociatedObject(self, &CSToastActiveKey, cs_activeToasts, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return cs_activeToasts; +} + +- (NSMutableArray *)cs_toastQueue { + NSMutableArray *cs_toastQueue = objc_getAssociatedObject(self, &CSToastQueueKey); + if (cs_toastQueue == nil) { + cs_toastQueue = [[NSMutableArray alloc] init]; + objc_setAssociatedObject(self, &CSToastQueueKey, cs_toastQueue, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return cs_toastQueue; +} + +#pragma mark - Events + +- (void)cs_toastTimerDidFinish:(NSTimer *)timer { + [self cs_hideToast:(UIView *)timer.userInfo]; +} + +- (void)cs_handleToastTapped:(UITapGestureRecognizer *)recognizer { + UIView *toast = recognizer.view; + NSTimer *timer = (NSTimer *)objc_getAssociatedObject(toast, &CSToastTimerKey); + [timer invalidate]; + + [self cs_hideToast:toast fromTap:YES]; +} + +#pragma mark - Activity Methods + +- (void)makeToastActivity:(id)position { + // sanity + UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); + if (existingActivityView != nil) return; + + CSToastStyle *style = [CSToastManager sharedStyle]; + + UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, style.activitySize.width, style.activitySize.height)]; + activityView.center = [self cs_centerPointForPosition:position withToast:activityView]; + activityView.backgroundColor = style.backgroundColor; + activityView.alpha = 0.0; + activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); + activityView.layer.cornerRadius = style.cornerRadius; + + if (style.displayShadow) { + activityView.layer.shadowColor = style.shadowColor.CGColor; + activityView.layer.shadowOpacity = style.shadowOpacity; + activityView.layer.shadowRadius = style.shadowRadius; + activityView.layer.shadowOffset = style.shadowOffset; + } + + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge]; + activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2); + [activityView addSubview:activityIndicatorView]; + [activityIndicatorView startAnimating]; + + // associate the activity view with self + objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + [self addSubview:activityView]; + + [UIView animateWithDuration:style.fadeDuration + delay:0.0 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + activityView.alpha = 1.0; + } completion:nil]; +} + +- (void)hideToastActivity { + UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); + if (existingActivityView != nil) { + [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration] + delay:0.0 + options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) + animations:^{ + existingActivityView.alpha = 0.0; + } completion:^(BOOL finished) { + [existingActivityView removeFromSuperview]; + objc_setAssociatedObject (self, &CSToastActivityViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + }]; + } +} + +#pragma mark - Helpers + +- (CGPoint)cs_centerPointForPosition:(id)point withToast:(UIView *)toast { + CSToastStyle *style = [CSToastManager sharedStyle]; + + UIEdgeInsets safeInsets = UIEdgeInsetsZero; + if (@available(iOS 11.0, *)) { + safeInsets = self.safeAreaInsets; + } + + CGFloat topPadding = style.verticalPadding + safeInsets.top; + CGFloat bottomPadding = style.verticalPadding + safeInsets.bottom; + + if([point isKindOfClass:[NSString class]]) { + if([point caseInsensitiveCompare:CSToastPositionTop] == NSOrderedSame) { + return CGPointMake(self.bounds.size.width / 2.0, (toast.frame.size.height / 2.0) + topPadding); + } else if([point caseInsensitiveCompare:CSToastPositionCenter] == NSOrderedSame) { + return CGPointMake(self.bounds.size.width / 2.0, self.bounds.size.height / 2.0); + } + } else if ([point isKindOfClass:[NSValue class]]) { + return [point CGPointValue]; + } + + // default to bottom + return CGPointMake(self.bounds.size.width / 2.0, (self.bounds.size.height - (toast.frame.size.height / 2.0)) - bottomPadding); +} + +@end + +@implementation CSToastStyle + +#pragma mark - Constructors + +- (instancetype)initWithDefaultStyle { + self = [super init]; + if (self) { + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8]; + self.titleColor = [UIColor whiteColor]; + self.messageColor = [UIColor whiteColor]; + self.maxWidthPercentage = 0.8; + self.maxHeightPercentage = 0.8; + self.horizontalPadding = 10.0; + self.verticalPadding = 10.0; + self.cornerRadius = 10.0; + self.titleFont = [UIFont boldSystemFontOfSize:16.0]; + self.messageFont = [UIFont systemFontOfSize:16.0]; + self.titleAlignment = NSTextAlignmentLeft; + self.messageAlignment = NSTextAlignmentLeft; + self.titleNumberOfLines = 0; + self.messageNumberOfLines = 0; + self.displayShadow = NO; + self.shadowOpacity = 0.8; + self.shadowRadius = 6.0; + self.shadowOffset = CGSizeMake(4.0, 4.0); + self.imageSize = CGSizeMake(80.0, 80.0); + self.activitySize = CGSizeMake(100.0, 100.0); + self.fadeDuration = 0.2; + } + return self; +} + +- (void)setMaxWidthPercentage:(CGFloat)maxWidthPercentage { + _maxWidthPercentage = MAX(MIN(maxWidthPercentage, 1.0), 0.0); +} + +- (void)setMaxHeightPercentage:(CGFloat)maxHeightPercentage { + _maxHeightPercentage = MAX(MIN(maxHeightPercentage, 1.0), 0.0); +} + +- (instancetype)init NS_UNAVAILABLE { + return nil; +} + +@end + +@interface CSToastManager () + +@property (strong, nonatomic) CSToastStyle *sharedStyle; +@property (assign, nonatomic, getter=isTapToDismissEnabled) BOOL tapToDismissEnabled; +@property (assign, nonatomic, getter=isQueueEnabled) BOOL queueEnabled; +@property (assign, nonatomic) NSTimeInterval defaultDuration; +@property (strong, nonatomic) id defaultPosition; + +@end + +@implementation CSToastManager + +#pragma mark - Constructors + ++ (instancetype)sharedManager { + static CSToastManager *_sharedManager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + _sharedManager = [[self alloc] init]; + }); + + return _sharedManager; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.sharedStyle = [[CSToastStyle alloc] initWithDefaultStyle]; + self.tapToDismissEnabled = YES; + self.queueEnabled = NO; + self.defaultDuration = 3.0; + self.defaultPosition = CSToastPositionBottom; + } + return self; +} + +#pragma mark - Singleton Methods + ++ (void)setSharedStyle:(CSToastStyle *)sharedStyle { + [[self sharedManager] setSharedStyle:sharedStyle]; +} + ++ (CSToastStyle *)sharedStyle { + return [[self sharedManager] sharedStyle]; +} + ++ (void)setTapToDismissEnabled:(BOOL)tapToDismissEnabled { + [[self sharedManager] setTapToDismissEnabled:tapToDismissEnabled]; +} + ++ (BOOL)isTapToDismissEnabled { + return [[self sharedManager] isTapToDismissEnabled]; +} + ++ (void)setQueueEnabled:(BOOL)queueEnabled { + [[self sharedManager] setQueueEnabled:queueEnabled]; +} + ++ (BOOL)isQueueEnabled { + return [[self sharedManager] isQueueEnabled]; +} + ++ (void)setDefaultDuration:(NSTimeInterval)duration { + [[self sharedManager] setDefaultDuration:duration]; +} + ++ (NSTimeInterval)defaultDuration { + return [[self sharedManager] defaultDuration]; +} + ++ (void)setDefaultPosition:(id)position { + if ([position isKindOfClass:[NSString class]] || [position isKindOfClass:[NSValue class]]) { + [[self sharedManager] setDefaultPosition:position]; + } +} + ++ (id)defaultPosition { + return [[self sharedManager] defaultPosition]; +} + +@end diff --git a/AppRunMan/server/XSHackIos.h b/AppRunMan/server/XSHackIos.h new file mode 100644 index 0000000..ea0a827 --- /dev/null +++ b/AppRunMan/server/XSHackIos.h @@ -0,0 +1,129 @@ +// +// XSHackIos.h +// nochange +// +// Created by mac on 2024/10/15. +// + +#ifndef XSHackIos_h +#define XSHackIos_h + +#import +#include +#include +#include +#include +#import +#include +#import +#import +#import +#import +#include +#import + + + +typedef struct __SecTask *SecTaskRef; +typedef struct __SecTrust *SecTrustRef; + +// 定义私有 API +@interface SecTask : NSObject ++ (SecTaskRef)createWithAuditToken:(audit_token_t)token; ++ (SecTaskRef)createWithPID:(pid_t)pid; +- (CFTypeRef)copyValueForEntitlement:(CFStringRef)entitlement error:(CFErrorRef*)error; +@end + + +OBJC_EXTERN UIImage *_UICreateScreenUIImage(void); +OBJC_EXTERN void CARenderServerRenderDisplay(kern_return_t a, CFStringRef b, IOSurfaceRef surface, int x, int y); +OBJC_EXTERN kern_return_t IOSurfaceLock(IOSurfaceRef buffer, IOSurfaceLockOptions options, uint32_t *seed); +OBJC_EXTERN kern_return_t IOSurfaceUnLock(IOSurfaceRef buffer, IOSurfaceLockOptions options, uint32_t *seed); +OBJC_EXTERN IOSurfaceRef IOSurfaceCreate(CFDictionaryRef dictionary); +OBJC_EXTERN CGImageRef UICreateCGImageFromIOSurface(IOSurfaceRef surface); +OBJC_EXTERN SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef); +OBJC_EXTERN CFTypeRef SecTaskCopyValueForEntitlement(SecTaskRef, CFStringRef entitlement, CFErrorRef*); +// 定义函数指针类型 +// 定义函数指针类型 +typedef Boolean (*SecTaskSetEntitlementsPtr)(SecTaskRef task, CFDictionaryRef entitlements); + +@interface SBApplication : NSObject { +} +@property (nonatomic, retain, readonly) NSString *displayIdentifier NS_DEPRECATED_IOS(4_0, 8_0); +@property (nonatomic, retain, readonly) NSString *bundleIdentifier NS_AVAILABLE_IOS(8_0); // Technically available in iOS 5 as well (https://github.com/MP0w/iOS-Headers/blob/master/iOS5.0/SpringBoard/SB.h#L143) and even iOS 4, but you probably don't want to use that (see: Camera/Photos). +@property (nonatomic, retain, readonly) NSString *displayName; + +- (void)activate; + +@end + +@interface SBApplicationController : NSObject ++ (id)sharedInstance; +- (SBApplication *)applicationWithBundleIdentifier:(NSString *)bundleID; +@end + +@interface SpringBoard : NSObject +- (NSArray *)activeAlertItems; +- (id)_accessibilityFrontMostApplication; +- (void)_simulateHomeButtonPress; +@end + +@interface UIImage (Private) ++ (UIImage *)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(int)format scale:(CGFloat)scale; +@end + +@interface SBLockScreenManager ++(id)sharedInstance; +-(void)unlockUIFromSource:(int)source withOptions:(id)options; +@property(readonly, assign) BOOL isUILocked; +@end + + +@interface SBUserAgent : NSObject ++ (id)sharedUserAgent; +- (void)lockAndDimDevice; +- (void)undimScreen; +- (void)unlockDevice; +@end + +@interface SBUIController : NSObject ++ (id)sharedInstance; +- (BOOL)isOnLockScreen; +@end + + + +@interface FBSSystemService : NSObject ++ (id)sharedService; +- (void)openApplication:(NSString *)bundleID + options:(NSDictionary *)options + clientPort:(mach_port_t)clientPort + withResult:(void(^)(NSError *error))callback; +@end + + + +int XSRuncmd(char *args[]); + +void XSSystem(const char *cmd); +NSString* XSFrontMostAppId(void); +int XSReboot(void); +int XSKillApp(NSString *appexe); +int XSKillAppByName(NSString *pkgName); +int XSBringAppForeground(NSString *appIdentifier); +void activateApp(NSString *bundleID); +void bringAppToForeground(NSString *bundleID); +UIImage* XSCcaptureScreen2(void); +NSArray* XSGetApps(void); +void XSRemoteUnlock(void); +void XSClearAll(NSString *appId); +NSString* XSGetAppInfoPath(NSString *app); +NSDictionary* XSGetAppInfo(NSString *appInfoPlist); +void XSSaveAppInfo(NSDictionary *dic, NSString *appInfoPath); +BOOL injectEntitlementsWithOptions(NSDictionary *options, NSError **error); +BOOL verifyEntitlement(NSString *entitlementName); +void injectNetworkPermissions(void); +pid_t system2(const char * command, int * infp, int * outfp); + +void getAllButtons(void); +#endif /* XSHackIos_h */ diff --git a/AppRunMan/server/XSHackIos.m b/AppRunMan/server/XSHackIos.m new file mode 100644 index 0000000..b078f0f --- /dev/null +++ b/AppRunMan/server/XSHackIos.m @@ -0,0 +1,1490 @@ +// +// XSHackIos.m +// nochange +// +// Created by mac on 2024/10/15. +// + +#import +#import +#include +#include +#include +#include +#import +#include +#include + +#import "XSHelper.h" +#import "XSHackIos.h" +#import "XSPhoneConfig.h" +#import "XSPhoneInfo.h" +/** +获取当前应用 + */ +SBApplication* XSGetFrontMostApplication(void) +{ + //TODO: might cause problem here. Both _accessibilityFrontMostApplication failed or front most application springboard will cause app be nil. + __block id app = nil; + NSLog(@"XS- getFrontMostApplication"); + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + dispatch_sync(dispatch_get_main_queue(), ^{ + @try{ + + SpringBoard *springboard = (SpringBoard *)[UIApplication sharedApplication]; + //SpringBoard *springboard = (SpringBoard*)[%c(SpringBoard) sharedApplication]; + if ([springboard respondsToSelector:@selector(_accessibilityFrontMostApplication)]) { + app = [springboard performSelector:@selector(_accessibilityFrontMostApplication)]; + NSLog(@"XS- Simulated home button press, %@", app); + } + // app = [springboard _accessibilityFrontMostApplication]; + //NSLog(@"com.zjx.springboard: app: %@, id: %@", app, [app displayIdentifier]); + + } + @catch (NSException *exception) { + NSLog(@"XS-: Debug: %@", exception.reason); + } + dispatch_semaphore_signal(semaphore); + }); + // 设置超时时间为5秒 + dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC); + + // 等待信号量,最多等待5秒 + long result = dispatch_semaphore_wait(semaphore, timeout); + + if (result == 0) { + // 在超时之前收到了信号 + NSLog(@"XSGetFrontMostApplication end"); + } else { + // 超时 + NSLog(@"XSGetFrontMostApplication 等待超时"); + } + + return app; +} + + +NSString* XSFrontMostAppId(void) { + SBApplication* sbapp = XSGetFrontMostApplication(); + if (sbapp == nil || [sbapp isEqual:[NSNull null]]) { + return @""; + } + return sbapp.bundleIdentifier; +} + + +extern char **environ; +//执行系统命令 +int XSRuncmd(char *args[]) +{ + printf("XSRuncmd: args "); + for (int i = 0; args[i] != NULL; i++) { + printf("%s ", args[i]); + } + printf("\n"); + + posix_spawnattr_t attr; + posix_spawn_file_actions_t fact; + pid_t pid; + + posix_spawnattr_init(&attr); + posix_spawn_file_actions_init(&fact); + posix_spawn(&pid,args[0], NULL, NULL,args,environ); + perror("posix_spawn"); + NSLog(@"XS- pid=%d,child pid = %d\n",getpid(),pid); + int stat=0; + waitpid(pid,&stat,0); + NSLog(@"XS- stat is %d\n",stat); + return pid; +} + +int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf){ + int rv = remove(fpath); + if (rv) + perror(fpath); + + return rv; +} + +void XSSystem(const char *cmd) { + int stat = nftw(cmd, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); + NSLog(@"nftw res: %d", stat); +} + + +NSString* XSGetAppExecutable(NSString *pkgName) { + + //获取应用程序列表 + Class cls = NSClassFromString(@"LSApplicationWorkspace"); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id s = [(id)cls performSelector:NSSelectorFromString(@"defaultWorkspace")]; + NSArray *array = [s performSelector:NSSelectorFromString(@"allApplications")]; +#pragma clang diagnostic pop + + Class LSApplicationProxy_class = NSClassFromString(@"LSApplicationProxy"); + + for (LSApplicationProxy_class in array) { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + NSString *res = [LSApplicationProxy_class performSelector:@selector(applicationIdentifier)]; + //NSString *strBundleID = [LSApplicationProxy_class performSelector:@selector(bundleIdentifier)]; +#pragma clang diagnostic pop + // localizedName + + if ([res isEqualToString:pkgName]) { + NSURL * bundleFullURL = [LSApplicationProxy_class performSelector:@selector(bundleURL)]; + NSString * s_bundleURL = [bundleFullURL absoluteString]; + + NSString *prefix = @"file://"; + NSRange needleRange = NSMakeRange(prefix.length, + s_bundleURL.length - prefix.length ); + NSString *needle = [s_bundleURL substringWithRange:needleRange]; + NSBundle *bundle = [NSBundle bundleWithPath:needle]; + NSString* executable = [[bundle infoDictionary] valueForKeyPath:@"CFBundleExecutable"]; + return executable; + + } + + } + return nil; +} + +int XSReboot(void) { + char *argv[] = { + "/usr/sbin/reboot", + NULL + }; + int r = XSRuncmd(argv); + + return r; +} + +int XSKillApp(NSString *appexe) { + if(appexe) { + const char* app = [appexe UTF8String]; + char *appStr = strdup(app); + char *argv[] = { + "/usr/bin/killall", + "-9", + appStr, + NULL + }; + int r = XSRuncmd(argv); + free(appStr); + return r; + } + return 0; +} + +int kill2(NSString *appexe) { + NSString *cmd = [NSString stringWithFormat:@"/usr/bin/killall -9 %@", appexe]; + const char* app = [cmd UTF8String]; + char *appStr = strdup(app); + int r = system2(appStr, NULL, NULL); + free(appStr); + return r; +} + + +int XSKillAppByName(NSString *pkgName){ + NSString* appexe = XSGetAppExecutable(pkgName); + return kill2(appexe); +} + + +int (*_XSOpenApp)(CFStringRef, Boolean); + +int XSBringAppForeground(NSString *appIdentifier) +{ + void* sbServices = dlopen("/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices", RTLD_LAZY); + CFStringRef appBundleName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), appIdentifier); + //[NSString stringWithFormat:@"%s", eventData]; + NSLog(@"XS-: Switch to application: %@", appBundleName); + if (!_XSOpenApp) { + _XSOpenApp = (int(*)(CFStringRef, Boolean))dlsym(sbServices,"SBSLaunchApplicationWithIdentifier"); + } + return _XSOpenApp(appBundleName, false); +} + +void bringAppToForeground(NSString *bundleID) { + @autoreleasepool { + Class FBSSystemServiceClass = NSClassFromString(@"FBSSystemService"); + if (FBSSystemServiceClass) { + id service = [FBSSystemServiceClass sharedService]; + NSDictionary *options = @{ + @"BSLaunchOrigin": @"SpringBoard", + @"BSSuspended": @NO, + }; + + [service openApplication:bundleID + options:options + clientPort:0 + withResult:^(NSError *error) { + if (error) { + NSLog(@"Failed to bring app to foreground: %@", error); + } + }]; + } + } +} + +void activateApp(NSString *bundleID){ + // 这个方法不行 + Class SBApplicationControllerClass = NSClassFromString(@"SBApplicationController"); + if (SBApplicationControllerClass) { + id controller = [SBApplicationControllerClass sharedInstance]; + id app = [controller applicationWithBundleIdentifier:bundleID]; + if ([app respondsToSelector:@selector(activate)]) { + [app activate]; + } + } +} + + + +void XSRemoteUnlock(void) { + // 获取 SBLockScreenManager 的共享实例 + + // 获取 SBUIController 实例 + @autoreleasepool { + Class sbUIControllerClass = objc_getClass("SBUIController"); + id sbUIController = [sbUIControllerClass performSelector:@selector(sharedInstance)]; + + // 检查设备是否在锁屏状态 + if ([sbUIController respondsToSelector:@selector(isOnLockScreen)]) { + BOOL isLocked = [sbUIController performSelector:@selector(isOnLockScreen)]; + + if (isLocked) { + // 模拟滑动解锁(对于没有密码的设备) + CGPoint startPoint = CGPointMake(50, CGRectGetMidY([UIScreen mainScreen].bounds)); + CGPoint endPoint = CGPointMake(CGRectGetMaxX([UIScreen mainScreen].bounds) - 50, CGRectGetMidY([UIScreen mainScreen].bounds)); + + UITouch *touch = [[UITouch alloc] init]; + [touch setValue:[NSValue valueWithCGPoint:startPoint] forKey:@"_locationInWindow"]; + + UIEvent *event = [[UIEvent alloc] init]; + [event setValue:@(UIEventTypeTouches) forKey:@"_type"]; + [event setValue:[NSSet setWithObject:touch] forKey:@"_touches"]; + + [[UIApplication sharedApplication] sendEvent:event]; + + [touch setValue:[NSValue valueWithCGPoint:endPoint] forKey:@"_locationInWindow"]; + [[UIApplication sharedApplication] sendEvent:event]; + + // 对于有密码的设备,还需要模拟输入密码 + // 这部分代码会更复杂,需要模拟点击数字键盘 + + NSLog(@"Simulated unlock gesture"); + } else { + NSLog(@"Device is not locked"); + } + } else { + NSLog(@"Unable to determine lock state"); + } + + // 模拟按下 Home 键 + SpringBoard *springboard = (SpringBoard *)[UIApplication sharedApplication]; + if ([springboard respondsToSelector:@selector(_simulateHomeButtonPress)]) { + [springboard performSelector:@selector(_simulateHomeButtonPress)]; + NSLog(@"Simulated home button press"); + } + } + + /* + Class lockScreenManagerClass = objc_getClass("SBLockScreenManager"); + if (lockScreenManagerClass) { + id lockScreenManager = [lockScreenManagerClass performSelector:@selector(sharedInstance)]; + // 获取 SBUserAgent 的共享实例 + Class userAgentClass = objc_getClass("SBUserAgent"); + id userAgent = [userAgentClass performSelector:@selector(sharedUserAgent)]; + + if (lockScreenManager && userAgent) { + + // 调用解锁方法 + if ([lockScreenManager performSelector:@selector(isUILocked)]) { + [lockScreenManager performSelector:@selector(unlockUIFromSource:withOptions:) + withObject:@(1) + withObject:nil]; + + // 尝试唤醒屏幕 + [userAgent performSelector:@selector(undimScreen)]; + + // 尝试解锁设备 + [userAgent performSelector:@selector(unlockDevice)]; + + NSLog(@"-ad -log- Unlock command sent"); + }else { + NSLog(@"-ad log- No lock"); + } + } else { + NSLog(@"Unable to get LockScreenManager"); + } + } else { + NSLog(@"-ad log- NO SBLockScreenManager"); + } + */ +} + +NSString* getDeviceName(void) +{ + struct utsname systemInfo; + uname(&systemInfo); + + return [NSString stringWithCString:systemInfo.machine + encoding:NSUTF8StringEncoding]; +} +/* +round up number by multiple of another number +*/ +int roundUp(int numToRound, int multiple) +{ + if (multiple == 0) + return numToRound; + + int remainder = numToRound % multiple; + if (remainder == 0) + return numToRound; + + return numToRound + multiple - remainder; +} + +CGImageRef createScreenShotCGImageRef(void) +{ + Boolean isiPad8orUp = false; + + CGFloat scale = [UIScreen mainScreen].scale; + CGSize screenSize = [UIScreen mainScreen].bounds.size; + + int height = (int)(screenSize.height * scale); + int width = (int)(screenSize.width * scale); + + // check whether it is ipad8 or later + NSString *searchText = getDeviceName(); + + NSRange range = [searchText rangeOfString:@"^iPad[8-9]|iPad[1-9][0-9]+" options:NSRegularExpressionSearch]; + if (range.location != NSNotFound) { // ipad pro (3rd) or later + isiPad8orUp = true; + } + + if (isiPad8orUp) + { + if (width < height) + { + int temp = width; + width = height; + height = temp; + } + } + else + { + if (width > height) + { + int temp = width; + width = height; + height = temp; + } + } + + int bytesPerElement = 4; + int bytesPerRow = roundUp(bytesPerElement * width, 32); + + NSNumber *IOSurfaceBytesPerElement = [NSNumber numberWithInteger:bytesPerElement]; + NSNumber *IOSurfaceBytesPerRow = [NSNumber numberWithInteger:bytesPerRow]; // don't know why but it should be a multiple of 32 + NSNumber *IOSurfaceAllocSize = [NSNumber numberWithInteger:bytesPerRow * height]; + NSNumber *nheight = [NSNumber numberWithInteger:height]; + NSNumber *nwidth = [NSNumber numberWithInteger:width]; + NSNumber *IOSurfacePixelFormat = [NSNumber numberWithInteger:1111970369]; + NSNumber *IOSurfaceIsGlobal = [NSNumber numberWithInteger:1]; + + NSDictionary *properties = [[NSDictionary alloc] initWithObjectsAndKeys:IOSurfaceAllocSize, @"IOSurfaceAllocSize" + , IOSurfaceBytesPerElement, @"IOSurfaceBytesPerElement", IOSurfaceBytesPerRow, @"IOSurfaceBytesPerRow", nheight, @"IOSurfaceHeight", + IOSurfaceIsGlobal, @"IOSurfaceIsGlobal", IOSurfacePixelFormat, @"IOSurfacePixelFormat", nwidth, @"IOSurfaceWidth", nil]; + + IOSurfaceRef screenSurface = IOSurfaceCreate((__bridge CFDictionaryRef)(properties)); + + properties = nil; + + IOSurfaceLock(screenSurface, 0, NULL); + CARenderServerRenderDisplay(0, CFSTR("LCD"), screenSurface, 0, 0); + + CGImageRef cgImageRef = nil; + if (screenSurface) { + cgImageRef = UICreateCGImageFromIOSurface(screenSurface); + int targetWidth = CGImageGetWidth(cgImageRef); + int targetHeight = CGImageGetHeight(cgImageRef); + + if (isiPad8orUp) // rotate 90 degrees counterclockwise + { + CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(cgImageRef); + CGContextRef bitmap; + + //if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) { + bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(cgImageRef), CGImageGetBytesPerRow(cgImageRef), colorSpaceInfo, kCGImageAlphaPremultipliedFirst); + //} else { + //bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(cgImageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); + + //} + + CGFloat degrees = -90.f; + CGFloat radians = degrees * (M_PI / 180.f); + + CGContextTranslateCTM (bitmap, 0.5*targetHeight, 0.5*targetWidth); + CGContextRotateCTM (bitmap, radians); + CGContextTranslateCTM (bitmap, -0.5*targetWidth, -0.5*targetHeight); + + CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), cgImageRef); + + CGImageRelease(cgImageRef); + cgImageRef = CGBitmapContextCreateImage(bitmap); + + CGColorSpaceRelease(colorSpaceInfo); + CGContextRelease(bitmap); + } + } + IOSurfaceUnlock(screenSurface, 0, NULL); + CFRelease(screenSurface); + screenSurface = nil; + + return cgImageRef; +} + +UIImage* XSCcaptureScreen2(void) { + CGImageRef cgImage = createScreenShotCGImageRef(); + UIImage *uiImage = [UIImage imageWithCGImage:cgImage]; + NSLog(@"img2:%@", uiImage); + CFRelease(cgImage); + return uiImage; +} + + +UIImage* XSCaptureScreen(void) { + NSLog(@"captureScreen"); + UIImage* res = _UICreateScreenUIImage(); + NSLog(@"img1:%@", res); + if (res && res != nil && ![res isEqual:[NSNull null]]) { + return res; + } + return XSCcaptureScreen2(); +} + +UIImage* defaultIconWithSize (CGSize size, NSString *appName) { + UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + + // 使用随机颜色填充矩形 + CGFloat hue = (CGFloat)arc4random() / UINT32_MAX; + UIColor *color = [UIColor colorWithHue:hue saturation:0.5 brightness:0.8 alpha:1.0]; + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); + + // 可选:添加应用名称的首字母 + NSString *initial = [[appName substringToIndex:1] uppercaseString]; + UIColor *textColor = [UIColor whiteColor]; + NSDictionary *attributes = @{ + NSFontAttributeName: [UIFont boldSystemFontOfSize:size.width * 0.6], + NSForegroundColorAttributeName: textColor + }; + CGSize textSize = [initial sizeWithAttributes:attributes]; + CGPoint textPoint = CGPointMake((size.width - textSize.width) / 2, + (size.height - textSize.height) / 2); + [initial drawAtPoint:textPoint withAttributes:attributes]; + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; +} + +NSArray* XSGetApps(void){ + + NSMutableArray *appInfoArray = [NSMutableArray array]; + //获取应用程序列表 + Class cls = NSClassFromString(@"LSApplicationWorkspace"); + id s = [(id)cls performSelector:NSSelectorFromString(@"defaultWorkspace")]; + NSArray *array = [s performSelector:NSSelectorFromString(@"allApplications")]; + Class LSApplicationProxy_class = NSClassFromString(@"LSApplicationProxy"); + + for (LSApplicationProxy_class in array){ + + NSString * applicationIdentifier = [LSApplicationProxy_class performSelector:@selector(applicationIdentifier)]; + + NSString *strBundleID = [LSApplicationProxy_class performSelector:@selector(bundleIdentifier)]; + NSString *localizedName = [LSApplicationProxy_class performSelector:@selector(localizedName)]; + // localizedName + //获取应用的相关信息 + NSString *strVersion = [LSApplicationProxy_class performSelector:@selector(bundleVersion)]; + NSString *strShortVersion = [LSApplicationProxy_class performSelector:@selector(shortVersionString)]; + NSURL * bundleFullURL = [LSApplicationProxy_class performSelector:@selector(bundleURL)]; + NSString * s_bundleURL = [bundleFullURL absoluteString]; + + NSURL *strContainerURL = [LSApplicationProxy_class performSelector:@selector(containerURL)]; + NSString *strContainerDataPath = [strContainerURL path]; + + if ([s_bundleURL hasPrefix:@"file:///private/"]){ + + + NSString *prefix = @"file://"; + NSRange needleRange = NSMakeRange(prefix.length, + s_bundleURL.length - prefix.length ); + + NSString *needle = [s_bundleURL substringWithRange:needleRange]; + + NSBundle *bundle = [NSBundle bundleWithPath:needle]; + + NSString* executable = [[bundle infoDictionary] valueForKeyPath:@"CFBundleExecutable"]; + + } + UIImage *icon = nil; + + // 方法1: 尝试从bundle中获取图标 + NSBundle *appBundle = [NSBundle bundleWithIdentifier:applicationIdentifier]; + if (appBundle) { + NSString *iconPath = [appBundle pathForResource:@"AppIcon60x60" ofType:@"png"]; + if (iconPath) { + icon = [UIImage imageWithContentsOfFile:iconPath]; + } + } + + // 方法2: 如果方法1失败,尝试使用UIApplication的私有API + if (!icon) { + UIApplication *application = [UIApplication sharedApplication]; + if ([application respondsToSelector:@selector(_iconDataForBundleIdentifier:)]) { + NSData *iconData = [application performSelector:@selector(_iconDataForBundleIdentifier:) withObject:applicationIdentifier]; + if (iconData) { + icon = [UIImage imageWithData:iconData]; + } + } + } + // 尝试使用_applicationIconImageForBundleIdentifier:获取图标 + if ([UIImage respondsToSelector:@selector(_applicationIconImageForBundleIdentifier:format:scale:)]) { + icon = [UIImage _applicationIconImageForBundleIdentifier:applicationIdentifier format:10 scale:[UIScreen mainScreen].scale]; + } + + if (!icon) { + // 使用默认图标 + icon = defaultIconWithSize(CGSizeMake(60, 60), localizedName); + } + + NSString *logInfo = [NSString stringWithFormat:@"bundleId:%@,name:%@,containerPath:%@,version:%@,shortVersion:%@,icon:%@", strBundleID, localizedName, strContainerDataPath, strVersion, strShortVersion, icon]; + NSLog(@"%@", logInfo); + NSDictionary *dic = @{ + @"bundleId": applicationIdentifier ?: @"", + @"name": localizedName ?: @"", + @"containerPath": strContainerDataPath ?: @"", + @"version": strVersion ?: @"", + @"shortVersion": strShortVersion ?: @"", + @"icon": icon ?: [NSNull null] + }; + + + [appInfoArray addObject:dic]; + } + + return [appInfoArray copy]; +} + + + +void XSCleanSafariHistory(void) { + NSString *historyPath = @"/var/mobile/Library/Safari/History.db"; + sqlite3 *database; + + if (sqlite3_open([historyPath UTF8String], &database) == SQLITE_OK) { + char *errMsg; + const char *sql = "DELETE FROM history_items; DELETE FROM history_visits; VACUUM;"; + + if (sqlite3_exec(database, sql, NULL, NULL, &errMsg) != SQLITE_OK) { + NSLog(@"Error cleaning Safari history: %s", errMsg); + sqlite3_free(errMsg); + } else { + NSLog(@"Safari history cleaned successfully"); + } + sqlite3_close(database); + } else { + NSLog(@"Unable to open database"); + } +} + + + +/** + 清楚safari数据 + */ +void XSCleanSafari(void) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + + // 清理 Safari 缓存 + NSString *safariCachePath = @"/var/mobile/Library/Caches/com.apple.mobilesafari"; + [XSHelper rmFiles:safariCachePath]; + + NSString *safariSafePath = @"/var/mobile/Library/Caches/com.apple.Safari.SafeBrowsing"; + [XSHelper rmFiles:safariSafePath]; + // 清理 Safari 的 WebKit 缓存 + NSString *webKitCachePath = @"/var/mobile/Library/WebKit/com.apple.mobilesafari"; + [XSHelper rmFiles:webKitCachePath]; + + + // 清理 Safari 历史记录 + // cleanSafariHistory(); + /* + NSString *historyPath = @"/var/mobile/Library/Safari/History.db"; + [fileManager removeItemAtPath:historyPath error:&error]; + if (error) { + NSLog(@"Error clearing Safari history: %@", error.localizedDescription); + } + */ + NSString *historyPath = @"/var/mobile/Library/Safari"; + [XSHelper rmFiles:historyPath]; + // 清理 Safari Cookies + NSString *cookiesPath = @"/var/mobile/Library/Cookies/Cookies.binarycookies"; + [XSHelper rmFiles:cookiesPath]; + + NSLog(@"Safari data cleared successfully"); + + NSFileManager *man = [NSFileManager defaultManager]; + // 清理cookie + NSString *cookiepath = @"/var/mobile/Library/Cookies"; + + [XSHelper rmFiles:cookiepath]; + + cookiepath = @"/private/var/root/Library/Cookies"; + + [XSHelper rmFiles:cookiepath]; + + + // 获取safari的沙盒路径 + NSString* safaricontainer = nil; + NSString* installplist = @"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"; + if ([man fileExistsAtPath:installplist]) { + NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile:installplist]; + id obj = plist[@"User"][@"com.apple.mobilesafari"]; + if (obj == nil) { + obj = plist[@"System"][@"com.apple.mobilesafari"]; + } + if (obj != nil) { + safaricontainer = obj[@"Container"]; + } + } else { + Class LSApplicationProxy_cls = objc_getClass("LSApplicationProxy"); + id obj = [LSApplicationProxy_cls performSelector:@selector(applicationProxyForIdentifier:) withObject:@"com.apple.mobilesafari"]; + + if (obj != nil && [obj respondsToSelector:@selector(dataContainerURL)]) { + safaricontainer = [[obj performSelector:@selector(dataContainerURL)] path]; + } + } + if(safaricontainer) { + // 清理library + NSString* libpath = [safaricontainer stringByAppendingPathComponent:@"Library"]; + NSString* libcachepath = [libpath stringByAppendingPathComponent:@"Caches"]; + [XSHelper rmFiles:libcachepath]; + } + +} + + + +void XSCleanKeychain(void) { + NSFileManager* man = [NSFileManager defaultManager]; + if ([man fileExistsAtPath:@"/var/Keychains/keychain-2.db"]) { + + /* + char *cpCmd = "/usr/bin/cp"; + if ([man fileExistsAtPath:@"/bin/cp"]) { + cpCmd = "/bin/cp"; + } + + char *cmds[] = { + cpCmd, + "/var/Keychains/keychain-2.db", + "/tmp/", + NULL + }; + */ + // XSRuncmd(cmds); + + XSSystem("cp /var/Keychains/keychain-2.db /tmp/"); + sqlite3* ppDb; + char cmd[256]; + if (0 == sqlite3_open("/tmp/keychain-2.db", &ppDb)) { + strcpy(cmd, "DELETE FROM cert WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'"); + sqlite3_exec(ppDb, cmd, 0, 0, 0); + strcpy(cmd, "DELETE FROM keys WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'"); + sqlite3_exec(ppDb, cmd, 0, 0, 0); + strcpy(cmd, "DELETE FROM inet WHERE agrp<>'apple' and agrp not like '%apple%' and agrp <> 'ichat' and agrp <>'lockdown-identities'"); + sqlite3_exec(ppDb, cmd, 0, 0, 0); + /* + char *cmds1[] = { + cpCmd, + "/tmp/keychain-2.*", + "/var/Keychains/", + NULL + }; + */ + //XSRuncmd(cmds1); + + XSSystem("cp /tmp/keychain-2.* /var/Keychains/"); + } + //free(cpCmd); + } +} + + +void XSCleanPastboard(void) { + UIPasteboard* pb = [UIPasteboard generalPasteboard]; + if (pb != nil) { + NSArray* items = [pb items]; + if (items != nil) { + items = [NSArray array]; + } + [pb setItems:items]; + } + + NSFileManager* man = [NSFileManager defaultManager]; + NSProcessInfo* proc = [NSProcessInfo processInfo]; + BOOL isbe8 = FALSE; + NSOperatingSystemVersion ver; + ver.majorVersion = 8; + ver.minorVersion = 0; + ver.patchVersion = 0; + if ([proc respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)]) { + isbe8 = [proc isOperatingSystemAtLeastVersion:ver]; + } + + NSString* pbplist = nil; + + if ([man fileExistsAtPath:@"/System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"]) { + pbplist = @"/System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"; + //pbbundle = @"com.apple.UIKit.pasteboardd"; + } + else if ([man fileExistsAtPath:@"/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"]) { + pbplist = @"/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist"; + //pbbundle = @"com.apple.UIKit.pasteboardd"; + } + else if ([man fileExistsAtPath:@"/System/Library/LaunchDaemons/com.apple.pasteboard.pasted.plist"]) { + pbplist = @"/System/Library/LaunchDaemons/com.apple.pasteboard.pasted.plist"; + //pbbundle = @"com.apple.pasteboard.pasted"; + } + + // BOOL pbdbexist = [man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard/pasteboardDB"]; + NSString* pbcontainer = nil; + if ([man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard"]) { + pbcontainer = @"/var/mobile/Library/Caches/com.apple.UIKit.pboard"; + } else if ([man fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.Pasteboard"]) { + pbcontainer = @"/var/mobile/Library/Caches/com.apple.Pasteboard"; + } + if (!isbe8 && [man fileExistsAtPath:pbplist]) { + XSSystem("launchctl unload -w"); + } + if (pbcontainer != nil && [man fileExistsAtPath:pbcontainer]) { + NSString* cmd = [NSString stringWithFormat:@"rm -rf %@/*", pbcontainer]; + XSSystem([cmd UTF8String]); + } + +} + + + +NSString* getAppExecutable(NSString *pkgName){ + + //获取应用程序列表 + Class cls = NSClassFromString(@"LSApplicationWorkspace"); + id s = [(id)cls performSelector:NSSelectorFromString(@"defaultWorkspace")]; + NSArray *array = [s performSelector:NSSelectorFromString(@"allApplications")]; + Class LSApplicationProxy_class = NSClassFromString(@"LSApplicationProxy"); + + for (LSApplicationProxy_class in array){ + + NSString * res = [LSApplicationProxy_class performSelector:@selector(applicationIdentifier)]; + + NSString *strBundleID = [LSApplicationProxy_class performSelector:@selector(bundleIdentifier)]; + // localizedName + + if ([res isEqualToString:pkgName]) { + + + NSURL * bundleFullURL = [LSApplicationProxy_class performSelector:@selector(bundleURL)]; + NSString * s_bundleURL = [bundleFullURL absoluteString]; + + if ([s_bundleURL hasPrefix:@"file:///private/"]){ + + + NSString *prefix = @"file://"; + NSRange needleRange = NSMakeRange(prefix.length, + s_bundleURL.length - prefix.length ); + + NSString *needle = [s_bundleURL substringWithRange:needleRange]; + + NSBundle *bundle = [NSBundle bundleWithPath:needle]; + + NSString* executable = [[bundle infoDictionary] valueForKeyPath:@"CFBundleExecutable"]; + return executable; + }} + } + + return nil; +} + + + +NSString* getAppSandboxPath(NSString *app){ + + //获取应用程序列表 + Class cls = NSClassFromString(@"LSApplicationWorkspace"); + id s = [(id)cls performSelector:NSSelectorFromString(@"defaultWorkspace")]; + NSArray *array = [s performSelector:NSSelectorFromString(@"allApplications")]; + Class LSApplicationProxy_class = NSClassFromString(@"LSApplicationProxy"); + + for (LSApplicationProxy_class in array){ + + NSString *strBundleID = [LSApplicationProxy_class performSelector:@selector(bundleIdentifier)]; + + //获取应用的相关信息 + NSString *strVersion = [LSApplicationProxy_class performSelector:@selector(bundleVersion)]; + NSString *strShortVersion = [LSApplicationProxy_class performSelector:@selector(shortVersionString)]; + + NSURL *strContainerURL = [LSApplicationProxy_class performSelector:@selector(containerURL)]; + NSString *strContainerDataPath = [strContainerURL path]; + + + //NSLog(@"bundleID:%@ localizedName: %@", strBundleID, strLocalizedName); + + if ([strBundleID isEqualToString:app]) { + return strContainerDataPath; + } + } + + return nil; +} + +NSString* XSGetAppInfoPath(NSString *app) { + NSString *appDataPath = getAppSandboxPath(app); + if (appDataPath) { + //判断目录,只有这两个目录才能清除,如果是其他的目录,比如/var/mobile/Documents/ 千万不能清除, + //否则可能需要重新激活或产生其他的问题 + if ([appDataPath hasPrefix:@"/private/var/mobile/Containers/Data/Application/"] || + [appDataPath hasPrefix:@"/var/mobile/Containers/Data/Application/"]) { + NSString *strLibraryPath = [appDataPath stringByAppendingPathComponent:@"Library"]; + NSString *strPreferencesPath = [strLibraryPath stringByAppendingPathComponent:@"Preferences"]; + NSString *appInfoPlist = [strPreferencesPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", app]]; + NSLog(@"app info path:%@", appInfoPlist); + return appInfoPlist; + } + } + return nil; +} + +NSDictionary* XSGetAppInfo(NSString *appInfoPlist) { + if (appInfoPlist) { + NSDictionary *appInfo = [[NSDictionary alloc] initWithContentsOfFile:appInfoPlist]; + return appInfo; + } + return nil; +} + +void XSSaveAppInfo(NSDictionary *dic, NSString *appInfoPath) { + NSMutableDictionary *saveDic = [[NSMutableDictionary alloc] init]; + if (dic) { + id kzzhDeviceInfo = dic[@"kzzhDeviceInfo"]; + if (kzzhDeviceInfo) { + [saveDic setValue:kzzhDeviceInfo forKey:@"kzzhDeviceInfo"]; + } + + id appInfo = dic[@"appInfo"]; + if (appInfo) { + [saveDic setValue:appInfo forKey:@"appInfo"]; + } + + id applovinInfo = dic[@"applovinInfo"]; + if (applovinInfo) { + [saveDic setValue:applovinInfo forKey:@"applovinInfo"]; + } + id kNilOptions = dic[@"kNilOptions"]; + if (kNilOptions) { + [saveDic setValue:kNilOptions forKey:@"kNilOptions"]; + } + id bfaceDictKey = dic[@"bfaceDictKey"]; + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSString *deviceId = config.DeviceId; + NSString *loclIp = [[XSPhoneInfo sharedInstance] IPAddress]; + if (bfaceDictKey) { + NSMutableDictionary *tempDic = [NSMutableDictionary dictionaryWithDictionary:bfaceDictKey]; + [tempDic setValue:deviceId forKey:@"adbrush_deviceid"]; + [tempDic setValue:loclIp forKey:@"adbrush_localip"]; + [saveDic setValue:tempDic forKey:@"bfaceDictKey"]; + } else { + NSDictionary *tempDic = @{@"adbrush_deviceid": deviceId, @"adbrush_localip": loclIp}; + [saveDic setValue:tempDic forKey:@"bfaceDictKey"]; + } + /* + NSDictionary *strAttrib = [NSDictionary dictionaryWithObjectsAndKeys: + @"mobile",NSFileGroupOwnerAccountName, + @"mobile",NSFileOwnerAccountName, + nil]; + */ + [saveDic writeToFile:appInfoPath atomically:YES]; + } +} + +void cleanBundleContainer(NSString *appDataPath) { + //判断目录,只有这两个目录才能清除,如果是其他的目录,比如/var/mobile/Documents/ 千万不能清除, + //否则可能需要重新激活或产生其他的问题 + if ([appDataPath hasPrefix:@"/private/var/mobile/Containers/Data/Application/"] || + [appDataPath hasPrefix:@"/var/mobile/Containers/Data/Application/"]) { + + NSFileManager *fm = [NSFileManager defaultManager]; + + NSString *strDocumentsPath = [appDataPath stringByAppendingPathComponent:@"Documents"]; + [fm removeItemAtPath:strDocumentsPath error:nil]; + + NSString *strLibraryPath = [appDataPath stringByAppendingPathComponent:@"Library"]; + + + NSString *strCachesPath = [strLibraryPath stringByAppendingPathComponent:@"Caches"]; + NSString *strPreferencesPath = [strLibraryPath stringByAppendingPathComponent:@"Preferences"]; + + + [fm removeItemAtPath:strLibraryPath error:nil]; + + NSString *strTmpPath = [appDataPath stringByAppendingPathComponent:@"tmp"]; + [fm removeItemAtPath:strTmpPath error:nil]; + + NSString *strStoreKitPath = [appDataPath stringByAppendingPathComponent:@"StoreKit"]; + [fm removeItemAtPath:strStoreKitPath error:nil]; + + //删除沙盒目录之后,要以mobile身份创建相应的目录,否则可能会因为权限问题使再次安装的应用 + //不能写入应用沙盒目录 + NSDictionary *strAttrib = [NSDictionary dictionaryWithObjectsAndKeys: + @"mobile",NSFileGroupOwnerAccountName, + @"mobile",NSFileOwnerAccountName, + nil]; + + [fm createDirectoryAtPath:appDataPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + [fm createDirectoryAtPath:strDocumentsPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + [fm createDirectoryAtPath:strLibraryPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + [fm createDirectoryAtPath:strCachesPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + [fm createDirectoryAtPath:strPreferencesPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + [fm createDirectoryAtPath:strTmpPath withIntermediateDirectories:NO + attributes:strAttrib error:nil]; + } +} + +void clearAppStringInfo(NSString* appPath) { + NSFileManager *fm = [NSFileManager defaultManager]; + if (![fm fileExistsAtPath:appPath]) { + return; + } + if ([appPath hasPrefix:@"/private/var/containers/Bundle/Application"] || + [appPath hasPrefix:@"/var/containers/Bundle/Application"] || + [appPath hasPrefix:@"/private/var/mobile/Containers/Data/Application"] || + [appPath hasPrefix:@"/var/mobile/Containers/Data/Application"]) { + NSString *itunesPath = [appPath stringByDeletingLastPathComponent]; + NSLog(@"itunes path: %@", itunesPath); + NSString *file1 = [NSString stringWithFormat:@"%@/iTunesMetadata.plist", itunesPath]; + NSString *file2 = [NSString stringWithFormat:@"%@/iTunesArtwork", itunesPath]; + NSString *file3 = [NSString stringWithFormat:@"%@/BundleMetadata.plist", itunesPath]; + [fm removeItemAtPath:file1 error:nil]; + [fm removeItemAtPath:file2 error:nil]; + [fm removeItemAtPath:file3 error:nil]; + } +} + +void XSClearAppData(NSString *app) { + NSString *appPath = getAppSandboxPath(app); + if (appPath) { + cleanBundleContainer(appPath); + clearAppStringInfo(appPath); + } +} + +BOOL screenIsLocked(void) { + Class sbUIControllerClass = objc_getClass("SBUIController"); + id sbUIController = [sbUIControllerClass performSelector:@selector(sharedInstance)]; + + // 检查设备是否在锁屏状态 + if ([sbUIController respondsToSelector:@selector(isOnLockScreen)]) { + BOOL isLocked = [sbUIController performSelector:@selector(isOnLockScreen)]; + return isLocked; + } + return YES; +} + +void XSClearAll(NSString *appId) { + XSCleanSafari(); + XSCleanKeychain(); + XSCleanPastboard(); + XSClearAppData(appId); +} + + +double getCPUTemperature(void) { + double temperature = 0.0; + + io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleSMC")); + if (platformExpert) { + CFMutableDictionaryRef propertyDict = NULL; + kern_return_t result = IORegistryEntryCreateCFProperties(platformExpert, &propertyDict, kCFAllocatorDefault, 0); + if (result == kIOReturnSuccess) { + CFDataRef data = CFDictionaryGetValue(propertyDict, CFSTR("TC0P")); + if (data) { + const UInt8 *bytes = CFDataGetBytePtr(data); + temperature = (double)bytes[0]; + } + CFRelease(propertyDict); + } + IOObjectRelease(platformExpert); + } + + return temperature; +} + +// 注入网络权限 +void injectNetworkPermissions(void) { + // 创建授权选项 + SecTaskRef task = SecTaskCreateFromSelf(NULL); + if (!task) return; + + CFErrorRef error = NULL; + CFTypeRef entitled = SecTaskCopyValueForEntitlement(task, + CFSTR("com.apple.private.network.client"), + &error); + + if (!entitled) { + // 添加网络客户端权限 + CFDictionaryRef entitlements = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue((CFMutableDictionaryRef)entitlements, + CFSTR("com.apple.private.network.client"), + kCFBooleanTrue); + + static void *security = NULL; + static SecTaskSetEntitlementsPtr SetEntitlements = NULL; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + security = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY); + if (security) { + SetEntitlements = (SecTaskSetEntitlementsPtr)dlsym(security, "SecTaskSetEntitlements"); + } + }); + + if (!security || !SetEntitlements) { + NSLog(@"XS- no SecTaskSetEntitlements"); + + return; + } + + // 应用权限 + SetEntitlements(task, entitlements); + + CFRelease(entitlements); + } + + if (entitled) CFRelease(entitled); + CFRelease(task); +} + + +BOOL injectEntitlementsWithOptions(NSDictionary *options, NSError **error) { + static void *security = NULL; + static SecTaskSetEntitlementsPtr SetEntitlements = NULL; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + security = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY); + if (security) { + SetEntitlements = (SecTaskSetEntitlementsPtr)dlsym(security, "SecTaskSetEntitlements"); + } + }); + + if (!security || !SetEntitlements) { + if (error) { + *error = [NSError errorWithDomain:@"EntitlementsInjectorErrorDomain" + code:-1 + userInfo:@{NSLocalizedDescriptionKey: @"无法加载必要的系统函数"}]; + } + return NO; + } + + SecTaskRef task = SecTaskCreateFromSelf(NULL); + if (!task) { + if (error) { + *error = [NSError errorWithDomain:@"EntitlementsInjectorErrorDomain" + code:-2 + userInfo:@{NSLocalizedDescriptionKey: @"无法创建任务引用"}]; + } + return NO; + } + + // 转换权限字典 + NSMutableDictionary *entitlements = [NSMutableDictionary dictionary]; + + // 基本网络权限 + entitlements[@"com.apple.developer.networking.HotspotConfiguration"] = @YES; + entitlements[@"com.apple.developer.networking.networkextension"] = @YES; + entitlements[@"com.apple.developer.networking.wifi-info"] = @YES; + + // 添加用户自定义权限 + [entitlements addEntriesFromDictionary:options]; + + // 注入权限 + CFErrorRef cfError = NULL; + Boolean success = SetEntitlements(task, (__bridge CFDictionaryRef)entitlements); + + CFRelease(task); + + if (!success) { + if (error) { + *error = (__bridge NSError *)cfError; + } + if (cfError) CFRelease(cfError); + return NO; + } + + return YES; +} + +// 验证权限是否注入成功 +BOOL verifyEntitlement(NSString *entitlementName) { + SecTaskRef task = SecTaskCreateFromSelf(NULL); + if (!task) return NO; + + CFErrorRef error = NULL; + CFTypeRef value = SecTaskCopyValueForEntitlement(task, + (__bridge CFStringRef)entitlementName, + &error); + + CFRelease(task); + + if (error) { + CFRelease(error); + return NO; + } + + BOOL hasEntitlement = (value != NULL); + if (value) CFRelease(value); + + return hasEntitlement; +} + + +pid_t system2(const char * command, int * infp, int * outfp) +{ + int p_stdin[2]; + int p_stdout[2]; + pid_t pid; + + if (pipe(p_stdin) == -1) + return -1; + + if (pipe(p_stdout) == -1) { + close(p_stdin[0]); + close(p_stdin[1]); + return -1; + } + + pid = fork(); + + if (pid < 0) { + close(p_stdin[0]); + close(p_stdin[1]); + close(p_stdout[0]); + close(p_stdout[1]); + return pid; + } else if (pid == 0) { + close(p_stdin[1]); + dup2(p_stdin[0], 0); + close(p_stdout[0]); + dup2(p_stdout[1], 1); + dup2(open("/dev/null", O_RDONLY), 2); + /// Close all other descriptors for the safety sake. + for (int i = 3; i < 4096; ++i) + close(i); + + setsid(); + execl("/bin/sh", "sh", "-c", command, NULL); + _exit(1); + } + + close(p_stdin[0]); + close(p_stdout[1]); + + if (infp == NULL) { + close(p_stdin[1]); + } else { + *infp = p_stdin[1]; + } + + if (outfp == NULL) { + close(p_stdout[0]); + } else { + *outfp = p_stdout[0]; + } + + if (pid > 0) + { + waitpid(pid, NULL, 0); + } + return pid; +} + + + +void printInfo(id object) { + if (!object) { + NSLog(@"Object is nil"); + return; + } + + // 获取类名 + NSLog(@"\nClass: %@", NSStringFromClass([object class])); + + // 1. 获取所有属性 + unsigned int propertyCount; + objc_property_t *properties = class_copyPropertyList([object class], &propertyCount); + + NSLog(@"\n=== Properties ==="); + for (unsigned int i = 0; i < propertyCount; i++) { + objc_property_t property = properties[i]; + + // 属性名 + const char *propertyName = property_getName(property); + // 属性特性 + const char *attributes = property_getAttributes(property); + + NSLog(@"Property: %s, Attributes: %s", propertyName, attributes); + + // 尝试获取属性值 + @try { + NSString *name = [NSString stringWithUTF8String:propertyName]; + id value = [object valueForKey:name]; + NSLog(@"Value: %@", value); + } @catch (NSException *exception) { + NSLog(@"Cannot access value"); + } + } + free(properties); + + // 2. 获取所有实例方法 + unsigned int methodCount; + Method *methods = class_copyMethodList([object class], &methodCount); + + NSLog(@"\n=== Methods ==="); + for (unsigned int i = 0; i < methodCount; i++) { + Method method = methods[i]; + SEL selector = method_getName(method); + NSString *methodName = NSStringFromSelector(selector); + + // 获取参数个数 + int arguments = method_getNumberOfArguments(method); + struct objc_method_description *desc = method_getDescription(method); + NSLog(@"args:%s", desc->types); + // 获取返回值类型 + char *returnType = method_copyReturnType(method); + + NSLog(@"Method: %@, Args: %d, ReturnType: %s", methodName, arguments, returnType); + free(returnType); + } + free(methods); + + // 3. 获取所有实例变量 + unsigned int ivarCount; + Ivar *ivars = class_copyIvarList([object class], &ivarCount); + + NSLog(@"\n=== Instance Variables ==="); + for (unsigned int i = 0; i < ivarCount; i++) { + Ivar ivar = ivars[i]; + const char *ivarName = ivar_getName(ivar); + const char *ivarType = ivar_getTypeEncoding(ivar); + + NSLog(@"Ivar: %s, Type: %s", ivarName, ivarType); + } + free(ivars); + + // 4. 获取遵循的协议 + unsigned int protocolCount; + Protocol * __unsafe_unretained *protocols = class_copyProtocolList([object class], &protocolCount); + + NSLog(@"\n=== Protocols ==="); + for (unsigned int i = 0; i < protocolCount; i++) { + Protocol *protocol = protocols[i]; + const char *protocolName = protocol_getName(protocol); + NSLog(@"Protocol: %s", protocolName); + } + free(protocols); +} + +// 递归获取父类信息 +void printClassHierarchy(Class cls) { + NSLog(@"\n=== Class Hierarchy ==="); + while (cls) { + NSLog(@"Class: %@", NSStringFromClass(cls)); + cls = class_getSuperclass(cls); + } +} + +// 获取方法的详细信息 +void printMethodInfo(Method method) { + SEL selector = method_getName(method); + NSString *methodName = NSStringFromSelector(selector); + + // 获取参数类型 + unsigned int argCount = method_getNumberOfArguments(method); + NSMutableArray *argTypes = [NSMutableArray array]; + + for (unsigned int i = 0; i < argCount; i++) { + char *argType = method_copyArgumentType(method, i); + if (argType) { + [argTypes addObject:[NSString stringWithUTF8String:argType]]; + free(argType); + } + } + + // 获取返回值类型 + char *returnType = method_copyReturnType(method); + NSString *returnTypeString = returnType ? [NSString stringWithUTF8String:returnType] : @"?"; + free(returnType); + + NSLog(@"Method: %@\nReturn Type: %@\nArgument Types: %@", + methodName, returnTypeString, argTypes); +} + +// 获取属性的详细信息 +void printPropertyInfo(objc_property_t property) { + const char *name = property_getName(property); + const char *attributes = property_getAttributes(property); + + unsigned int attrCount; + objc_property_attribute_t *attrs = property_copyAttributeList(property, &attrCount); + + NSMutableArray *attributeDetails = [NSMutableArray array]; + for (unsigned int i = 0; i < attrCount; i++) { + NSString *attrName = @(attrs[i].name); + NSString *attrValue = attrs[i].value ? @(attrs[i].value) : @""; + [attributeDetails addObject:[NSString stringWithFormat:@"%@=%@", attrName, attrValue]]; + } + + free(attrs); + + NSLog(@"Property: %s\nAttributes: %s\nDetailed Attributes: %@", + name, attributes, attributeDetails); +} + + + +// 属性特性解析工具 +NSDictionary* parsePropertyAttributes(const char *attributes) { + NSString *attributeString = @(attributes); + NSArray *components = [attributeString componentsSeparatedByString:@","]; + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + + for (NSString *component in components) { + if ([component hasPrefix:@"T"]) { + result[@"type"] = [component substringFromIndex:1]; + } else if ([component isEqualToString:@"R"]) { + result[@"readonly"] = @YES; + } else if ([component isEqualToString:@"C"]) { + result[@"copy"] = @YES; + } else if ([component isEqualToString:@"&"]) { + result[@"strong"] = @YES; + } else if ([component isEqualToString:@"W"]) { + result[@"weak"] = @YES; + } else if ([component isEqualToString:@"N"]) { + result[@"nonatomic"] = @YES; + } + } + + return result; +} + + + +// 获取前台应用 +void getFrontAppWindows(void) { + SpringBoard *springBoard = (SpringBoard *)[UIApplication sharedApplication]; + UIApplication *frontApp = [springBoard _accessibilityFrontMostApplication]; + printInfo(frontApp); + // 获取SBWindowManager类 + Class SBWindowManagerClass = NSClassFromString(@"SBWindowManager"); + id windowManager = [SBWindowManagerClass sharedInstance]; + NSLog(@"SBWindowManager"); + printInfo(windowManager); + UIWindow *win = [[NSClassFromString(@"SBUIController") sharedInstance] window]; + printInfo(win); + // 尝试获取windows + if ([windowManager respondsToSelector:@selector(windows)]) { + NSArray *windows = [windowManager windows]; + NSLog(@"windows: %@", windows); + } +} + + +void findButtonsInView(UIView *view) { + NSLog(@"findButtonsInView:%@",view); + // 如果是按钮 + if ([view isKindOfClass:[UIButton class]]) { + UIButton *button = (UIButton *)view; + CGRect frameInWindow = [button convertRect:button.bounds toView:nil]; + + NSString *title = [button titleForState:UIControlStateNormal]; + NSLog(@"Button: %@, Position: %@", title, NSStringFromCGRect(frameInWindow)); + } + + // 遍历子视图 + for (UIView *subview in view.subviews) { + findButtonsInView(subview); + } +} + +UIWindow* getKeyWindow(void) { + NSLog(@"getKeyWindow"); + getFrontAppWindows(); + UIWindow *keyWindow = nil; + + // iOS 13及以上版本 + if (@available(iOS 13.0, *)) { + NSSet *connectedScenes = [[UIApplication sharedApplication] connectedScenes]; + for (UIScene *scene in connectedScenes) { + if ([scene isKindOfClass:[UIWindowScene class]]) { + UIWindowScene *windowScene = (UIWindowScene *)scene; + for (UIWindow *window in windowScene.windows) { + NSLog(@"getKeyWindow: %@", window); + findButtonsInView(window); + if (window.isKeyWindow) { + keyWindow = window; + //break; + } + } + } + } + } else { + // iOS 13以下版本 + keyWindow = [[UIApplication sharedApplication] keyWindow]; + } + + return keyWindow; +} + + +void getAllButtons(void) { + dispatch_sync(dispatch_get_main_queue(),^{ + // 获取当前窗口 + //FBScene *scene = getForegroundAppScene(); + //findButtonsInView(scene.window); + + UIWindow *keyWindow = getKeyWindow(); + // 递归查找按钮 + findButtonsInView(keyWindow); + }); +} + diff --git a/AppRunMan/server/XSHelper.h b/AppRunMan/server/XSHelper.h new file mode 100644 index 0000000..7e706c2 --- /dev/null +++ b/AppRunMan/server/XSHelper.h @@ -0,0 +1,76 @@ +// +// XSHelper.h +// nochange +// +// Created by mac on 2024/10/15. +// + +#ifndef XSHelper_h +#define XSHelper_h + +#import +#import +#import +#import + + +// 在头文件定义宏 +#define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] +#define RGB(r,g,b) RGBA(r,g,b,1.0f) + + +typedef void (^MyOCRCallback)(NSString *text); +typedef void (^NextCallback)(void); + +float XSRoundToDecimal(float value, int decimalPlaces); +double XSCalculateElapsedTime(uint64_t start, uint64_t end) ; +void XSAfterNext(int sec, NextCallback next); + +NSError* XSErrorFromException(NSException* exception); + +@interface XSHelper : NSObject +{ + +} + ++ (NSString *)readFileText: (NSString *)path; ++ (BOOL) saveFile: (NSString *) path data: (NSData *)data; ++ (BOOL) saveFile: (NSString *) path text: (NSString *)text; ++ (void) rmFiles: (NSString *) path; ++ (UIImage *) imageFromFile:(NSString *) path; ++ (NSString *)data2str: (NSData *) data; ++ (NSData *)str2Data:(NSString *)str; ++ (BOOL) strIsEmpty: (NSString *)str; ++ (NSDictionary *) json2Dictionary: (NSString *)json; ++ (NSDictionary *) jsonData2Dictionary: (NSData *)data; ++ (NSString *)dic2Json: (NSDictionary *)dict; ++ (NSData *)obj2JsonData:(id)obj; ++ (NSNumber *)str2num:(NSString *)str; ++ (bool) isMatch: (NSString *)pattern test:(NSString *)test; ++ (NSString *)replaceStr: (NSString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr; ++ (void)replaceMulStr: (NSMutableString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr; ++ (NSString *)replaceStr: (NSString *)text regex:(NSString *)regex newStr:(NSString *)newStr; ++ (UIImage *)png2jpg:(UIImage *)png; ++ (void)performOCROnImage:(UIImage *)image callback:(MyOCRCallback) callback; ++ (NSString *)base64StringFromJpgImage:(UIImage *)image; ++ (UIImage *)imageFromBase64String:(NSString *)base64String; ++ (double) getCurTime; ++ (int)random:(int)min and:(int)max; +@end + + +@interface NSData (AES) + +- (NSData *)aesEncrypt: (NSString *)key iv:(NSString *)iv; +- (NSData *)aesDecrypt: (NSString *)key iv:(NSString *)iv; + +@end + +@interface NSString (AES) +- (NSString *)aesEncrypt: (NSString *)key iv:(NSString *)iv; +- (NSString *)aesDecrypt: (NSString *)key iv:(NSString *)iv; +@end + + + +#endif /* XSHelper_h */ diff --git a/AppRunMan/server/XSHelper.m b/AppRunMan/server/XSHelper.m new file mode 100644 index 0000000..25b68dd --- /dev/null +++ b/AppRunMan/server/XSHelper.m @@ -0,0 +1,373 @@ +// +// XSHelper.m +// nochange +// +// Created by mac on 2024/10/15. +// + +#import +#import "XSHelper.h" + + + +NSError* XSErrorFromException(NSException* exception) { + NSMutableDictionary* userInfo = [NSMutableDictionary dictionary]; + + [userInfo setObject:exception.name forKey:NSLocalizedFailureReasonErrorKey]; + [userInfo setObject:exception.reason forKey:NSLocalizedDescriptionKey]; + + if (exception.userInfo) { + [userInfo addEntriesFromDictionary:exception.userInfo]; + } + + return [NSError errorWithDomain:@"ExceptionDomain" code:-1 userInfo:userInfo]; +} + +// mach_absolute_time() +double XSCalculateElapsedTime(uint64_t start, uint64_t end) { + static mach_timebase_info_data_t timebaseInfo; + if (timebaseInfo.denom == 0) { + mach_timebase_info(&timebaseInfo); + } + + uint64_t elapsed = end - start; + uint64_t nanos = elapsed * timebaseInfo.numer / timebaseInfo.denom; + return (double)nanos / NSEC_PER_MSEC; +} +// 小数位保留 +float XSRoundToDecimal(float value, int decimalPlaces) { + float multiplier = powf(10.0f, decimalPlaces); + return roundf(value * multiplier) / multiplier; +} + +void XSAfterNext(int sec, NextCallback next) { + // 或使用GCD timer + dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0)); + dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, sec * NSEC_PER_SEC, 0); + dispatch_source_set_event_handler(timer, ^{ + // 延迟操作 + next(); + }); + dispatch_resume(timer); +} + + + +@interface XSHelper() +{ + +} + +@end + + +@implementation XSHelper + ++ (int)random:(int)min and:(int)max { + return min + arc4random_uniform(max - min + 1); +} + ++ (NSData *)str2Data:(NSString *)str { + return [str dataUsingEncoding:NSUTF8StringEncoding]; +} ++ (NSString *)data2str: (NSData *) data { + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];; +} ++ (BOOL) strIsEmpty: (NSString *)str { + if (str == nil) { + return YES; + } + if ([str isEqual:[NSNull null]]) { + return YES; + } + if ([str length] <=0) { + return YES; + } + return NO; +} ++ (bool) isMatch: (NSString *)pattern test:(NSString *)test { + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern + options:0 + error:nil]; + NSUInteger numberOfMatches = [regex numberOfMatchesInString:test + options:0 + range:NSMakeRange(0, [test length])]; + return numberOfMatches > 0; +} + ++ (NSDictionary *) json2Dictionary: (NSString *)json { + if(json == nil || [json isEqual:[NSNull null]] || [json isEqual:@""]) { + return @{}; + } + return [XSHelper jsonData2Dictionary:[XSHelper str2Data:json]]; +} + ++ (NSDictionary *) jsonData2Dictionary: (NSData *)data { + NSError *jsonError; + NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&jsonError]; + if (jsonError) { + NSLog(@"json2dic error: %@", jsonError); + } + return dic; +} ++ (NSData *)obj2JsonData:(id)obj { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj + options:NSJSONWritingPrettyPrinted + error:&error]; + + return jsonData; +} + ++ (NSString *)dic2Json: (NSDictionary *)dict { + NSData *jsonData = [XSHelper obj2JsonData:dict]; + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; +} + ++ (NSString *)readFileText:(NSString *)path { + NSError *error = nil; + NSString *content = [NSString stringWithContentsOfFile:path + encoding:NSUTF8StringEncoding + error:&error]; + if (error) { + NSLog(@"XS- Helper readFileText Error: %@", error.localizedDescription); + return nil; + } + return content; +} ++ (BOOL) saveFile: (NSString *) path data: (NSData *)data { + return [data writeToFile:path atomically:YES]; +} + ++ (BOOL) saveFile: (NSString *) path text: (NSString *)text { + NSData *data = [XSHelper str2Data:text]; + return [XSHelper saveFile:path data:data]; +} + ++ (void) rmFiles: (NSString *) path { + NSFileManager *man = [NSFileManager defaultManager]; + if ([man fileExistsAtPath:path]) { + NSArray *dirArray = [man contentsOfDirectoryAtPath:path error:nil]; + for (NSString * str in dirArray) { + NSString *subPath = [path stringByAppendingPathComponent:str]; + NSLog(@"XS- del file:%@", subPath); + NSError *error; + [man removeItemAtPath:subPath error:&error]; + if (error) { + NSLog(@"XS- Error clearing: %@,,%@", path, error.localizedDescription); + } + } + } else { + NSLog(@"XS- %@ not found", path); + } + +} + ++ (NSNumber *)str2num:(NSString *)str { + NSNumberFormatter *f = [[NSNumberFormatter alloc] init]; + f.numberStyle = NSNumberFormatterDecimalStyle; + NSNumber *myNumber = [f numberFromString:str]; + return myNumber; +} ++ (NSString *)replaceStr: (NSString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr { + return [text stringByReplacingOccurrencesOfString:oldStr withString:newStr]; +} + ++ (void)replaceMulStr: (NSMutableString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr { + [text replaceOccurrencesOfString:oldStr + withString:newStr + options:NSLiteralSearch + range:NSMakeRange(0, [text length])]; +} + ++ (NSString *)replaceStr: (NSString *)text regex:(NSString *)regex newStr:(NSString *)newStr { + NSError *error = nil; + NSRegularExpression *nsregex = [NSRegularExpression regularExpressionWithPattern:regex + options:0 + error:&error]; + if (!error) { + NSString *newString = [nsregex stringByReplacingMatchesInString:text + options:0 + range:NSMakeRange(0, [text length]) + withTemplate:@"YYYY-MM-DD"]; + NSLog(@"%@", newString); // 输出: The date is YYYY-MM-DD + return newString; + } + return text; +} + +/// 编码:A => QQ== ++ (NSString *)base64Encode:(NSString *)string { + // 1. 将字符串转换成二进制数据 + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + + // 2. 利用 iOS 7.0 的方法,直接 base64 编码 + return [data base64EncodedStringWithOptions:0]; +} + +/// 解码:QQ== => A ++ (NSString *)base64Decode:(NSString *)string { + // 1. 将base64编码后的字符串,解码成二进制数据 + NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0]; + + // 2. 返回解码后的字符串 + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +} + +//-- img ++ (UIImage *) imageFromFile:(NSString *) path { + return [UIImage imageWithContentsOfFile:path]; +} ++ (NSString *)base64StringFromJpgImage:(UIImage *)image { + NSData *imageData = UIImageJPEGRepresentation(image, 0.8); + NSString *base64String = [imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]; + return base64String; +} + ++ (UIImage *)imageFromBase64String:(NSString *)base64String { + NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters]; + return [UIImage imageWithData:imageData]; +} ++ (UIImage *)png2jpg:(UIImage *)png { + NSData *jpgdata = UIImageJPEGRepresentation(png, 0.8); + return [UIImage imageWithData:jpgdata]; +} + + + + ++ (double) getCurTime { + // 获取当前日期和时间 + NSDate *now = [NSDate date]; + return [now timeIntervalSince1970]; +} + + +// Vision ++ (void)performOCROnImage:(UIImage *)image callback:(MyOCRCallback)callback { + NSLog(@"XS- performOCROnImage"); + if (!image) { + NSLog(@"XS- No image provided"); + callback(@""); + return; + } + + // 在后台队列中执行 OCR + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + // 创建 VNImageRequestHandler + VNImageRequestHandler *imageRequestHandler = [[VNImageRequestHandler alloc] initWithCIImage:[CIImage imageWithCGImage:image.CGImage] + options:@{}]; + + // 创建文本识别请求 + VNRecognizeTextRequest *textRecognitionRequest = [[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) { + if (error) { + NSLog(@"XS- Error: %@", error.localizedDescription); + dispatch_async(dispatch_get_main_queue(), ^{ + callback(@""); + }); + return; + } + + NSMutableString *recognizedText = [NSMutableString string]; + for (VNRecognizedTextObservation *observation in request.results) { + VNRecognizedText *topCandidate = [observation topCandidates:1].firstObject; + if (topCandidate) { + [recognizedText appendFormat:@"%@\n", topCandidate.string]; + } + } + + NSLog(@"XS- Recognized Text:\n%@", recognizedText); + + // 在主线程上处理结果 + dispatch_async(dispatch_get_main_queue(), ^{ + callback(recognizedText); + }); + }]; + + // 设置识别语言(可选) + textRecognitionRequest.recognitionLanguages = @[@"en-US", @"zh-Hans"]; + + // 执行请求 + NSError *error; + [imageRequestHandler performRequests:@[textRecognitionRequest] error:&error]; + if (error) { + NSLog(@"XS- Error performing OCR request: %@", error.localizedDescription); + dispatch_async(dispatch_get_main_queue(), ^{ + callback(@""); + }); + } + }); +} + + +@end + + + +@implementation NSData (AES) + +- (NSData *)aesEncrypt: (NSString *)key iv:(NSString *)iv { + return [self AES128operation:kCCEncrypt key:key iv:iv]; +} + +- (NSData *)aesDecrypt: (NSString *)key iv:(NSString *)iv { + return [self AES128operation:kCCDecrypt key:key iv:iv]; +} + +- (NSData *)AES128operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv +{ + char keyPtr[kCCKeySizeAES128 + 1]; + bzero(keyPtr, sizeof(keyPtr)); + [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; + + // IV + char ivPtr[kCCBlockSizeAES128 + 1]; + bzero(ivPtr, sizeof(ivPtr)); + [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; + + size_t bufferSize = [self length] + kCCBlockSizeAES128; + void *buffer = malloc(bufferSize); + size_t numBytesEncrypted = 0; + + + + CCCryptorStatus cryptorStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding, + keyPtr, kCCKeySizeAES128, + ivPtr, + self.bytes, self.length, + buffer, bufferSize, + &numBytesEncrypted); + + if(cryptorStatus == kCCSuccess) { + NSLog(@"Success"); + return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; + } else { + NSLog(@"Error"); + } + + free(buffer); + return nil; +} + +@end + + +@implementation NSString (AES) + +- (NSString *)aesEncrypt: (NSString *)key iv:(NSString *)iv { + NSData *data = [[XSHelper str2Data:self] aesEncrypt:key iv:iv]; + return [data base64EncodedStringWithOptions:0]; +} + +- (NSString *)aesDecrypt: (NSString *)key iv:(NSString *)iv { + NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:0]; + NSData *dec = [data aesDecrypt:key iv:iv]; + return [XSHelper data2str:dec]; +} + +@end + + + diff --git a/AppRunMan/server/XSHttpHelper.h b/AppRunMan/server/XSHttpHelper.h new file mode 100644 index 0000000..565abc2 --- /dev/null +++ b/AppRunMan/server/XSHttpHelper.h @@ -0,0 +1,29 @@ +// +// XSHttpHelper.h +// nochange +// +// Created by mac on 2024/10/23. +// + +#ifndef XSHttpHelper_h +#define XSHttpHelper_h + + +typedef void (^request_callback)(NSData *); +typedef void (^error_callback)(NSError *); +typedef void (^download_callback)(NSString*); +typedef void (^rt_str_callback)(NSString*); + +@interface XSHttpHelper : NSObject +// @property (nonatomic, strong) NSURLSession *session; +@property (nonatomic, strong) NSURLSessionDataTask *dataTask; +@property (nonatomic, strong) NSURLSessionDataTask *postDataTask; + +- (void) doGET: (NSString*) urlStr withCallback:(request_callback) callback withError: (error_callback) errorCallback; +- (NSData *) doGET: (NSString*) urlStr; +- (void) doPOST: (NSString*) urlStr json: (NSString *)json withCallback:(request_callback) callback withError: (error_callback) errorCallback; +- (NSData*) doPOST:(NSString *)urlStr json:(NSString *)json; +- (void)requestNetworkPermissions; +@end + +#endif /* XSHttpHelper_h */ diff --git a/AppRunMan/server/XSHttpHelper.m b/AppRunMan/server/XSHttpHelper.m new file mode 100644 index 0000000..0320dc3 --- /dev/null +++ b/AppRunMan/server/XSHttpHelper.m @@ -0,0 +1,206 @@ +// +// XSHttpHelper.m +// nochange +// +// Created by mac on 2024/10/23. +// + +#import + +#import "XSHttpHelper.h" +#import "XSHelper.h" +#import "XSPhoneConfig.h" + +#import + +@interface SSLBypassDelegate : NSObject +@end + +@implementation NSURLSession (SSLBypass) + ++ (NSURLSession *)sessionWithoutSSLValidation { + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; + return [NSURLSession sessionWithConfiguration:configuration + delegate:[[SSLBypassDelegate alloc] init] + delegateQueue:nil]; +} + +@end + + + +@implementation SSLBypassDelegate + +- (void)URLSession:(NSURLSession *)session +didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge + completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + completionHandler(NSURLSessionAuthChallengeUseCredential, credential); + } +} + +@end + +@interface XSHttpHelper () { +@private NSString *apikey; + +} + +@end + +@implementation XSHttpHelper + + +-(instancetype)init { + if (self = [super init]) { + apikey = [[XSPhoneConfig sharedInstance] ApiKey]; + return self; + } + return nil; +} + + + +// http begin --------- +- (void) doGET: (NSString*) urlStr withCallback:(request_callback) callback withError: (error_callback) errorCallback { + @try { + NSLog(@"XS- doGET URL:%@", urlStr); + NSURL *url = [NSURL URLWithString:urlStr]; + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5]; + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [request setValue:self->apikey forHTTPHeaderField:@"apikey"]; + + NSURLSession *session = [NSURLSession sessionWithoutSSLValidation];// [NSURLSession sharedSession]; + self.dataTask = [session dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) + { + NSLog(@"XS- http get res"); + if (error) { + NSLog(@"XS- http get error: %@", error); + errorCallback(error); + } else { + NSLog(@"XS- %@;Response:\n%@", urlStr, [XSHelper data2str: data]); + callback(data);// do something with the data + } + + }]; + [self.dataTask resume]; + } @catch (NSException *exception) { + NSLog(@"XS- http get exception error,%@", exception); + errorCallback(XSErrorFromException(exception)); + } + +} + +- (NSData *) doGET: (NSString*) urlStr { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSData* _data = nil; + [self doGET:urlStr withCallback:^(NSData *data) { + _data = data; + dispatch_semaphore_signal(semaphore); + } withError:^(NSError *err) { + dispatch_semaphore_signal(semaphore); + }]; + // 设置超时时间为5秒 + dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC); + + // 等待信号量,最多等待5秒 + long result = dispatch_semaphore_wait(semaphore, timeout); + + if (result == 0) { + // 在超时之前收到了信号 + NSLog(@"doGET end"); + } else { + // 超时 + NSLog(@"doGET 等待超时"); + } + return _data; +} + +- (void) doPOST: (NSString*) urlStr json: (NSString *)json withCallback:(request_callback) callback withError: (error_callback) errorCallback { + @try { + NSLog(@"XS- doPOST:%@", urlStr); + NSURL *url = [NSURL URLWithString:urlStr]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request setHTTPMethod:@"POST"]; + + // 设置请求头 + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [request setValue:self->apikey forHTTPHeaderField:@"apikey"]; + NSLog(@"XS- POST body:\n%@", json); + // 将字典转换为JSON数据 + NSData *bodyData = [XSHelper str2Data:json]; + [request setHTTPBody:bodyData]; + + NSURLSession *session = [NSURLSession sessionWithoutSSLValidation];//[NSURLSession sharedSession]; + + self.postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + NSLog(@"XS- post error : %@", error); + errorCallback(error); + } else { + NSLog(@"XS- %@;Response:\n%@", urlStr, [XSHelper data2str: data]); + callback(data); + } + }]; + + [self.postDataTask resume]; + } @catch (NSException *exception) { + NSLog(@"XS- post exception;%@", exception); + errorCallback(XSErrorFromException(exception)); + } +} + +- (NSData*) doPOST:(NSString *)urlStr json:(NSString *)json { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block NSData* _data = nil; + [self doPOST:urlStr json:json withCallback:^(NSData *data) { + _data = data; + dispatch_semaphore_signal(semaphore); + } withError:^(NSError *err) { + dispatch_semaphore_signal(semaphore); + }]; + // 设置超时时间为5秒 + dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC); + + // 等待信号量,最多等待5秒 + long result = dispatch_semaphore_wait(semaphore, timeout); + + if (result == 0) { + // 在超时之前收到了信号 + NSLog(@"do POST end"); + } else { + // 超时 + NSLog(@"do POST 等待超时"); + } + return _data; +} + +- (void)requestNetworkPermissions { + NEHotspotConfigurationManager *manager = [NEHotspotConfigurationManager sharedManager]; + + // 请求本地网络权限 + [manager getConfiguredSSIDsWithCompletionHandler:^(NSArray *ssids) { + if (ssids) { + NSLog(@"已获取网络权限"); + } + }]; +} + +// 设置网络配置 +- (void)setupNetworkConfiguration { + NEHotspotConfiguration *config = [[NEHotspotConfiguration alloc] initWithSSID:@"YourSSID"]; + [[NEHotspotConfigurationManager sharedManager] applyConfiguration:config + completionHandler:^(NSError * _Nullable error) { + if (error) { + NSLog(@"网络配置错误: %@", error); + } else { + NSLog(@"网络配置成功"); + } + }]; +} + +@end diff --git a/AppRunMan/server/XSIosTouch.h b/AppRunMan/server/XSIosTouch.h new file mode 100644 index 0000000..fc5a472 --- /dev/null +++ b/AppRunMan/server/XSIosTouch.h @@ -0,0 +1,51 @@ +// +// XSIosTouch.h +// nochange +// +// Created by mac on 2024/10/15. +// + +#ifndef XSIosTouch_h +#define XSIosTouch_h + +#import +#import +#import +#import +#import +#import +#import +#import +#import "IOHIDUsageTables.h" + +void XSInitGetSenderId(void); + +OBJC_EXTERN IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator); +void IOHIDEventSetSenderID(IOHIDEventRef event, uint64_t senderID); +void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event); +// #define kIOHIDEventDigitizerSenderID 0xDEFACEDBEEFFECE5 + +uint64_t IOHIDEventGetSenderID(IOHIDEventRef event); +uint64_t IOHIDEventGetSenderIDForEvent(IOHIDEventRef event); + +enum { + TOUCH_UP, + TOUCH_DOWN, + TOUCH_MOVE +}; + +@interface XSIosTouch : NSObject ++ (instancetype)sharedInstance; +- (void) Down:(int) index x:(float)x y:(float) y; +- (void) Move:(int) index x:(float)x y:(float) y; +- (void) Up:(int) index x:(float)x y:(float) y; +// - (void) End; +- (void) Tap:(int) index x:(float)x y:(float)y; + +- (void) KeyDown:(uint16_t)usage ; + +- (void) KeyUp:(uint16_t)usage ; + +@end + +#endif /* XSIosTouch_h */ diff --git a/AppRunMan/server/XSIosTouch.m b/AppRunMan/server/XSIosTouch.m new file mode 100644 index 0000000..488f85d --- /dev/null +++ b/AppRunMan/server/XSIosTouch.m @@ -0,0 +1,503 @@ +// +// XSIosTouch.m +// nochange +// +// Created by mac on 2024/10/15. +// + +#import + +#import "XSIosTouch.h" +#import "XSPhoneConfig.h" +#import "XSHelper.h" + + +// static var-------- +// touch event sender id +static unsigned long long int _XSSenderID = 0x0; +static IOHIDEventSystemClientRef _XSIoHIDEventSystemForSenderID = NULL; + +// static var end-------- + + +/* +Get the sender id and unregister itself. +*/ +static void XSSetSenderIdCallback(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event) +{ + NSLog(@"XSSetSenderIdCallback 1"); + if (IOHIDEventGetType(event) == kIOHIDEventTypeDigitizer){ + NSLog(@"XSSetSenderIdCallback 2"); + if (_XSSenderID == 0x0) + { + NSLog(@"XSSetSenderIdCallback 3"); + _XSSenderID = IOHIDEventGetSenderID(event); + + NSInteger currentTime = [[NSDate date] timeIntervalSince1970]; + NSInteger timeSinceReboot = [NSProcessInfo processInfo].systemUptime; + NSInteger rebootTime = currentTime - timeSinceReboot; + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + [config SetLastReboot:rebootTime]; + if (_XSSenderID > 0) { + NSLog(@"XSSetSenderIdCallback 4"); + [config SetSenderId:_XSSenderID]; + } + NSLog(@"com.zjx.springboard: sender id is: %qX", _XSSenderID); + } + } +} + +/** +Start the callback for setting sender id +*/ +static void XSStartSetSenderIDCallBack(void) +{ + _XSIoHIDEventSystemForSenderID = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + IOHIDEventSystemClientScheduleWithRunLoop(_XSIoHIDEventSystemForSenderID, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDEventSystemClientRegisterEventCallback(_XSIoHIDEventSystemForSenderID, (IOHIDEventSystemClientEventCallback)XSSetSenderIdCallback, NULL, NULL); +} +void XSInitGetSenderId(void) { + @try { + NSInteger currentTime = [[NSDate date] timeIntervalSince1970]; + NSInteger timeSinceReboot = [NSProcessInfo processInfo].systemUptime; + NSInteger thisRebootTime = currentTime - timeSinceReboot; + + XSPhoneConfig *config = [XSPhoneConfig sharedInstance]; + NSInteger lastRebootTime = config.LastReboot; + + if (labs(lastRebootTime - thisRebootTime) <= 3) { + if (config.SenderId > 0) { + _XSSenderID = config.SenderId; + return; + } + } + + if (!_XSIoHIDEventSystemForSenderID) { + XSStartSetSenderIDCallBack(); + } + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSInteger retryCount = 0; + while (retryCount < 10) { + [NSThread sleepForTimeInterval:2.0f]; + + if (_XSIoHIDEventSystemForSenderID && _XSSenderID != 0x0) { + IOHIDEventSystemClientUnregisterEventCallback(_XSIoHIDEventSystemForSenderID); + IOHIDEventSystemClientUnscheduleWithRunLoop(_XSIoHIDEventSystemForSenderID, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + break; + } + + retryCount++; + } + + if (retryCount >= 10) { + NSLog(@"Failed to get sender ID after maximum retries"); + } + }); + } @catch (NSException *exception) { + NSLog(@"Error initializing sender ID: %@", exception); + } +} + + +@interface XSIosTouch() { +@private + CGFloat device_screen_width; + CGFloat device_screen_height; + IOHIDEventSystemClientRef ioSystemClient; + dispatch_queue_t touchQueue; + dispatch_semaphore_t eventSemaphore; + NSTimeInterval lastEventTime; + BOOL isProcessingEvent; +} + +@end + + +@implementation XSIosTouch + ++(instancetype)sharedInstance +{ + static XSIosTouch* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[XSIosTouch alloc] init]; + }); + return _sharedInstance; +} + +-(instancetype)init { + if (self = [super init]) { + @try { + CGFloat screen_scale = [[UIScreen mainScreen] scale]; + self->device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale; + self->device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale; + + self->touchQueue = dispatch_queue_create("com.xsiostouch.queue", DISPATCH_QUEUE_SERIAL); + self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + self->eventSemaphore = dispatch_semaphore_create(1); + self->lastEventTime = 0; + self->isProcessingEvent = NO; + + return self; + } @catch (NSException *exception) { + NSLog(@"Error initializing XSIosTouch: %@", exception); + return nil; + } + } + return nil; +} +- (void)dealloc { + if (self->ioSystemClient) { + IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient); + CFRelease(self->ioSystemClient); + self->ioSystemClient = NULL; + } + + if (_XSIoHIDEventSystemForSenderID) { + IOHIDEventSystemClientUnregisterEventCallback(_XSIoHIDEventSystemForSenderID); + CFRelease(_XSIoHIDEventSystemForSenderID); + _XSIoHIDEventSystemForSenderID = NULL; + } +} + +- (void)cleanupResources { + @synchronized(self) { + if (self->ioSystemClient) { + IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient); + CFRelease(self->ioSystemClient); + self->ioSystemClient = NULL; + } + } +} +- (BOOL)checkSystemStatus { + // 检查系统状态,防止过度负载 + if (self->isProcessingEvent) { + return NO; + } + + NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970]; + if (currentTime - self->lastEventTime < 0.016) { + return NO; + } + + return YES; +} + +- (void)resetEventSystem { + @synchronized(self) { + if (self->ioSystemClient) { + IOHIDEventSystemClientUnregisterEventCallback(self->ioSystemClient); + CFRelease(self->ioSystemClient); + self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + } + self->isProcessingEvent = NO; + } +} +- (void)handleEventSystemFailure { + static int failureCount = 0; + + @synchronized(self) { + failureCount++; + if (failureCount >= 3) { + [self resetEventSystem]; + failureCount = 0; + } + } +} + +// device screen size +- (AbsoluteTime) getAbsoluteTime { + uint64_t machAbsoluteTime = mach_absolute_time(); + AbsoluteTime timeStamp; + timeStamp.hi = (UInt32)(machAbsoluteTime >> 32); + timeStamp.lo = (UInt32)(machAbsoluteTime); + return timeStamp; +} + + + + +- (IOHIDEventRef)generateChildEvent:(int)index type:(int)type x:(float)x y:(float)y { + @try { + if (x < 0 || y < 0 || index < 0) { + NSLog(@"Invalid parameters for child event"); + return NULL; + } + + AbsoluteTime timeStamp = [self getAbsoluteTime]; + uint32_t isTouch = (type == TOUCH_UP) ? 0 : 1; + IOHIDDigitizerEventMask eventMask = 0; + + // 设置事件掩码 + if (type != TOUCH_UP && type != TOUCH_DOWN) { + eventMask |= kIOHIDDigitizerEventPosition; + } + if (type == TOUCH_UP || type == TOUCH_DOWN) { + eventMask |= (kIOHIDDigitizerEventTouch | kIOHIDDigitizerEventRange); + } + + // 坐标归一化 + double dx = (self->device_screen_width > 0) ? (x / self->device_screen_width) : 0; + double dy = (self->device_screen_height > 0) ? (y / self->device_screen_height) : 0; + + // 确保坐标在有效范围内 + dx = fmin(fmax(dx, 0.0), 1.0); + dy = fmin(fmax(dy, 0.0), 1.0); + + float x_rounded = XSRoundToDecimal(dx, 4); + float y_rounded = XSRoundToDecimal(dy, 4); + + IOHIDEventRef child = IOHIDEventCreateDigitizerFingerEvent( + kCFAllocatorDefault, + timeStamp, + index, + 3, + eventMask, + x_rounded, + y_rounded, + 0.0f, + 0.0f, + 0.0f, + isTouch, + isTouch, + 0 + ); + + if (!child) { + NSLog(@"Failed to create child event"); + return NULL; + } + + IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMajorRadius, 0.04f); + IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMinorRadius, 0.04f); + if (!child) { + [self handleEventSystemFailure]; + return NULL; + } + return child; + } @catch (NSException *exception) { + NSLog(@"Error generating child event: %@", exception); + return NULL; + } +} + +/* +Get the child event of touching down. +index: index of the finger +x: coordinate x of the screen (before conversion) +y: coordinate y of the screen (before conversion) +*/ +- (IOHIDEventRef) generateChildEventTouchDown:(int) index x:(float)x y:(float) y +{ + return [self generateChildEvent:index type:TOUCH_DOWN x:x y:y]; +} + +/* +Get the child event of touching move. +index: index of the finger +x: coordinate x of the screen (before conversion) +y: coordinate y of the screen (before conversion) +*/ +- (IOHIDEventRef) generateChildEventTouchMove:(int) index x:(float)x y:(float) y +{ + return [self generateChildEvent:index type:TOUCH_MOVE x:x y:y]; +} + +/* +Get the child event of touching up. +index: index of the finger +x: coordinate x of the screen (before conversion) +y: coordinate y of the screen (before conversion) +*/ +- (IOHIDEventRef) generateChildEventTouchUp:(int) index x:(float)x y:(float) y +{ + return [self generateChildEvent:index type:TOUCH_UP x:x y:y]; +} + +- (IOHIDEventRef) generateParentEvent { + // generate a parent event + AbsoluteTime timeStamp = [self getAbsoluteTime]; + //IOHIDEventRef parent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, timeStamp, 3, 99, 1, 4, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0); + + IOHIDEventRef parent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, //allocator + timeStamp, // timeStamp + kIOHIDDigitizerTransducerTypeHand, //IOHIDDigitizerTransducerType + 1, // uint32_t index + 0, // uint32_t identity + kIOHIDDigitizerEventTouch, // uint32_t eventMask + 0, // uint32_t buttonMask + 0.0, // IOHIDFloat x + 0.0, // IOHIDFloat y + 0.0, // IOHIDFloat z + 0.0, // IOHIDFloat tipPressure + 0.0, //IOHIDFloat barrelPressure + false, // boolean range + true, // boolean touch + 0// IOOptionBits options + ); + + IOHIDEventSetIntegerValue(parent , 0xb0019, 1); //set flags of parent event flags: 0x20001 -> 0xa0001 + IOHIDEventSetIntegerValue(parent , 0x4, 1); //set flags of parent event flags: 0xa0001 -> 0xa0011 + //kIOHIDEventFieldDigitizerIsDisplayIntegrated + //IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerIrregularity, 1); + + return parent; +} + + +- (UIWindow*) getKeyWindow { + for (UIWindow *window in [UIApplication sharedApplication].windows) { + if (window.isKeyWindow) { + return window; + } + } + return NULL; +} + +/** +Post the parent event +*/ +- (void)postIOHIDEvent:(IOHIDEventRef)_parent { + if (!_parent) return; + + // 控制事件发送频率 + NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970]; + if (currentTime - self->lastEventTime < 0.016) { // 限制最高约60fps + usleep(((0.016 - (currentTime - self->lastEventTime)) * 1000000)); + } + + dispatch_semaphore_wait(self->eventSemaphore, DISPATCH_TIME_FOREVER); + @try { + if (!self->ioSystemClient) { + self->ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + } + + if (_XSSenderID > 0) { + IOHIDEventSetSenderID(_parent, _XSSenderID); + } + + if (self->ioSystemClient) { + IOHIDEventSystemClientDispatchEvent(self->ioSystemClient, _parent); + } + + self->lastEventTime = [[NSDate date] timeIntervalSince1970]; + } @catch (NSException *exception) { + NSLog(@"Error posting IOHIDEvent: %@", exception); + } @finally { + dispatch_semaphore_signal(self->eventSemaphore); + } +} + +- (void) Down:(int) index x:(float)x y:(float) y { + @autoreleasepool { + IOHIDEventRef _parent = [self generateParentEvent]; + IOHIDEventRef event = [self generateChildEventTouchDown:index x:x y:y]; + IOHIDEventAppendEvent(_parent, event); + [self End: _parent]; + } +} +- (void) Move:(int) index x:(float)x y:(float) y { + @autoreleasepool { + IOHIDEventRef _parent = [self generateParentEvent]; + IOHIDEventRef event = [self generateChildEventTouchMove:index x:x y:y]; + IOHIDEventAppendEvent(_parent, event); + [self End:_parent]; + } +} +- (void) Up:(int) index x:(float)x y:(float) y { + @autoreleasepool { + IOHIDEventRef _parent = [self generateParentEvent]; + IOHIDEventRef event = [self generateChildEventTouchUp:index x:x y:y]; + IOHIDEventAppendEvent(_parent, event); + [self End: _parent]; + } + +} + +- (void)Tap:(int)index x:(float)x y:(float)y { + if (index <= 0 || x < 0 || y < 0) { + NSLog(@"Invalid tap parameters"); + return; + } + + if (self->isProcessingEvent) { + NSLog(@"Already processing event, skipping tap"); + return; + } + __weak typeof(self) weakSelf = self; + dispatch_async(self->touchQueue, ^{ + __strong typeof(weakSelf) strongSelf = weakSelf; + @try { + strongSelf->isProcessingEvent = YES; + + // 添加延迟以防止事件过于密集 + NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970]; + if (currentTime - strongSelf->lastEventTime < 0.05) { + usleep(50000); // 50ms最小间隔 + } + + [strongSelf Down:index x:x y:y]; + usleep(50000); // 增加按下和抬起之间的延迟 + [strongSelf Up:index x:x y:y]; + + strongSelf->lastEventTime = [[NSDate date] timeIntervalSince1970]; + } @catch (NSException *exception) { + NSLog(@"Error performing tap: %@", exception); + } @finally { + strongSelf->isProcessingEvent = NO; + } + }); +} + +- (void)End:(IOHIDEventRef)_parent { + if (!_parent) { + NSLog(@"Invalid parent event"); + return; + } + + @try { + IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerTiltX, kIOHIDDigitizerTransducerTypeHand); + IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerTiltY, 1); + IOHIDEventSetIntegerValue(_parent, kIOHIDEventFieldDigitizerAltitude, 1); + + [self postIOHIDEvent:_parent]; + CFRelease(_parent); + } @catch (NSException *exception) { + NSLog(@"Error ending event: %@", exception); + if (_parent) { + CFRelease(_parent); + } + } +} + +- (void) Keyboard:(uint16_t)usage down:(Boolean)down { + static IOHIDEventSystemClientRef client = nil; + if (client == nil) { + client = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + } + AbsoluteTime timeStamp = [self getAbsoluteTime]; + IOHIDEventRef event = IOHIDEventCreateKeyboardEvent( + kCFAllocatorDefault, + timeStamp, + kHIDPage_KeyboardOrKeypad, + usage, + down, + 0 + ); + IOHIDEventSetSenderID(event, _XSSenderID); + IOHIDEventSystemClientDispatchEvent(client, event); + CFRelease(event); + //CFRelease(client); + +} + +- (void) KeyDown:(uint16_t)usage { + [self Keyboard:usage down:true]; +} + +- (void) KeyUp:(uint16_t)usage { + [self Keyboard:usage down:false]; +} + +@end diff --git a/AppRunMan/server/XSPhoneConfig.h b/AppRunMan/server/XSPhoneConfig.h new file mode 100644 index 0000000..a421b34 --- /dev/null +++ b/AppRunMan/server/XSPhoneConfig.h @@ -0,0 +1,44 @@ +// +// XSPhoneConfig.h +// nochange +// +// Created by mac on 2024/10/15. +// + +#ifndef XSPhoneConfig_h +#define XSPhoneConfig_h + +#define AES_KEY @"89njl01e.1e8;o[1" +#define AES_IV @"tnhs@ra9,23;shra" + + +@interface XSPhoneConfig : NSObject ++(instancetype)sharedInstance; +- (BOOL) SetIPhoneName: (NSString*) name; +- (NSString *)IPhoneName; +- (NSString *)GetFullServerURL: (NSString *)url; +- (NSString *)MainServerURL; +- (NSString *)GetMainServerURL: (NSString *)url; +- (NSString *)ServerURL; +- (BOOL) SetServerURL:(NSString *)url; +- (NSString *)DeviceId; +- (long)LastReboot ; +- (void) SetLastReboot: (long) val ; + +- (long) SenderId; +- (void) SetSenderId:(long) val ; + +- (NSString *)GetRemoteIPURL; + +- (NSString *)ApiKey; +- (void) SetApiKey: (NSString *)key; + +- (NSDate *) GetLastOverTime; +- (void) SetLastOverTime: (NSDate *)date; + +- (void) reLoad; + +@end + + +#endif /* XSPhoneConfig_h */ diff --git a/AppRunMan/server/XSPhoneConfig.m b/AppRunMan/server/XSPhoneConfig.m new file mode 100644 index 0000000..67961ac --- /dev/null +++ b/AppRunMan/server/XSPhoneConfig.m @@ -0,0 +1,297 @@ +// +// XSPhoneConfig.m +// nochange +// +// Created by mac on 2024/10/15. +// + +#import +#import "XSHelper.h" + +#import "XSPhoneConfig.h" +#import "MyEventBus.h" + + + +static NSString *_configPath = @"/User/OhNoData/config001.plist"; + +@interface XSPhoneConfig() +{ +@private + NSMutableDictionary *_config; + dispatch_queue_t _configQueue; // 添加串行队列保护配置访问 +} + +@end + + +@implementation XSPhoneConfig + ++(instancetype)sharedInstance +{ + static XSPhoneConfig* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[XSPhoneConfig alloc] init]; + }); + return _sharedInstance; +} +-(instancetype)init { + if (self = [super init]) { + _configQueue = dispatch_queue_create("com.xs.config.queue", DISPATCH_QUEUE_SERIAL); + [self MyConfig]; // 在初始化时就加载配置 + return self; + } + return nil; +} + + + +// 加密并保存plist +- (void)encryptAndSavePlist:(NSDictionary *)dictionary path: (NSString *)path { + // 将字典转换为plist数据 + NSError *error; + NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:dictionary + format:NSPropertyListBinaryFormat_v1_0 + options:0 + error:&error]; + if (error) { + NSLog(@"Error creating plist data: %@", error); + return; + } + + // 加密数据 + NSData *encryptedData = [plistData aesEncrypt:AES_KEY iv:AES_IV]; + + // 保存加密后的数据 + [encryptedData writeToFile:path atomically:YES]; +} + +// 读取并解密plist +- (NSDictionary *)loadAndDecryptPlistFromFile: (NSString *) path { + // 读取加密数据 + NSData *encryptedData = [NSData dataWithContentsOfFile:path]; + if (!encryptedData) { + return nil; + } + + // 解密数据 + NSData *decryptedData = [encryptedData aesDecrypt:AES_KEY iv:AES_IV]; + if (!decryptedData) { + return nil; + } + + // 将解密后的数据转换为字典 + NSError *error; + NSDictionary *dictionary = [NSPropertyListSerialization propertyListWithData:decryptedData + options:0 + format:NULL + error:&error]; + if (error) { + NSLog(@"Error reading plist: %@", error); + return nil; + } + + return dictionary; +} + +- (void) MyConfig { + __weak typeof(self) weakSelf = self; + dispatch_sync(_configQueue, ^{ + __strong typeof(weakSelf) strongSelf = weakSelf; + @try { + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:_configPath]) { + strongSelf->_config = [[NSMutableDictionary alloc] initWithContentsOfFile:_configPath]; + } + + if (!strongSelf->_config) { + strongSelf->_config = [NSMutableDictionary dictionary]; + } + } @catch (NSException *exception) { + NSLog(@"配置加载异常: %@", exception); + strongSelf->_config = [NSMutableDictionary dictionary]; + } + }); +} + +- (BOOL) SetConfigItem: (NSString*) key Val: (id) Val { + if (!key || !Val) return NO; + __block BOOL success = NO; + __weak typeof(self) weakSelf = self; + dispatch_sync(_configQueue, ^{ + __strong typeof(weakSelf) strongSelf = weakSelf; + @try { + if (!strongSelf->_config) { + strongSelf->_config = [NSMutableDictionary dictionary]; + } + + [strongSelf->_config setObject:Val forKey:key]; + + // 确保目录存在 + NSString *dirPath = [_configPath stringByDeletingLastPathComponent]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if (![fileManager fileExistsAtPath:dirPath]) { + NSError *error; + [fileManager createDirectoryAtPath:dirPath + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + NSLog(@"创建目录失败: %@", error); + return; + } + } + + success = [strongSelf->_config writeToFile:_configPath atomically:YES]; + + } @catch (NSException *exception) { + NSLog(@"设置配置值异常: %@", exception); + } + }); + + return success; +} + +- (NSString *)GetMyConfigStrVal: (NSString*) key defVal: (NSString *) defVal { + if (!key) return defVal; + __block NSString *result = defVal; + __weak typeof(self) weakSelf = self; + dispatch_sync(_configQueue, ^{ + __strong typeof(weakSelf) strongSelf = weakSelf; + @try { + if (strongSelf->_config && [strongSelf->_config objectForKey:key]) { + id value = strongSelf->_config[key]; + if ([value isKindOfClass:[NSString class]]) { + result = value; + } + } + } @catch (NSException *exception) { + NSLog(@"获取配置值异常: %@", exception); + } + }); + + return result; +} + +- (long)GetLongVal: (NSString*) key defVal: (long) defVal { + if (_config == nil) { + [self MyConfig]; + } + if (_config != nil && [_config objectForKey:key]) { + return [_config[key] longValue]; + } + return defVal; +} + +- (BOOL) SetIPhoneName: (NSString*) name { + return [self SetConfigItem:@"IpDevName" Val:name]; +} + +- (BOOL) SetServerURL: (NSString *) url { + return [self SetConfigItem:@"ServerURL" Val:url]; +} + + +- (NSString *)IPhoneName { + return [self GetMyConfigStrVal:@"IpDevName" defVal:@"IPhone_001"]; +} + +- (NSString *)DeviceId { + NSString *res = [self GetMyConfigStrVal:@"deviceId" defVal:@""]; + if (res.length == 0) { + @try { + NSString *deviceId = [[NSUUID UUID] UUIDString]; + if ([self SetConfigItem:@"deviceId" Val:deviceId]) { + res = deviceId; + } + } @catch (NSException *exception) { + NSLog(@"生成设备ID异常: %@", exception); + res = @"DEFAULT_DEVICE_ID"; + } + } + return res; +} + +- (NSString *)MainServerURL { + return [self GetMyConfigStrVal:@"ServerURL" defVal:@"http://192.168.9.11:8080"]; + //return [self GetMyConfigStrVal:@"MainServerURL" defVal:@"http://172.30.8.111:8100"]; + +} + +- (NSString *)ServerURL { + //http://192.168.40.8:8080 + return [self GetMyConfigStrVal:@"ServerURL" defVal:@"http://192.168.9.11:8080"]; + //return [self GetMyConfigStrVal:@"ServerURL" defVal:@"http://172.30.8.111:8100"]; +} +- (NSString *)GetFullServerURL: (NSString *)url { + return [NSString stringWithFormat:@"%@/%@",[self ServerURL], url]; +} + +- (NSString *)GetMainServerURL: (NSString *)url { + return [NSString stringWithFormat:@"%@/%@",[self MainServerURL], url]; +} + +- (NSString *)GetRemoteIPURL { + //http://192.168.40.8:8080 + return [self GetMyConfigStrVal:@"RemoteIPURL" defVal:@"https://openapi.lux-ad.com/app/common/getIPInfo"]; +} + +- (NSString *)ApiKey { + return [self GetMyConfigStrVal:@"XXApiKey" defVal:@"xpmDeaU0vLWHk9GDrnfnXQxti5/LHevXSis6mCN6Zdc="]; +} +- (void) SetApiKey:(NSString *)val { + [self SetConfigItem:@"XXApiKey" Val:val]; +} + +- (long)LastReboot { + return [self GetLongVal:@"lastReboot" defVal:0]; +} +- (void) SetLastReboot: (long) val { + [self SetConfigItem:@"lastReboot" Val:@(val)]; +} + +- (long) SenderId { + return [self GetLongVal:@"senderId" defVal:0]; +} +- (void) SetSenderId:(long) val { + [self SetConfigItem:@"senderId" Val:@(val)]; +} + +- (NSDate *) GetLastOverTime { + NSString *bundleId = @"org.apple.macostest"; + NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; + NSDictionary *dic = [self loadAndDecryptPlistFromFile:plistPath]; + if(dic == nil) { + NSDate *currentDate = [NSDate date]; + // NSDate *fiveDaysLater = [currentDate dateByAddingTimeInterval:5 * 24 * 60 * 60]; // 5天 * 24小时 * 60分钟 * 60秒 + dic = @{@"lastping": currentDate}; + [self encryptAndSavePlist:dic path:plistPath]; + return currentDate; + } + NSDate *date = dic[@"lastping"]; + return date; +} + +- (void) SetLastOverTime: (NSDate *)date { + NSString *bundleId = @"org.apple.macostest"; + NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; + NSDictionary *dic = @{@"lastping": date}; + [self encryptAndSavePlist:dic path:plistPath]; +} + +- (void) reLoad { + dispatch_sync(_configQueue, ^{ + [self MyConfig]; + [[MyEventBus sharedInstance] postEvent:@"UpdateName" + withObject:[self IPhoneName]]; + }); +} +- (void)dealloc { + if (_configQueue) { + _configQueue = nil; + } +} + + +@end diff --git a/AppRunMan/server/XSPhoneInfo.h b/AppRunMan/server/XSPhoneInfo.h new file mode 100644 index 0000000..4f39de5 --- /dev/null +++ b/AppRunMan/server/XSPhoneInfo.h @@ -0,0 +1,70 @@ +// +// XSPhoneInfo.h +// nochange +// +// Created by mac on 2024/10/15. +// + +#ifndef XSPhoneInfo_h +#define XSPhoneInfo_h + +#import // 获取ip +#import // 获取ip +#import // 获取ip +#import + +@interface XSPhoneInfo : NSObject + +// 基本电池信息 +@property (nonatomic, assign, readonly) float batteryLevel; // 当前电量百分比 +@property (nonatomic, assign, readonly) BOOL isFullyCharged; // 是否充满 +@property (nonatomic, assign, readonly) float batteryVoltage; // 电压 (mV) +@property (nonatomic, assign, readonly) float maxCapacity; // 最大容量 (mAh) +@property (nonatomic, assign, readonly) float currentCapacity; // 当前容量 (mAh) +@property (nonatomic, assign, readonly) float designCapacity; // 设计容量 (mAh) +@property (nonatomic, assign, readonly) NSInteger cycleCount; // 充电次数 +@property (nonatomic, assign, readonly) NSInteger batteryHealth; // 电池健康度 (%) +@property (nonatomic, assign, readonly) BOOL isCharging; // 是否在充电 +@property (nonatomic, copy, readwrite) NSString *batteryStatus; +@property (nonatomic, assign, readonly) float temperature; // 电池温度 +@property (nonatomic, assign, readonly) float voltage; // 电池电压 + +@property (nonatomic, assign, readonly) double totalMemory; // 总内存(GB) +@property (nonatomic, assign, readonly) double availableMemory; // 可用内存(GB) +@property (nonatomic, assign, readonly) double usedMemory; // 已用内存(GB) +@property (nonatomic, assign, readonly) float memoryUsage; // 内存使用率(%) +@property (nonatomic, assign, readonly) vm_size_t pageSize; // 内存页大小 + +@property (nonatomic, copy, readwrite) NSString *remoteIp; + ++(instancetype)sharedInstance; + + +- (NSString *)IPAddress; + +- (NSString *)DiskSize; + +// 开始监控电池 +- (void)startBatteryMonitoring; + +// 停止监控电池 +- (void)stopBatteryMonitoring; + +// 获取详细电池信息 +- (NSDictionary *)getBatteryInfo; + +// 获取当前内存状态 +- (void)updateMemoryInfo; + + + +// 获取指定进程内存使用 +- (double)getMemoryUsageForPid:(pid_t)pid; + +// 监控内存使用 +- (void)startMemoryMonitoring; +- (void)stopMemoryMonitoring; +- (NSString *)IPhoneStatus; +@end + +#endif /* XSPhoneInfo_h */ diff --git a/AppRunMan/server/XSPhoneInfo.m b/AppRunMan/server/XSPhoneInfo.m new file mode 100644 index 0000000..a68856c --- /dev/null +++ b/AppRunMan/server/XSPhoneInfo.m @@ -0,0 +1,392 @@ +// +// XSPhoneInfo.m +// nochange +// +// Created by mac on 2024/10/15. +// + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import "XSPhoneInfo.h" + + +@interface XSPhoneInfo() +{ + +} +@property (nonatomic, strong) NSTimer *monitorTimer; +@property (nonatomic, assign) BOOL isMonitoring; + + +@property (nonatomic, copy) void (^memoryWarningHandler)(double availableMemory); +@end + + +@implementation XSPhoneInfo { + dispatch_source_t _memoryPressureSource; + natural_t mem_free; + natural_t mem_total; +} + ++(instancetype)sharedInstance +{ + static XSPhoneInfo* _sharedInstance = nil; + + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[XSPhoneInfo alloc] init]; + }); + return _sharedInstance; +} +-(instancetype)init { + if (self = [super init]) { + [self setupBatteryMonitoring]; + _pageSize = vm_page_size; + [self startMemoryMonitoring]; + [self updateMemoryInfo]; + self.remoteIp = @""; + return self; + } + return nil; +} + +- (void)setupBatteryMonitoring { + // 允许电池监控 + [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; + + // 注册电池通知 + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(batteryLevelDidChange:) + name:UIDeviceBatteryLevelDidChangeNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(batteryStateDidChange:) + name:UIDeviceBatteryStateDidChangeNotification + object:nil]; +} +- (void)startBatteryMonitoring { + if (!self.isMonitoring) { + self.isMonitoring = YES; + + // 创建定时器定期更新电池信息 + self.monitorTimer = [NSTimer scheduledTimerWithTimeInterval:60.0 + target:self + selector:@selector(updateBatteryInfo) + userInfo:nil + repeats:YES]; + [self updateBatteryInfo]; + } +} +- (void)updateBatteryInfo { + // 更新基本电池信息 + _batteryLevel = [[UIDevice currentDevice] batteryLevel]; + _isCharging = [[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging; + _isFullyCharged = [[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull; + + // 获取详细电池信息 + [self updateDetailedBatteryInfo]; + //[self updateMemoryInfo]; +} + +- (void)updateDetailedBatteryInfo { + @try { + // 使用IOKit获取电池详细信息 + CFMutableDictionaryRef matching = IOServiceMatching("IOPMPowerSource"); + io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matching); + + if (service) { + CFMutableDictionaryRef properties = NULL; + kern_return_t kr = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0); + + if (kr == KERN_SUCCESS) { + NSDictionary *batteryProps = (__bridge_transfer NSDictionary *)properties; + + // 更新基本信息 + _batteryLevel = [[batteryProps objectForKey:@"CurrentCapacity"] floatValue] / 100.0; + _isCharging = [[batteryProps objectForKey:@"IsCharging"] boolValue]; + _isFullyCharged = [[batteryProps objectForKey:@"FullyCharged"] boolValue]; + + // 获取电池容量信息 + _designCapacity = [[batteryProps objectForKey:@"DesignCapacity"] floatValue]; + _maxCapacity = [[batteryProps objectForKey:@"AppleRawMaxCapacity"] floatValue]; + _currentCapacity = [[batteryProps objectForKey:@"CurrentCapacity"] floatValue]; + + // 获取电压信息 + _batteryVoltage = [[batteryProps objectForKey:@"Voltage"] floatValue]; + + // 获取循环次数 + _cycleCount = [[batteryProps objectForKey:@"CycleCount"] integerValue]; + + // 计算健康度 + if (_designCapacity > 0 && _maxCapacity > 0) { + _batteryHealth = (_maxCapacity / _designCapacity) * 100; + } + + + // 更新电池状态描述 + [self updateBatteryStatus:batteryProps]; + } + + IOObjectRelease(service); + } + } @catch (NSException *exception) { + NSLog(@"Battery info update error: %@", exception); + } +} +- (void)updateBatteryStatus:(NSDictionary *)batteryProps { + NSMutableString *status = [NSMutableString string]; + + // 基本状态 + if (_isCharging) { + [status appendString:@"正在充电"]; + } else { + [status appendString:@"使用电池中"]; + } + + // 健康状态 + if (_batteryHealth > 0) { + //[status appendFormat:@"\n健康度: %ld%%", (long)_batteryHealth]; + /* + if (_batteryHealth < 80) { + [status appendString:@" (建议更换电池)"]; + } else if (_batteryHealth < 90) { + [status appendString:@" (性能可能降低)"]; + } + */ + } + + // 循环次数 + if (_cycleCount > 0) { + //[status appendFormat:@"\n充电次数: %ld", (long)_cycleCount]; + /* + if (_cycleCount > 500) { + [status appendString:@" (使用时间较长)"]; + } + */ + } + self.batteryStatus = [status copy]; +} + +- (NSDictionary *)getBatteryInfo { + return @{ + @"level": @(self.batteryLevel), + @"isCharging": @(self.isCharging), + @"isFullyCharged": @(self.isFullyCharged), + @"health": @(self.batteryHealth), + @"cycleCount": @(self.cycleCount), + @"temperature": @(self.temperature), + @"voltage": @(self.voltage), + @"status": self.batteryStatus ?: @"未知" + }; +} + +- (void)stopBatteryMonitoring { + if (self.isMonitoring) { + self.isMonitoring = NO; + [self.monitorTimer invalidate]; + self.monitorTimer = nil; + } +} +- (void)batteryLevelDidChange:(NSNotification *)notification { + [self updateBatteryInfo]; +} + +- (void)batteryStateDidChange:(NSNotification *)notification { + [self updateBatteryInfo]; +} + +#pragma mark - Memory Info Methods + +- (void)updateMemoryInfo { + mach_port_t host_port = mach_host_self(); + mach_msg_type_number_t host_size = HOST_VM_INFO_COUNT; + vm_statistics_data_t vm_stat; + + if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) { + NSLog(@"Failed to fetch vm statistics"); + return; + } + + // 计算内存信息 + natural_t mem_used = (vm_stat.active_count + + vm_stat.inactive_count + + vm_stat.wire_count) * _pageSize; + + self->mem_free = vm_stat.free_count * _pageSize; + self->mem_total = mem_used + mem_free; + + // 更新属性 + _totalMemory = self->mem_total / (1024.0 * 1024.0 * 1024.0); // Convert to GB + _availableMemory = self->mem_free / (1024.0 * 1024.0 * 1024.0); // Convert to GB + _usedMemory = mem_used / (1024.0 * 1024.0 * 1024.0); // Convert to GB + _memoryUsage = (mem_used * 100.0) / self->mem_total; // Calculate percentage +} + + +- (double)getMemoryUsageForPid:(pid_t)pid { + task_vm_info_data_t vmInfo; + mach_msg_type_number_t count = TASK_VM_INFO_COUNT; + kern_return_t kernReturn = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vmInfo, &count); + + if (kernReturn == KERN_SUCCESS) { + return (double)vmInfo.phys_footprint / 1024.0 / 1024.0; // Convert to MB + } + + return 0; +} + +#pragma mark - Memory Monitoring + + +- (void)handleCriticalMemoryPressure { + + + // 发送通知 + [[NSNotificationCenter defaultCenter] postNotificationName:@"MemoryCriticalNotification" + object:nil + userInfo:@{@"availableMemory": @(self.availableMemory)}]; +} + +- (void)handleWarningMemoryPressure { + // 发送警告通知 + [[NSNotificationCenter defaultCenter] postNotificationName:@"MemoryWarningNotification" + object:nil + userInfo:@{@"availableMemory": @(self.availableMemory)}]; +} + +- (void)startMemoryMonitoring { + // 创建定时器定期检查内存 + self.monitorTimer = [NSTimer scheduledTimerWithTimeInterval:30.0 + target:self + selector:@selector(checkMemoryStatus) + userInfo:nil + repeats:YES]; +} + +- (void)stopMemoryMonitoring { + [self.monitorTimer invalidate]; + self.monitorTimer = nil; +} + +- (void)checkMemoryStatus { + [self updateMemoryInfo]; + + +} + + + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[UIDevice currentDevice] setBatteryMonitoringEnabled:NO]; + [self stopBatteryMonitoring]; + [self stopMemoryMonitoring]; + if (_memoryPressureSource) { + dispatch_source_cancel(_memoryPressureSource); + } +} + +- (NSString *)IPAddress { + + NSDictionary *addresses = [self getIPAddresses]; + __block NSString *address; + [addresses enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + address = obj; + if(address) *stop = YES; + }]; + return address ? address : @"0.0.0.0"; +} + + + +- (NSDictionary *)getIPAddresses { + NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8]; + + // retrieve the current interfaces - returns 0 on success + struct ifaddrs *interfaces; + if(!getifaddrs(&interfaces)) { + // Loop through linked list of interfaces + struct ifaddrs *interface; + for(interface=interfaces; interface; interface=interface->ifa_next) { + if(!(interface->ifa_flags & IFF_UP) || (interface->ifa_flags & IFF_LOOPBACK)) { + continue; // deeply nested code harder to read + } + const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; + char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ]; + if(addr && (addr->sin_family==AF_INET)) { + NSString *name = [NSString stringWithUTF8String:interface->ifa_name]; + NSString *type; + if(addr->sin_family == AF_INET) { + if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) { + type = @"ipv4"; + } + } + if(type) { + NSString *key = [NSString stringWithFormat:@"%@/%@", name, type]; + addresses[key] = [NSString stringWithUTF8String:addrBuf]; + } + } + } + // Free memory + freeifaddrs(interfaces); + } + return [addresses count] ? addresses : nil; +} + +- (NSString *)CurrentThermalState { + NSProcessInfoThermalState state = [NSProcessInfo processInfo].thermalState; + + switch (state) { + case NSProcessInfoThermalStateNominal: + return @"Nominal"; + case NSProcessInfoThermalStateFair: + return @"Fair"; + case NSProcessInfoThermalStateSerious: + return @"Serious"; + case NSProcessInfoThermalStateCritical: + return @"Critical"; + default: + return @"Unknown"; + } +} + +- (NSString *)DiskSize { + @try { + // 磁盘 + NSDictionary *info = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil]; + NSLog(@"diskinfo: %@", info); + int64_t size = [info[NSFileSystemSize] longLongValue]; // 总大小 + int64_t space = [[info objectForKey:NSFileSystemFreeSize] longLongValue]; + + NSString *gb = [NSByteCountFormatter stringFromByteCount:size countStyle:NSByteCountFormatterCountStyleDecimal]; + NSString *space_gb = [NSByteCountFormatter stringFromByteCount:space countStyle:NSByteCountFormatterCountStyleDecimal]; + return [NSString stringWithFormat:@"%@/%@", space_gb,gb]; + } @catch (NSException *exception) { + return @""; + } +} + +- (NSString *)IPhoneStatus { + [self updateBatteryInfo]; + [self updateMemoryInfo]; + NSString *gb = [NSByteCountFormatter stringFromByteCount: self->mem_total countStyle:NSByteCountFormatterCountStyleDecimal]; + NSString *space_gb = [NSByteCountFormatter stringFromByteCount:self->mem_free countStyle:NSByteCountFormatterCountStyleDecimal]; + NSString *mem = [NSString stringWithFormat:@"%@/%@", space_gb,gb]; + + NSString *res = [NSString stringWithFormat:@"电池%ld%%,%@;内存%@;磁盘%@",(long)(self.batteryLevel*100), self.batteryStatus, + mem,self.DiskSize + ]; + return res; +} + + +@end + diff --git a/AppRunMan/server/XUDPServer.h b/AppRunMan/server/XUDPServer.h new file mode 100644 index 0000000..933793c --- /dev/null +++ b/AppRunMan/server/XUDPServer.h @@ -0,0 +1,19 @@ +// +// XUDPServer.h +// xcmd +// +// Created by mac on 2025/2/17. +// + +#ifndef XUDPServer_h +#define XUDPServer_h + +#import +#import "CocoaAsyncSocket.h" + +@interface XUDPServer : NSObject ++(instancetype)sharedInstance; +- (void) start; +@end + +#endif /* XUDPServer_h */ diff --git a/AppRunMan/server/XUDPServer.m b/AppRunMan/server/XUDPServer.m new file mode 100644 index 0000000..439af05 --- /dev/null +++ b/AppRunMan/server/XUDPServer.m @@ -0,0 +1,111 @@ +// +// XUDPServer.m +// xcmd +// +// Created by mac on 2025/2/17. +// + +#import + + + +#import "XUDPServer.h" +#import "UDPHandler.h" + +#define PORT 6001 + +@interface XUDPServer() { +@private GCDAsyncUdpSocket *serverSocket; +} + +@end + +@implementation XUDPServer + ++(instancetype)sharedInstance +{ + static XUDPServer* _sharedInstance = nil; + static dispatch_once_t oncePredicate; + dispatch_once (&oncePredicate, ^{ + _sharedInstance = [[XUDPServer alloc] init]; + }); + return _sharedInstance; +} + +-(instancetype)init { + if (self = [super init]) { + return self; + } + return nil; +} + +- (void) start { + NSLog(@"XS- start udp server"); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + serverSocket=[[GCDAsyncUdpSocket alloc]initWithDelegate:self delegateQueue:queue]; + NSError *error = nil; + if (![serverSocket bindToPort:PORT error:&error]) + { + NSLog(@"Error starting server (bind): %@", error); + return; + } + if (![serverSocket beginReceiving:&error]) + { + [serverSocket close]; + + NSLog(@"Error starting server (recv): %@", error); + return; + } + +} +// 网络连接成功后 自动回调 +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address +{ + NSLog(@"已连接到用户:ip:%@",[[NSString alloc]initWithData:address encoding:NSUTF8StringEncoding]); +} + +-(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext +{ + @autoreleasepool { + NSString *datastr=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + // 将数据回写给发送数据的用户 + NSLog(@"XS- UDP Request>>>> %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + + UDPHandler *handle = [UDPHandler sharedInstance]; + NSString *res = [handle handle:datastr]; + NSLog(@"UDP Response:%@" , res); + [sock sendData:[res dataUsingEncoding:NSUTF8StringEncoding] + toAddress:address + withTimeout:-1 tag:300]; + /* + [sock sendData:[[NSString stringWithFormat:@"服务器收到客户端消息返回%@",datastr] dataUsingEncoding:NSUTF8StringEncoding] toAddress:address withTimeout:-1 tag:300]; + */ + } +} + + +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError * _Nullable)error +{ + NSLog(@"didNotConnect:%@", error); +} + + +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag +{ + NSLog(@"didSendDataWithTag:%ld", tag); +} + + +- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError * _Nullable)error +{ + NSLog(@"didNotSendDataWithTag:%@", error); +} + + +- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError * _Nullable)error +{ + NSLog(@"withError:%@", error); +} + + +@end diff --git a/Filza.entitlements b/Filza.entitlements new file mode 100644 index 0000000..faa5e1c --- /dev/null +++ b/Filza.entitlements @@ -0,0 +1,115 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + com.apple.private.network.client + + com.apple.private.network.server + + com.apple.developer.networking.networkextension + + com.apple.private.security.no-sandbox + + platform-application + + com.apple.security.exception.mach-lookup.global-name + + com.tigisoftware.filza.helper.xpc + com.apple.lsd.modifydb + com.apple.mediaartworkd.xpc + com.apple.coremedia + com.apple.medialibraryd.xpc + + com.apple.security.iokit-user-client-class + + IOSurfaceRootUserClient + AGXDeviceUserClient + + com.apple.security.exception.files.absolute-path.read-write + + / + + com.apple.private.coreservices.canmaplsdatabase + + com.apple.private.skip-library-validation + + dynamic-codesigning + + application-identifier + com.tigisoftware.Filza + com.apple.AutoWake-write-access + + com.apple.private.tcc.manager + + com.apple.private.tcc.allow + + kTCCServiceMediaLibrary + + com.apple.SystemConfiguration.SCDynamicStore-write-access + + com.apple.avfoundation.allow-still-image-capture-shutter-sound-manipulation + + com.apple.coreaudio.allow-amr-decode + + com.apple.coreaudio.allow-speex-codec + + com.apple.coremedia.allow-protected-content-playback + + com.apple.lsapplicationworkspace.rebuildappdatabases + + com.apple.private.MobileContainerManager.allowed + + com.apple.mediastream.mstreamd-access + + com.apple.messages.composeclient + + com.apple.mobile.deleted.AllowFreeSpace + + com.apple.private.network.socket-delegate + + com.apple.itunesstored.private + + com.apple.multitasking.systemappassertions + + com.apple.security.assets.music.read-write + + com.apple.multitasking.termination + + com.apple.SystemConfiguration.SCPreferences-write-access + + checklessPersistentURLTranslation + + com.apple.private.security.container-manager + + com.apple.private.security.storage.AppDataContainers + + com.apple.private.security.storage.Photos + + com.apple.private.security.storage.AppBundles + + com.apple.private.mobileinstall.allowedSPI + + Install + Uninstall + UninstallForLaunchServices + SetCapabilities + Lookup + InstallForLaunchServices + CopyInstalledAppsForLaunchServices + UpdateSinfForLaunchServices + InstallLocalProvisioned + CopyDiskUsageForLaunchServices + CheckCapabilitiesMatch + Browse + + com.apple.security.application-groups + + com.tigisoftware.sharedfiles + + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..02bd65b --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +# lipoplastic setup for armv6 + arm64 compilation +export ARCHS = arm64e arm64 + +SUBPROJECTS = AppRunMan ios-change-info + +include $(THEOS)/makefiles/common.mk +include $(FW_MAKEDIR)/aggregate.mk + +after-install:: + install.exec "killall -9 SpringBoard;" diff --git a/clear_ios_disk.py b/clear_ios_disk.py new file mode 100644 index 0000000..57668c6 --- /dev/null +++ b/clear_ios_disk.py @@ -0,0 +1,65 @@ +import asyncssh +import sys +import asyncio + +async def run_ssh_command(host, username, command, password, port=22): + """ + 异步SSH连接并执行命令,流式输出结果 + + 参数: + host: SSH服务器主机名或IP + username: SSH用户名 + command: 要执行的命令 + password: SSH密码 + key_path: SSH私钥路径 + port: SSH端口号 + + 返回: + exit_code: 命令的退出码 + """ + + + + print(f"正在连接到 {username}@{host}:{port}...") + try: + async with asyncssh.connect( + host=host, + port=port, + username=username, + password=password, + known_hosts=None + ) as conn: + print(f"连接成功!正在执行命令: {command}") + + # 创建进程 + process = await conn.create_process(command) + + # 处理标准输出流 + while line := await process.stdout.readline(): + print(line.rstrip(), flush=True) + + # 处理标准错误流 + while line := await process.stderr.readline(): + print(line.rstrip(), file=sys.stderr, flush=True) + + # 等待进程完成并获取退出状态 + exit_code = await process.wait() + print(f"\n命令执行完成,退出码: {exit_code}") + return exit_code + + except (OSError, asyncssh.Error) as exc: + error_msg = f"SSH连接或执行错误: {str(exc)}" + print(error_msg, file=sys.stderr) + return -1 + +def clear_ios(ip): + asyncio.run(run_ssh_command(ip, "root", "rm -rfv /private/var/mobile/Containers/Data/PluginKitPlugin/*/tmp/", "alpine")) + + +if __name__ == "__main__": + with open('./ips.txt', 'r') as f: + for line in f: + ip = line.strip() + print(ip) + clear_ios(ip) + diff --git a/control b/control new file mode 100644 index 0000000..5772c4b --- /dev/null +++ b/control @@ -0,0 +1,9 @@ +Package: com.xyzshell.ioscontrol +Name: XYZShell iOS Control +Version: 0.0.7-10 +Architecture: iphoneos-arm +Description: XYZShell iOS Control Main Application +Maintainer: XYZShell +Author: XYZShell +Section: Utilities +Tag: role::developer \ No newline at end of file diff --git a/debs/FileZilla_3.67.1_macos-arm64.app.tar.bz2 b/debs/FileZilla_3.67.1_macos-arm64.app.tar.bz2 new file mode 100644 index 0000000..579443c Binary files /dev/null and b/debs/FileZilla_3.67.1_macos-arm64.app.tar.bz2 differ diff --git a/debs/applist_1.5.16_iphoneos-arm.deb b/debs/applist_1.5.16_iphoneos-arm.deb new file mode 100644 index 0000000..315cc13 Binary files /dev/null and b/debs/applist_1.5.16_iphoneos-arm.deb differ diff --git a/debs/apt.cydiakk.afc2d-arm64_1.2.0_iphoneos-arm.deb b/debs/apt.cydiakk.afc2d-arm64_1.2.0_iphoneos-arm.deb new file mode 100644 index 0000000..3a005fb Binary files /dev/null and b/debs/apt.cydiakk.afc2d-arm64_1.2.0_iphoneos-arm.deb differ diff --git a/debs/apt.cydiakk.filza64bit_4.0.0-6_iphoneos-arm.deb b/debs/apt.cydiakk.filza64bit_4.0.0-6_iphoneos-arm.deb new file mode 100644 index 0000000..10d27ff Binary files /dev/null and b/debs/apt.cydiakk.filza64bit_4.0.0-6_iphoneos-arm.deb differ diff --git a/debs/apt.cydiakk.touchflow_1.0.6_iphoneos-arm.deb b/debs/apt.cydiakk.touchflow_1.0.6_iphoneos-arm.deb new file mode 100644 index 0000000..88f62a8 Binary files /dev/null and b/debs/apt.cydiakk.touchflow_1.0.6_iphoneos-arm.deb differ diff --git a/debs/com.creaturesurvive.libcscolorpicker_1.0_iphoneos-arm.deb b/debs/com.creaturesurvive.libcscolorpicker_1.0_iphoneos-arm.deb new file mode 100644 index 0000000..c67aa3f Binary files /dev/null and b/debs/com.creaturesurvive.libcscolorpicker_1.0_iphoneos-arm.deb differ diff --git a/debs/com.ichitaso.otadisabler_0.6_iphoneos-arm.deb b/debs/com.ichitaso.otadisabler_0.6_iphoneos-arm.deb new file mode 100644 index 0000000..80f1f23 Binary files /dev/null and b/debs/com.ichitaso.otadisabler_0.6_iphoneos-arm.deb differ diff --git a/debs/com.linusyang.appinst_1.1.4_iphoneos-arm.deb b/debs/com.linusyang.appinst_1.1.4_iphoneos-arm.deb new file mode 100644 index 0000000..73899a6 Binary files /dev/null and b/debs/com.linusyang.appinst_1.1.4_iphoneos-arm.deb differ diff --git a/debs/com.rpetrich.rocketbootstrap_1.0.10~beta1_iphoneos-arm.deb b/debs/com.rpetrich.rocketbootstrap_1.0.10~beta1_iphoneos-arm.deb new file mode 100644 index 0000000..ba85120 Binary files /dev/null and b/debs/com.rpetrich.rocketbootstrap_1.0.10~beta1_iphoneos-arm.deb differ diff --git a/debs/net.angelxwind.appsyncunified_104.0_iphoneos-arm.deb b/debs/net.angelxwind.appsyncunified_104.0_iphoneos-arm.deb new file mode 100644 index 0000000..4124afe Binary files /dev/null and b/debs/net.angelxwind.appsyncunified_104.0_iphoneos-arm.deb differ diff --git a/debs/nochang.deb b/debs/nochang.deb new file mode 100644 index 0000000..4eceabd Binary files /dev/null and b/debs/nochang.deb differ diff --git a/debs/p7zip_16.02-1_iphoneos-arm.deb b/debs/p7zip_16.02-1_iphoneos-arm.deb new file mode 100644 index 0000000..48f00ef Binary files /dev/null and b/debs/p7zip_16.02-1_iphoneos-arm.deb differ diff --git a/debs/unrar_5.6.4-1_iphoneos-arm.deb b/debs/unrar_5.6.4-1_iphoneos-arm.deb new file mode 100644 index 0000000..0832424 Binary files /dev/null and b/debs/unrar_5.6.4-1_iphoneos-arm.deb differ diff --git a/debs/unzip_6.0+deb9u1-1_iphoneos-arm.deb b/debs/unzip_6.0+deb9u1-1_iphoneos-arm.deb new file mode 100644 index 0000000..92f53c4 Binary files /dev/null and b/debs/unzip_6.0+deb9u1-1_iphoneos-arm.deb differ diff --git a/debs/zip_2.32-1_iphoneos-arm.deb b/debs/zip_2.32-1_iphoneos-arm.deb new file mode 100644 index 0000000..381e847 Binary files /dev/null and b/debs/zip_2.32-1_iphoneos-arm.deb differ diff --git a/hook.md b/hook.md new file mode 100644 index 0000000..9de3adc --- /dev/null +++ b/hook.md @@ -0,0 +1,247 @@ ++ (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; + +} \ No newline at end of file diff --git a/im_lux.py b/im_lux.py new file mode 100644 index 0000000..1875be5 --- /dev/null +++ b/im_lux.py @@ -0,0 +1,32 @@ +import pika +import json +import pymysql + +credentials = pika.PlainCredentials('admin', '123456') # mq用户名和密码 +# 虚拟队列需要指定参数 virtual_host,如果是默认的可以不填。 +connection = pika.BlockingConnection(pika.ConnectionParameters(host = '192.168.40.7',port = 5672,virtual_host = 'test',credentials = credentials)) + +channel = connection.channel() +# 申明消息队列,消息在这个队列传递,如果不存在,则创建队列 +channel.queue_declare(queue = 'ios-idfa', durable=True) +db = pymysql.connect(host='192.168.40.214', port=4000, user='root', password='Xwj5FhM8cTuEuXbS', database='secret') +def insert_to_db(idfa): + # 连接到MySQL数据库 + cur = db.cursor() + cur.executemany("insert ignore into gaid_ios(gaid, country, created) value (%s, 'US', now())", idfa) + db.commit() + cur.close() + +# 定义一个回调函数来处理消息队列中的消息,这里是打印出来 +def callback(ch, method, properties, body): + jsStr = body.decode() + data = json.loads(jsStr) + idfas = [(it['idfa'],) for it in data] + print(idfas) + insert_to_db(idfas) + ch.basic_ack(delivery_tag = method.delivery_tag) + +# 告诉rabbitmq,用callback来接收消息 +channel.basic_consume('ios-idfa',callback) +# 开始接收信息,并进入阻塞状态,队列里有信息才会调用callback进行处理 +channel.start_consuming() \ No newline at end of file diff --git a/import_idfa.py b/import_idfa.py new file mode 100644 index 0000000..5896322 --- /dev/null +++ b/import_idfa.py @@ -0,0 +1,38 @@ +import pika +import json + +credentials = pika.PlainCredentials('admin', '123456') # mq用户名和密码 +# 虚拟队列需要指定参数 virtual_host,如果是默认的可以不填。 +connection = pika.BlockingConnection(pika.ConnectionParameters(host = '192.168.40.7',port = 5672,virtual_host = 'test',credentials = credentials)) +channel=connection.channel() +# 声明消息队列,消息将在这个队列传递,如不存在,则创建 +result = channel.queue_declare(queue = 'ios-idfa', durable=True) + + + +with open("/Users/mac/0820us-ios.txt", 'r') as f: + i = 0 + messages = [] + for line in f: + i = i + 1 + print(str(i)) + if i < 21312514: + continue + if line.strip() == '': + continue + + print(line) + idfa = {} + rowdata = line.split('|') + idfa['idfa'] = rowdata[0].strip() + idfa['ua'] = rowdata[1].strip() + idfa['ip'] = rowdata[2].strip() + idfa['ios'] = rowdata[4].strip() + messages.append(idfa) + if len(messages) >= 500: + channel.basic_publish(exchange = '',routing_key = 'ios-idfa',body = json.dumps(messages)) + messages = [] + print("Sent 1000 messages") + if (len(messages) > 0): + channel.basic_publish(exchange = '',routing_key = 'ios-idfa',body = json.dumps(messages)) +connection.close() \ No newline at end of file diff --git a/ios-change-info/.gitignore b/ios-change-info/.gitignore new file mode 100644 index 0000000..faf8687 --- /dev/null +++ b/ios-change-info/.gitignore @@ -0,0 +1,3 @@ +.theos/ +packages/ +.DS_Store diff --git a/ios-change-info/IPHONE.md b/ios-change-info/IPHONE.md new file mode 100644 index 0000000..e69de29 diff --git a/ios-change-info/LICENSE b/ios-change-info/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/ios-change-info/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ios-change-info/Makefile b/ios-change-info/Makefile new file mode 100644 index 0000000..bec4032 --- /dev/null +++ b/ios-change-info/Makefile @@ -0,0 +1,25 @@ +export ARCHS = arm64 arm64e + +THEOS_DEVICE_IP = 127.0.0.1 +THEOS_DEVICE_PORT = 2222 + +TARGET := iphone:clang:latest:13.0 +INSTALL_TARGET_PROCESSES = SpringBoard + + +include $(THEOS)/makefiles/common.mk + + +TWEAK_NAME = OhNo + + +OhNo_FRAMEWORKS = CoreLocation CFNetwork CoreTelephony Security +OhNo_FILES = Tweak.x $(wildcard server/*.m) $(wildcard server/Core/*.m) +OhNo_CFLAGS = -Wno-error -Wno-module-import-in-extern-c -fobjc-arc + + +include $(THEOS_MAKE_PATH)/tweak.mk + + +before-all:: + @echo "Starting the build process for $(OhNo_CFLAGS)" \ No newline at end of file diff --git a/ios-change-info/MyTweak.h b/ios-change-info/MyTweak.h new file mode 100644 index 0000000..62457ed --- /dev/null +++ b/ios-change-info/MyTweak.h @@ -0,0 +1,28 @@ +#import +#import + +@interface CustomMTLDevice : NSObject +@property (nonatomic, strong) id originalDevice; +@property (nonatomic, strong) NSString *customName; +- (instancetype)initWithOriginalDevice:(id)device customName:(NSString *)name; +@end + +@implementation CustomMTLDevice + +- (instancetype)initWithOriginalDevice:(id)device customName:(NSString *)name { + if (self = [super init]) { + _originalDevice = device; + _customName = name; + } + return self; +} + +- (NSString *)name { + return self.customName ?: [self.originalDevice name]; +} + +- (id)forwardingTargetForSelector:(SEL)aSelector { + return self.originalDevice; +} + +@end \ No newline at end of file diff --git a/ios-change-info/OhNo.plist b/ios-change-info/OhNo.plist new file mode 100644 index 0000000..e5c60ee --- /dev/null +++ b/ios-change-info/OhNo.plist @@ -0,0 +1 @@ +{ Filter = { Bundles = ( "com.apple.UIKit" ); }; } diff --git a/ios-change-info/README.en.md b/ios-change-info/README.en.md new file mode 100644 index 0000000..da9035e --- /dev/null +++ b/ios-change-info/README.en.md @@ -0,0 +1,36 @@ +# ios-change-info + +#### Description +hook ios info + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/ios-change-info/README.md b/ios-change-info/README.md new file mode 100644 index 0000000..e7f4c6d --- /dev/null +++ b/ios-change-info/README.md @@ -0,0 +1,15 @@ +# ios-change-info + +## 型号 +## 系统 +## 屏幕 +## 音频 +## 电池 +## 内存 +## 启动时间 +## 国家/地区,时区和区域设置,首选语言 +## 网络链接类型,速度 +## IP地址 +## http 标头 +## IDFA +## IDFV diff --git a/ios-change-info/Tweak.x b/ios-change-info/Tweak.x new file mode 100644 index 0000000..ec832a7 --- /dev/null +++ b/ios-change-info/Tweak.x @@ -0,0 +1,1168 @@ + +#import +#import +#include +#import +#import +#import +#import // 获取ip +#import // 获取ip +#import // 获取ip +#import +#import +#import +#import +#import +#import +#import +#import + +typedef void (^tryGetValCallback)(id parameter); + +@interface SBLockScreenManager : NSObject +- (BOOL)unlockUIFromSource:(int)source withOptions:(id)options; +- (void)lockUIFromSource:(int)source withOptions:(id)options; +@end + + + +NSDictionary *settings; + +void reloadConfig() { + @try { + NSString *bundleId = @"org.xyzshell.NotNil"; + NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; + + if ([[NSFileManager defaultManager] fileExistsAtPath:plistPath]) { + settings = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; + if (!settings) { + NSLog(@"Failed to load settings"); + } + } + } @catch (NSException *exception) { + NSLog(@"Error loading config: %@", exception); + } +} + + +NSUUID* str2uuid(NSString *str) { + return [[NSUUID alloc] initWithUUIDString:str]; +} + +NSInteger str2int(NSString *str) { + return [str integerValue]; +} +float str2float(NSString *str) { + return [str floatValue]; +} +double str2double(NSString *str) { + return [str doubleValue]; +} + +unsigned long long str2ull(NSString *str) { + return [str longLongValue]; +} + +void tryGetVal(NSString *key, tryGetValCallback block) { + @try { + if (!key || !block || !settings) return; + + id data = settings[key]; + if (data) { + block(data); + } + } @catch (NSException *exception) { + NSLog(@"Error in tryGetVal for key %@: %@", key, exception); + } +} + +const char* str2chars(NSString *str) { + const char *cString = [str UTF8String]; + return cString; +} + + +%group ohno + +// group ohho start + +%hook ATTrackingManager + ++ (NSUInteger)trackingAuthorizationStatus { + __block NSUInteger originalStatus = %orig; + NSLog(@"start hook trackingAuthorizationStatus"); + NSLog(@"[ATTrackingManager Hook] Original trackingAuthorizationStatus: %lu", (unsigned long)originalStatus); + + // 你可以在这里修改返回值 + // 例如,总是返回已授权状态: + // return 3; // ATTrackingManagerAuthorizationStatusAuthorized + tryGetVal(@"trackingStatus", ^(id parameter) { + originalStatus = str2int(parameter); + }); + // 或者,你可以直接返回原始值 + return originalStatus; + +} + +%end + +%hook ASIdentifierManager + +-(NSUUID*)advertisingIdentifier +{ + // 修改IDFA + NSLog(@"start hook idfa"); + __block NSUUID *idfa = %orig; + // reloadConfig(); + tryGetVal(@"idfa", ^(id parameter) { + idfa = str2uuid(parameter); + }); + NSLog(@"hook idfa: %@", idfa); + return idfa; +} +-(BOOL) isAdvertisingTrackingEnabled { + __block BOOL res = %orig; + tryGetVal(@"trackingStatus", ^(id parameter) { + NSInteger status = str2int(parameter); + res = (status >= 3 ? YES : NO); + }); + return res; +} + +%end + +// static BOOL orientationMonitoringEnabled = NO; + +%hook UIDevice +// IDFV +-(NSUUID*)identifierForVendor{ + NSLog(@"start hook idfv"); + __block NSUUID *idfv = %orig; + tryGetVal(@"idfv", ^(id parameter) { + idfv = str2uuid(parameter); + }); + NSLog(@"hook idfv: %@", idfv); + return idfv; +} + +- (NSString *)name{ + NSLog(@"start hook device name"); + __block NSString *name = %orig; + tryGetVal(@"deviceName", ^(id parameter) { + name = parameter; + }); + NSLog(@"hook device name: %@", name); + return name; +} + +- (NSString *)model{ + return %orig; +} + +- (NSString *)localizedModel{ + return %orig; +} + +- (NSString *)systemName{ + return %orig; +} + +- (NSString *)systemVersion{ + NSLog(@"start hook system version"); + __block NSString *systemVersion = %orig; + tryGetVal(@"osVersion", ^(id parameter) { + systemVersion = parameter; + }); + NSLog(@"hook system version: %@", systemVersion); + return systemVersion; +} + +- (UIDeviceBatteryState)batteryState { + NSLog(@"start hook batteryState"); + __block UIDeviceBatteryState res = %orig; + tryGetVal(@"batteryState", ^(id parameter) { + NSInteger intVal = str2int(parameter); + res = (UIDeviceBatteryState)intVal; + }); + return res; +} + +- (float)batteryLevel { + // 随机电量 + NSLog(@"start hook batteryLevel"); + __block float res = %orig; + tryGetVal(@"batteryLevel", ^(id parameter) { + res = str2float(parameter); + }); + return res; +} + +- (UIDeviceOrientation)orientation { + return UIDeviceOrientationPortrait; +} + +%end + +%hook NSProcessInfo + +- (NSTimeInterval) systemUptime { + // 开机时间 + NSLog(@"start hook systemUptime"); + __block NSTimeInterval res = %orig; + tryGetVal(@"systemUptime", ^(id parameter) { + double v = str2double(parameter); + if(v > -1.0f) { + res = v + res; + } + }); + return res; +} + +- (unsigned long long) physicalMemory { + // 内存 + NSLog(@"start hook physicalMemory"); + __block unsigned long long memory = %orig; + tryGetVal(@"physicalMemory", ^(id parameter) { + unsigned long long t = str2ull(parameter); + if(t > 1000) { + memory = t; + } + }); + NSLog(@"hook physicalMemory: %llu", memory); + return memory; +} + +- (NSUInteger) processorCount { + NSLog(@"start hook processorCount"); + __block NSUInteger res = %orig; + tryGetVal(@"cpuCore", ^(id parameter) { + NSUInteger t = str2int(parameter); + if(t > 0) { + res = t; + } + }); + return res; +} + +- (NSOperatingSystemVersion)operatingSystemVersion { + NSOperatingSystemVersion version = %orig; + __block NSString *versionString = @""; + tryGetVal(@"osVersion", ^(id parameter) { + versionString = parameter; + }); + + if (!versionString || ![versionString length]) { + return version; + } + + NSArray *components = [versionString componentsSeparatedByString:@"."]; + if (components.count == 0 || components.count > 3) { + return version; + } + + // 验证每个组件是否为有效数字 + for (NSString *component in components) { + if (![[NSScanner scannerWithString:component] scanInteger:NULL]) { + return version; + } + } + + version.majorVersion = [components[0] integerValue]; + version.minorVersion = components.count > 1 ? [components[1] integerValue] : 0; + version.patchVersion = components.count > 2 ? [components[2] integerValue] : 0; + + return version; +} + + +%end + +%hook UIWindow +- (UIEdgeInsets) safeAreaInsets { + NSLog(@"start hook safeAreaInsets"); + __block UIEdgeInsets originalInsets = %orig; + %log(@"Original safeAreaInsets: %@", NSStringFromUIEdgeInsets(originalInsets)); + + tryGetVal(@"safeAreaInsets", ^(id parameter) { + NSDictionary *dic = parameter; + // 修改 safeAreaInsets + UIEdgeInsets modifiedInsets = UIEdgeInsetsMake( + originalInsets.top = str2double(dic[@"top"]), // 增加顶部安全区域 + originalInsets.left = 0, // 增加左侧安全区域 + originalInsets.bottom = str2double(dic[@"bottom"]), // 增加底部安全区域 + originalInsets.right = 0 // 增加右侧安全区域 + ); + originalInsets = modifiedInsets; + }); + + %log(@"Modified safeAreaInsets: %@", NSStringFromUIEdgeInsets(originalInsets)); + return originalInsets; +} +%end + +%hook UIScreen +- (CGFloat) brightness { + // 随机亮度 + NSLog(@"start hook brightness"); + __block CGFloat originalBrightness = %orig; + tryGetVal(@"screenBrightness", ^(id parameter) { + double fat = str2double(parameter); + if(fat > -1.0f) { + originalBrightness = fat; + } + }); + + return originalBrightness; +} +- (CGRect)bounds { + NSLog(@"start hook bounds"); + __block CGRect originalBounds = %orig; + tryGetVal(@"screenBounds", ^(id parameter) { + NSDictionary *dic = parameter; + double w = str2double(dic[@"x"]); + double h = str2double(dic[@"y"]); + CGRect newBounds = { + .origin = {.x = 0, .y = 0}, + .size = {.width = w, .height = h}, + }; + originalBounds = newBounds; + }); + return originalBounds; +} +- (CGFloat) scale { + NSLog(@"start hook scale"); + __block CGFloat originalScale = %orig; + tryGetVal(@"screenScale", ^(id parameter) { + double fat = str2double(parameter); + if(fat > -1.0f) { + originalScale = fat; + } + }); + return originalScale; +} +- (CGRect)nativeBounds { + NSLog(@"start hook nativeBounds"); + __block CGRect originalBounds = %orig; + tryGetVal(@"screenBounds", ^(id parameter) { + NSDictionary *dic = parameter; + double w = str2double(dic[@"nx"]); + double h = str2double(dic[@"ny"]); + CGRect newBounds = { + .origin = {.x = 0, .y = 0}, + .size = {.width = w, .height = h}, + }; + originalBounds = newBounds; + }); + return originalBounds; +} + +- (BOOL)isCaptured { + // 总是返回NO,表示屏幕没有被捕获(镜像) + return NO; +} + +- (UIScreen *)mirroredScreen { + // 总是返回nil,表示没有镜像屏幕 + return nil; +} + +%end + +%hook AVAudioSession +- (float) outputVolume { + // 音量 + NSLog(@"start hook outputVolume"); + __block float originalVolume = %orig; + tryGetVal(@"outputVolume", ^(id parameter) { + float fat = str2float(parameter); + if(fat > -1.0f) { + originalVolume = fat; + } + }); + return originalVolume; +} +%end + +%hook UIScreenMode + +- (CGSize)size { + // 修改屏幕大小信息 + NSLog(@"start hook bounds"); + __block CGSize originalSize = %orig; + tryGetVal(@"screenBounds", ^(id parameter) { + NSDictionary *dic = parameter; + double w = str2double(dic[@"x"]); + double h = str2double(dic[@"y"]); + CGSize newBounds = { + .width = w, + .height = h + }; + originalSize = newBounds; + }); + return originalSize; +} + +%end + +%hook NSFileManager +- (NSDictionary *) attributesOfFileSystemForPath:(NSString *)path error:(NSError **)error { + // 磁盘信息 + NSLog(@"start hook disk info"); + NSDictionary *res = %orig; + // int64_t size = [info[NSFileSystemSize] longLongValue]; // 总大小 + // int64_t space = [[info objectForKey:NSFileSystemFreeSize] longLongValue]; + if ([path isEqualToString:NSHomeDirectory()]) { + NSMutableDictionary *modifiedAttributes = [res mutableCopy]; + // 修改或添加属性 + tryGetVal(@"diskSize", ^(id parameter) { + int64_t fat = str2ull(parameter); + if(fat > 0) { + modifiedAttributes[NSFileSystemSize] = @(fat); // 1 GB + } + }); + tryGetVal(@"diskFreeSize", ^(id parameter) { + int64_t fat = str2ull(parameter); + if(fat > 0) { + modifiedAttributes[NSFileSystemFreeSize] = @(fat); // 1 GB + } + }); + + return [modifiedAttributes copy]; + } + + return res; +} +// 反越狱检测 +- (BOOL)fileExistsAtPath:(NSString *)event { + NSLog(@"start hook fileExistsAtPath"); + NSArray *array = @[@"/Application/Cydia.app", + @"/Application/Sileo.app", + @"/usr/lib/TweakInject", + @"/Library/TweakInject", + @"/Library/MobileSubstrate/MobileSubstrate.dylib", + @"/bin/bash", + @"/usr/sbin/sshd", + @"/etc/apt", + @"/usr/bin/ssh", + @"/private/var/lib/apt", + @"/private/var/lib/cydia", + @"/private/var/tmp/cydia.log", + @"/Applications/WinterBoard.app", + @"/var/lib/cydia", + @"/private/etc/dpkg/origins/debian", + @"/bin.sh", + @"/private/etc/apt", + @"/etc/ssh/sshd_config", + @"/private/etc/ssh/sshd_config", + @"/Applications/SBSetttings.app", + @"/private/var/mobileLibrary/SBSettingsThemes/", + @"/private/var/stash", + @"/usr/libexec/sftp-server", + @"/usr/libexec/cydia/", + @"/usr/sbin/frida-server", + @"/usr/bin/cycript", + @"/usr/local/bin/cycript", + @"/usr/lib/libcycript.dylib", + @"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", + @"/System/Library/LaunchDaemons/com.ikey.bbot.plist", + @"/Applications/FakeCarrier.app", + @"/Library/MobileSubstrate/DynamicLibraries/Veency.plist", + @"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", + @"/usr/libexec/ssh-keysign", + @"/usr/libexec/sftp-server", + @"/Applications/blackra1n.app", + @"/Applications/IntelliScreen.app", + @"/Applications/Snoop-itConfig.app", + @"/var/lib/dpkg/info", + @"/User/Applications"]; + + NSInteger index = [array indexOfObjectPassingTest:^BOOL(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + BOOL ret = [event hasPrefix:obj]; + if (ret) { + *stop = YES; + } + return ret; + }]; + if (index != NSNotFound) { + NSLog(@"9999999==%@=",event); + return NO; + } + return %orig; +} +%end + +%hook NSLocale ++ (NSArray *) preferredLanguages { + // 语言 + NSLog(@"start hook preferredLanguages"); + return @[@"en-US"]; +} ++ (NSLocale *)currentLocale { + // 如果你想修改返回的 locale,可以在这里进行修改 + // 例如,强制返回一个特定的 locale: + NSLog(@"start hook currentLocale"); + __block NSLocale *res = %orig; + tryGetVal(@"locale", ^(id parameter) { + NSString *loc = parameter; + res = [[NSLocale alloc] initWithLocaleIdentifier:loc]; + }); + return res; +} ++ (NSLocale *)systemLocale { + NSLog(@"start hook systemLocale"); + __block NSLocale *res = %orig; + tryGetVal(@"locale", ^(id parameter) { + NSString *loc = parameter; + res = [[NSLocale alloc] initWithLocaleIdentifier:loc]; + }); + return res; +} + +%end + +%hook NSTimeZone + + ++ (NSTimeZone *)localTimeZone { + // NSTimeZone *originalTimeZone = %orig; + // NSLog(@"[HOOK] Local time zone accessed: %@", [originalTimeZone name]); + + // 如果你想修改返回的时区,可以在这里进行修改 + // 例如,强制返回一个特定的时区: + NSLog(@"start hook localTimeZone"); + __block NSTimeZone *res = %orig; + tryGetVal(@"timeZone", ^(id parameter) { + NSString *loc = parameter; + res = [NSTimeZone timeZoneWithName:loc]; + }); + return res; + // return originalTimeZone; +} + ++ (NSTimeZone *)systemTimeZone { + NSLog(@"start hook systemTimeZone"); + __block NSTimeZone *res = %orig; + tryGetVal(@"timeZone", ^(id parameter) { + NSString *loc = parameter; + res = [NSTimeZone timeZoneWithName:loc]; + }); + return res; +} + ++ (NSTimeZone *)defaultTimeZone { + NSLog(@"start hook defaultTimeZone"); + __block NSTimeZone *res = %orig; + tryGetVal(@"timeZone", ^(id parameter) { + NSString *loc = parameter; + res = [NSTimeZone timeZoneWithName:loc]; + }); + return res; +} + + +%end + +// 状态栏 +%hook UIStatusBarManager +- (CGRect) statusBarFrame { + NSLog(@"start hook statusBarFrame"); + __block CGRect originalFrame = %orig; + tryGetVal(@"safeAreaInsets", ^(id parameter) { + NSDictionary *dic = parameter; + double barHeight = str2double(dic[@"height"]); + CGSize tempSize = {.width = originalFrame.size.width, .height = barHeight}; + originalFrame.size = tempSize; + }); + return originalFrame; +} +%end + +%hook NSMutableURLRequest +// Maybe server side checks the user agent? +- (instancetype)initWithURL:(NSURL *)URL { + self = %orig(URL); + if (self) { + tryGetVal(@"userAgent", ^(id parameter) { + [self setValue:parameter forHTTPHeaderField:@"User-Agent"]; + }); + } + return self; +} + +- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { + __block NSString *_userAgent = value; + if ([field isEqualToString:@"User-Agent"]) { + // 修改User Agent + tryGetVal(@"userAgent", ^(id parameter) { + _userAgent = parameter; + }); + } + %orig(_userAgent, field); +} + +%end + +%hook NSURLSession + ++ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration { + NSLog(@"start hook sessionWithConfiguration"); + //if (configuration.HTTPAdditionalHeaders[@"User-Agent"]) { + tryGetVal(@"userAgent", ^(id parameter) { + configuration.HTTPAdditionalHeaders = @{@"User-Agent": parameter}; + }); + //} + return %orig; +} + +- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + tryGetVal(@"userAgent", ^(id parameter) { + [mutableRequest setValue:parameter forHTTPHeaderField:@"User-Agent"]; + }); + + return %orig(mutableRequest, completionHandler); +} + +%end + +%hook WKWebView + +- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *error))completionHandler { + NSLog(@"start hook evaluateJavaScript"); + %log(@"Evaluating JavaScript: %@", javaScriptString); + __block NSString *userAgent = nil; + tryGetVal(@"userAgent", ^(id parameter) { + userAgent = parameter; + }); + if(userAgent) { + [self setCustomUserAgent:userAgent]; + } + %orig(javaScriptString, completionHandler); +} + +- (void)setCustomUserAgent:(NSString *)userAgent { + __block NSString *_userAgent = userAgent; + tryGetVal(@"userAgent", ^(id parameter) { + _userAgent = parameter; + }); + %orig(_userAgent); +} + +- (NSString *)customUserAgent { + // 获取原来的 User-Agent + __block NSString *userAgent = %orig; + + tryGetVal(@"userAgent", ^(id parameter) { + userAgent = parameter; + }); + + // 返回修改后的 User-Agent + return userAgent; +} + +%end + + + +%hook CTTelephonyNetworkInfo +- (NSDictionary *) serviceCurrentRadioAccessTechnology { + NSLog(@"start hook serviceCurrentRadioAccessTechnology"); + NSDictionary *originalTechnologies = %orig; + %log(@"Original Radio Access Technologies: %@", originalTechnologies); + + NSMutableDictionary *modifiedProviders = [[NSMutableDictionary alloc] init]; + + tryGetVal(@"simInfo", ^(id parameter) { + NSDictionary *simInfoDic = parameter; + for(NSString *service in simInfoDic.allKeys) { + NSDictionary *dic = simInfoDic[service]; + NSString *wwan = dic[@"wwan"]; + if([wwan isEqual:@"5G"]) { + [modifiedProviders setValue:@"CTRadioAccessTechnologyNR" forKey:service]; + } else { + [modifiedProviders setValue:@"CTRadioAccessTechnologyLTE" forKey:service]; + } + } + }); + + if([modifiedProviders count] > 0) { + return [modifiedProviders copy]; + } + return originalTechnologies; +} +- (NSDictionary *)serviceSubscriberCellularProviders { + NSLog(@"start hook serviceSubscriberCellularProviders"); + NSDictionary *originalProviders = %orig; + %log(@"Original Cellular Providers: %@", originalProviders); + + NSMutableDictionary *modifiedProviders = [[NSMutableDictionary alloc] init]; + + tryGetVal(@"simInfo", ^(id parameter) { + NSDictionary *simInfoDic = parameter; + for(NSString *service in simInfoDic.allKeys) { + NSDictionary *dic = simInfoDic[service]; + CTCarrier *carrier = [[CTCarrier alloc] init]; + [carrier setValue:dic[@"carrierName"] forKey:@"carrierName"]; + [carrier setValue:dic[@"mobileCountryCode"] forKey:@"mobileCountryCode"]; + [carrier setValue:dic[@"mobileNetworkCode"] forKey:@"mobileNetworkCode"]; + [carrier setValue:dic[@"isoCountryCode"] forKey:@"isoCountryCode"]; + [modifiedProviders setValue:carrier forKey:service]; + } + }); + + if([modifiedProviders count] > 0) { + return [modifiedProviders copy]; + } + return originalProviders; +} +%end + +// 添加随机函数 +static double randomRadiansPerSecond() { + double randomValue = (double)arc4random() / UINT32_MAX; + return (randomValue * 20.0) - 10.0; +} +// 创建 CMGyroData 的子类 +@interface CustomCMGyroData : CMGyroData +@property (nonatomic, assign) CMRotationRate customRotationRate; +@end + +@implementation CustomCMGyroData + +- (CMRotationRate)rotationRate { + return self.customRotationRate; +} + +@end + + + +// 陀螺仪 +%hook CMMotionManager + +- (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMGyroHandler)handler { + if (!queue || !handler) return %orig; + CMGyroHandler newHandler = ^(CMGyroData *gyroData, NSError *error) { + + if(gyroData) { + CMRotationRate originalRate = gyroData.rotationRate; + + // 在这里,你可以修改或记录 rotationRate + NSLog(@"Gyro RotationRate - x: %f, y: %f, z: %f", + originalRate.x, originalRate.y, originalRate.z); + } + // 设置随机的旋转速率 + CMRotationRate randomRate; + randomRate.x = randomRadiansPerSecond(); + randomRate.y = randomRadiansPerSecond(); + randomRate.z = randomRadiansPerSecond(); + + // 如果你想修改值,可以这样做: + // 创建自定义的 CMGyroData 对象 + CustomCMGyroData *customGyroData = (CustomCMGyroData *)[[objc_getClass("CMGyroData") alloc] init]; + // Objective-C 没有直接的方法来修改 CMGyroData 的值,所以这里我们只是记录 + // 设置自定义数据 + customGyroData.customRotationRate = randomRate; + // 调用原始处理程序,但使用我们的自定义数据 + if (handler) { + handler((CMGyroData *)customGyroData, error); + } + }; + + %orig(queue, newHandler); +} + +%end + +// int uname(struct utsname *); +%hookf(int, uname, struct utsname * systemInfo) { + NSLog(@"start hook uname"); + int nRet = %orig; + tryGetVal(@"productStr", ^(id parameter) { + char str_machine_name[100]; + [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; + strcpy(systemInfo->machine,str_machine_name); + }); + return nRet; // Call the original implementation of this function + +} + +%hookf(int, sysctl, const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { + NSLog(@"start hook sysctl"); + // 这里可能会导致软件崩溃 + int nRet = %orig; + if(namelen == 2) { + if (name[0] == CTL_KERN && name[1] == KERN_BOOTTIME && oldp) { + struct timeval *a = (struct timeval*)oldp; + // test + // a->tv_sec = 10; + // a->tv_usec = 10; + tryGetVal(@"kernBootTime", ^(id parameter) { + int kernBootTime = str2int(parameter); + + a->tv_sec = kernBootTime + a->tv_sec; + }); + } + } + return nRet; + /* + if (namelen == 2 && name[0] == CTL_HW && name[1] == HW_MACHINE && oldp) { + int const ret = %orig; + if (test_machine_name) { + // 修改 machine + char str_machine_name[100]; + [test_machine_name getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; + strncpy((char*)oldp, str_machine_name, strlen(str_machine_name)); + } + NSLog(@"start hook sysctl new"); + return ret; + } else { + NSLog(@"start hook sysctl old"); + return %orig; + } + */ + // return %orig; +} + +// 安全的字符串复制函数 +static BOOL safe_copy_string(void *dst, size_t *dstlen, const char *src) { + if (!dst || !dstlen || !src) return NO; + + size_t srclen = strlen(src); + size_t needed = srclen + 1; + + if (*dstlen < needed) { + *dstlen = needed; + return NO; + } + + strlcpy(dst, src, *dstlen); + *dstlen = srclen; + return YES; +} + +%hookf(int, sysctlbyname, const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + NSLog(@"start hook sysctlbyname"); + if (strcmp(name, "hw.machine") == 0) { + NSLog(@"start hook sysctlbyname new machine"); + int ret = %orig; + __block NSString *machine = nil; + tryGetVal(@"productStr", ^(id parameter) { + if ([parameter isKindOfClass:[NSString class]]) { + NSString *temp = parameter; + machine = [temp copy]; + } + }); + if (oldp && machine) { + // char str_machine_name[100]; + const char *hwMachineCh = [machine UTF8String]; + // [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; + //strcpy((char *)oldp, hwMachineCh); + if (hwMachineCh) { + if (!safe_copy_string(oldp, oldlenp, hwMachineCh)) { + return ENOMEM; + } + } + } + return ret; + } else if (strcmp(name, "hw.model") == 0) { + NSLog(@"start hook sysctlbyname new model"); + int ret = %orig; + __block NSString *modelStr = nil; + tryGetVal(@"hwModel", ^(id parameter) { + if ([parameter isKindOfClass:[NSString class]]) { + NSString *temp = parameter; + modelStr = [temp copy]; + } + }); + if (oldp && modelStr) { + // char str_machine_name[100]; + const char *hwMachineCh = [modelStr UTF8String]; + // [parameter getCString:str_machine_name maxLength:100 encoding:NSUTF8StringEncoding]; + //strcpy((char *)oldp, hwMachineCh); + if (hwMachineCh) { + if (!safe_copy_string(oldp, oldlenp, hwMachineCh)) { + return ENOMEM; + } + } + } + return ret; + } else { + NSLog(@"start hook sysctlbyname old"); + return %orig; + } +} + +// int clock_gettime(clockid_t __clock_id, struct timespec *__tp); +%hookf(int, clock_gettime, clockid_t __clock_id, struct timespec *__tp) { + NSLog(@"start hook clock_gettime"); + int nret = %orig; + if(__clock_id == CLOCK_MONOTONIC_RAW) { + // __tp->tv_sec = 20; + // __tp->tv_nsec = 20; + } + return nret; +} + +// 修改ip + +// 辅助函数:创建网络接口 +static struct ifaddrs* createInterface(const char* name, const char* ipv4, const char* ipv6) { + if (!name || !ipv4 || !ipv6) return NULL; + + @try { + // 创建新接口 + struct ifaddrs *new_ifaddr = (struct ifaddrs *)calloc(1, sizeof(struct ifaddrs)); + if (!new_ifaddr) return NULL; + + // 设置接口名称 + new_ifaddr->ifa_name = strdup(name); + if (!new_ifaddr->ifa_name) { + free(new_ifaddr); + return NULL; + } + new_ifaddr->ifa_flags = IFF_UP | IFF_RUNNING; + + // 创建IPv4地址结构 + struct sockaddr_in *addr_in = (struct sockaddr_in *)calloc(1, sizeof(struct sockaddr_in)); + if (!addr_in) { + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + + // 设置IPv4地址 + addr_in->sin_family = AF_INET; + if (inet_pton(AF_INET, ipv4, &addr_in->sin_addr) != 1) { + free(addr_in); + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + new_ifaddr->ifa_addr = (struct sockaddr *)addr_in; + + // 创建IPv6结构 + struct ifaddrs *next_ifaddr = (struct ifaddrs *)calloc(1, sizeof(struct ifaddrs)); + if (!next_ifaddr) { + free(addr_in); + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + + // 设置IPv6名称 + next_ifaddr->ifa_name = strdup(name); + if (!next_ifaddr->ifa_name) { + free(next_ifaddr); + free(addr_in); + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + next_ifaddr->ifa_flags = IFF_UP | IFF_RUNNING; + + // 创建IPv6地址结构 + struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)calloc(1, sizeof(struct sockaddr_in6)); + if (!addr_in6) { + free(next_ifaddr->ifa_name); + free(next_ifaddr); + free(addr_in); + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + + // 设置IPv6地址 + addr_in6->sin6_family = AF_INET6; + if (inet_pton(AF_INET6, ipv6, &addr_in6->sin6_addr) != 1) { + free(addr_in6); + free(next_ifaddr->ifa_name); + free(next_ifaddr); + free(addr_in); + free(new_ifaddr->ifa_name); + free(new_ifaddr); + return NULL; + } + next_ifaddr->ifa_addr = (struct sockaddr *)addr_in6; + + // 链接接口 + new_ifaddr->ifa_next = next_ifaddr; + return new_ifaddr; + } @catch (NSException *exception) { + NSLog(@"Error creating interface: %@", exception); + return NULL; + } +} + +// 修改现有接口的IP地址 +static void modifyInterfaceIP(struct ifaddrs *interface, const char *ipv4, const char *ipv6) { + if (!interface || !ipv4 || !ipv6) return; + + @try { + if (interface->ifa_addr) { + if (((struct sockaddr_in*)interface->ifa_addr)->sin_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in*)interface->ifa_addr; + inet_pton(AF_INET, ipv4, &addr->sin_addr); + } else if (((struct sockaddr_in*)interface->ifa_addr)->sin_family == AF_INET6) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)interface->ifa_addr; + inet_pton(AF_INET6, ipv6, &addr6->sin6_addr); + } + } + } @catch (NSException *exception) { + NSLog(@"Error modifying interface IP: %@", exception); + } +} + +%hookf(int, getifaddrs, struct ifaddrs **interfaces) { + if (!interfaces) return EINVAL; + + int nRet = %orig; + if (nRet != 0) return nRet; + + @try { + // 获取网络配置 + __block NSDictionary *networkConfig = nil; + tryGetVal(@"networkInterfacesInfo", ^(id parameter) { + if ([parameter isKindOfClass:[NSDictionary class]]) { + networkConfig = parameter; + } + }); + + if (!networkConfig) { + return nRet; + } + + // 处理现有接口 + struct ifaddrs *interface; + bool isHookEn0IpV4 = false; + + for (interface = *interfaces; interface; interface = interface->ifa_next) { + if (!interface->ifa_name) continue; + + NSString *name = @(interface->ifa_name); + if ([name isEqualToString:@"en0"]) { + NSDictionary *en0Config = networkConfig[@"en0"]; + if (en0Config) { + const char *ipv4 = [en0Config[@"ipv4"] UTF8String]; + const char *ipv6 = [en0Config[@"ipv6"] UTF8String]; + if (ipv4 && ipv6) { + modifyInterfaceIP(interface, ipv4, ipv6); + isHookEn0IpV4 = true; + } + } + } + } + + // 添加新接口 + if (!isHookEn0IpV4) { + NSDictionary *en0Config = networkConfig[@"en0"]; + if (en0Config) { + const char *ipv4 = [en0Config[@"ipv4"] UTF8String]; + const char *ipv6 = [en0Config[@"ipv6"] UTF8String]; + struct ifaddrs *new_en0 = createInterface("en0", ipv4, ipv6); + if (new_en0) { + new_en0->ifa_next->ifa_next = *interfaces; + *interfaces = new_en0; + } + } + } + + // 添加pdp_ip0接口 + NSDictionary *pdpConfig = networkConfig[@"pdp_ip0"]; + if (pdpConfig) { + const char *ipv4 = [pdpConfig[@"ipv4"] UTF8String]; + const char *ipv6 = [pdpConfig[@"ipv6"] UTF8String]; + struct ifaddrs *new_pdp = createInterface("pdp_ip0", ipv4, ipv6); + if (new_pdp) { + new_pdp->ifa_next->ifa_next = *interfaces; + *interfaces = new_pdp; + } + } + + } @catch (NSException *exception) { + NSLog(@"Error in getifaddrs hook: %@", exception); + } + + return nRet; +} + + + +/* Boolean +SCNetworkReachabilityGetFlags ( + SCNetworkReachabilityRef target, + SCNetworkReachabilityFlags *flags + ) +*/ + +%hookf(Boolean, SCNetworkReachabilityGetFlags, SCNetworkReachabilityRef target, SCNetworkReachabilityFlags *flags) { + NSLog(@"start hook SCNetworkReachabilityGetFlags"); + Boolean result = %orig(target, flags); + + if (result && flags != NULL) { + // 可以在这里修改 flags 的值 + // 例如,总是添加 kSCNetworkReachabilityFlagsReachable 标志 + *flags |= kSCNetworkReachabilityFlagsReachable; + *flags |= kSCNetworkReachabilityFlagsIsWWAN; + } + + return result; +} + + +%hookf(BOOL,UIAccessibilityIsClosedCaptioningEnabled) { + return YES; +} + +%hookf(BOOL,UIAccessibilityIsMonoAudioEnabled) { + return YES; +} + +// group ohho end +%end + + + + +%ctor{ + NSLog(@"start hook"); + @try { + @autoreleasepool { + NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + //NSLog(@"print -- %@",bundleIdentifier); + NSString *bundleId = @"org.xyzshell.NotNil"; + NSString *plistPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", bundleId]; + // 创建文件管理器实例 + NSFileManager *fileManager = [NSFileManager defaultManager]; + + // 检查文件是否存在 + BOOL fileExists = [fileManager fileExistsAtPath:plistPath]; + if(fileExists) { + settings = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; + NSArray *pkgs = settings[@"apps"]; + + if([pkgs indexOfObject:bundleIdentifier] != NSNotFound){ + NSLog(@"hooks start %@", bundleIdentifier); + // 指定需要运行的执行的分组代码,%init有两种用法,这里只展示一种 + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kLuxSSFaceKey"]; + %init(ohno); + } + } + } + } @catch (NSException *exception) { + NSLog(@"Error in ctor: %@", exception); + } +} + +static void cleanup() { + // 清理分配的资源 + if (settings) { + settings = nil; + } + // 其他清理工作 +} + +%dtor { + cleanup(); +} \ No newline at end of file diff --git a/ios-change-info/control b/ios-change-info/control new file mode 100644 index 0000000..d7ea9d1 --- /dev/null +++ b/ios-change-info/control @@ -0,0 +1,9 @@ +Package: com.xyzshell.ohno +Name: OhNo +Version: 0.0.2 +Architecture: iphoneos-arm +Description: An awesome MobileSubstrate tweak! +Maintainer: mac +Author: mac +Section: Tweaks +Depends: firmware (>= 12.2), mobilesubstrate (>= 0.9.5000) diff --git a/ios_wh.py b/ios_wh.py new file mode 100644 index 0000000..97f4828 --- /dev/null +++ b/ios_wh.py @@ -0,0 +1,60 @@ +import requests +import paramiko +import socket +import time + +url = "http://192.168.9.11:8080/ios/top_selection/heartbeats" +data = """ +{ + "url": "/start" +} +""".encode('utf-8') + +def restart(ip): + try: + # 实例化SSHClient + ssh_client = paramiko.SSHClient() + # 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接 ,此方法必须放在connect方法的前面 + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + # 连接SSH服务端,以用户名和密码进行认证 ,调用connect方法连接服务器 + ssh_client.connect(hostname=ip, port=22, username='root', password='alpine', timeout=3) + # 打开一个Channel并执行命令 结果放到stdout中,如果有错误将放到stderr中 + stdin, stdout, stderr = ssh_client.exec_command('killall -9 SpringBoard', timeout=3) + print(stdout.read().decode('utf-8')) + print(stderr.read().decode('utf-8')) + ssh_client.close() + except Exception as e: + print(e) + +def start(ip): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(5) + # 发送数据: + s.sendto(data, (ip.strip(), 6001)) + # 接收数据: + print(s.recv(1024).decode('utf-8')) + s.close() + except Exception as e: + print(e) + + +ips = [] + +res = requests.get(url) +json = res.json() +for it in json: + if it["life"] and it["loadCount"] < 30: + ips.append(it["ip"]) + +print(ips) + +for ip in ips: + print(ip) + restart(ip) + +time.sleep(5) + +for ip in ips: + print(ip) + start(ip) \ No newline at end of file diff --git a/ips.txt b/ips.txt new file mode 100644 index 0000000..d384cf5 --- /dev/null +++ b/ips.txt @@ -0,0 +1,2 @@ +172.30.8.102 +172.30.8.116 \ No newline at end of file diff --git a/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib new file mode 100644 index 0000000..db2fdb7 Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib differ diff --git a/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist new file mode 100644 index 0000000..32288e8 Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/Info.plist differ diff --git a/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib new file mode 100644 index 0000000..29c6297 Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib differ diff --git a/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib new file mode 100644 index 0000000..476a9a1 Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/BYZ-38-t0r-view-8bC-Xf-vdC.nib differ diff --git a/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist new file mode 100644 index 0000000..a19e16c Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/Info.plist differ diff --git a/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib new file mode 100644 index 0000000..13cf575 Binary files /dev/null and b/layout/Applications/nochange.app/Base.lproj/Main.storyboardc/UINavigationController-fJL-tO-o2a.nib differ diff --git a/layout/Applications/nochange.app/Settings.storyboardc/Info.plist b/layout/Applications/nochange.app/Settings.storyboardc/Info.plist new file mode 100644 index 0000000..8a3db60 Binary files /dev/null and b/layout/Applications/nochange.app/Settings.storyboardc/Info.plist differ diff --git a/layout/Applications/nochange.app/Settings.storyboardc/Settings.nib b/layout/Applications/nochange.app/Settings.storyboardc/Settings.nib new file mode 100644 index 0000000..533d368 Binary files /dev/null and b/layout/Applications/nochange.app/Settings.storyboardc/Settings.nib differ diff --git a/layout/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib b/layout/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib new file mode 100644 index 0000000..a9b833e Binary files /dev/null and b/layout/Applications/nochange.app/Settings.storyboardc/Y6W-OH-hqX-view-5EZ-qb-Rvc.nib differ diff --git a/layout/Applications/nochange.app/embedded.mobileprovision b/layout/Applications/nochange.app/embedded.mobileprovision new file mode 100644 index 0000000..e1e9918 Binary files /dev/null and b/layout/Applications/nochange.app/embedded.mobileprovision differ diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control new file mode 100644 index 0000000..d04eddf --- /dev/null +++ b/layout/DEBIAN/control @@ -0,0 +1,9 @@ +Package: com.xyzshell.nochange +Name: NoChange +Version: 0.0.3 +Architecture: iphoneos-arm +Description: An awesome application! +Maintainer: xyzshell +Author: xyzshell +Section: Utilities + diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst new file mode 100755 index 0000000..97e8790 --- /dev/null +++ b/layout/DEBIAN/postinst @@ -0,0 +1,2 @@ +#!/bin/sh +uicache --path /Applications/nochange.app diff --git a/local_file.txt b/local_file.txt new file mode 100644 index 0000000..6cefb3f --- /dev/null +++ b/local_file.txt @@ -0,0 +1,16 @@ + + + + + IpDevName + wallmate_1 + ServerURL + http://192.168.40.8:8080 + deviceId + E3F05B44-D26A-403B-A1C8-44321B067AB8 + lastReboot + 1754275233 + senderId + 4294968157 + + diff --git a/modify_config.py b/modify_config.py new file mode 100644 index 0000000..b073607 --- /dev/null +++ b/modify_config.py @@ -0,0 +1,59 @@ +import paramiko +import os +import plistlib + +# 设置SSH连接参数 +# hostname = '172.30.104.18' +port = 22 +username = 'root' +password = 'alpine' +# packagename = 'com.funny.prank.call' + +def moveRemote(hostname:str, packagename:str,serverurl:str): + # 创建SSH传输通道 + transport = paramiko.Transport((hostname, port)) + transport.set_keepalive(5) + # 连接SSH服务端,以用户名和密码进行认证 + transport.connect(username=username, password=password) + + # 创建SFTP客户端 + sftp = paramiko.SFTPClient.from_transport(transport) + + # 上传本地文件到远程主机 + local_path = 'local_file.txt' + remote_path = '/User/OhNoData/config001.plist' + # sftp.put(local_path, remote_path) + sftp.get(remote_path, local_path) + + + with open(local_path, 'rb') as fp: + configPlist = plistlib.load(fp) + configPlist['IpDevName'] = packagename + configPlist['ServerURL'] = serverurl + + with open(local_path, 'wb') as fp: + plistlib.dump(configPlist, fp) + + print(configPlist) + + # 上传本地文件到远程主机 + sftp.put(local_path, remote_path) + + # 关闭SFTP连接 + sftp.close() + + # 关闭SSH传输通道 + transport.close() + +if __name__ == "__main__": + ips1 = [] + with open("./ips.txt", 'r') as f: + ips1 = [i.strip() for i in f.readlines()] + + + for it in ips1: + try: + print(it) + moveRemote(it, "wallmate_1", "http://192.168.40.8:8080") + except Exception as e: + print(e) \ No newline at end of file diff --git a/packages/myios.deb b/packages/myios.deb new file mode 100644 index 0000000..2a34595 Binary files /dev/null and b/packages/myios.deb differ diff --git a/pub.sh b/pub.sh new file mode 100755 index 0000000..0805754 --- /dev/null +++ b/pub.sh @@ -0,0 +1,23 @@ +copy_debs() { + sshpass -p alpine pscp -l root -A -h ./ips.txt ./packages/* /User/Downloads +} + +install_change() { + sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/myios.deb" +} + +restart() { + ## sshpass -p alpine pssh -l root -A -ih ./ansible_files/pssh_ip.txt "killall -9 tempor" + sshpass -p alpine pssh -l root -A -ih ./ips.txt "killall -9 SpringBoard" +} + +if [[ $1 = "copy" ]] +then + copy_debs +elif [[ $1 = "install" ]] +then + install_change +elif [[ $1 = "restart" ]] +then + restart +fi \ No newline at end of file diff --git a/red.md b/red.md new file mode 100644 index 0000000..7620bd5 --- /dev/null +++ b/red.md @@ -0,0 +1,24 @@ +## 执行shell + + +sshpass -p alpine pscp -l root -A -h ./ips.txt ./debs/* /User/Downloads +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/net.angelxwind.appsyncunified_104.0_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/com.linusyang.appinst_1.1.4_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/p7zip_16.02-1_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/unrar_5.6.4-1_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/unzip_6.0+deb9u1-1_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/zip_2.32-1_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/apt.cydiakk.afc2d-arm64_1.2.0_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/apt.cydiakk.filza64bit_4.0.0-6_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/com.rpetrich.rocketbootstrap_1.0.10~beta1_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/applist_1.5.16_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/com.creaturesurvive.libcscolorpicker_1.0_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/apt.cydiakk.touchflow_1.0.6_iphoneos-arm.deb" +sshpass -p alpine pssh -l root -A -ih ./ips.txt "dpkg -i /User/Downloads/com.ichitaso.otadisabler_0.6_iphoneos-arm.deb" + +sshpass -p alpine pssh -l root -A -ih ./ips.txt "uiopen \"https://www.liangjianghu.com/searchads-appstore-switch\"" + +apt --fix-broken install + + +https://as.dogged.cn/ \ No newline at end of file diff --git a/testudp.py b/testudp.py new file mode 100644 index 0000000..d88d8bf --- /dev/null +++ b/testudp.py @@ -0,0 +1,22 @@ +import socket + + +data = """ +{ + "url": "/start" +} +""".encode('utf-8') + +with open('./ips.txt', 'r') as f: + for ip in f.readlines(): + print(ip.strip()) + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(5) + # 发送数据: + s.sendto(data, (ip.strip(), 6001)) + # 接收数据: + print(s.recv(1024).decode('utf-8')) + s.close() + except Exception as e: + print(e) diff --git a/tidb_dump b/tidb_dump new file mode 100644 index 0000000..23c5713 --- /dev/null +++ b/tidb_dump @@ -0,0 +1 @@ +tiup dumpling -u root -P 54321 -h 183.222.62.53 -p W3*Cry56f-^9_miq10 -T secret.gaid_ios --filetype sql -t 8 -o /home/ubuntu/tools/data -r 200000 -F 256MiB \ No newline at end of file