├── Cycript.framework ├── Cycript └── Headers │ └── Cycript.h ├── LatestBuild ├── README.md ├── WeChatHook.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── EL.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── EL.xcuserdatad │ └── xcschemes │ ├── WeChatHook.xcscheme │ └── xcschememanagement.plist ├── WeChatHook ├── CaptainHook.h ├── Package │ ├── DEBIAN │ │ ├── control │ │ └── control.txt │ └── usr │ │ └── lib │ │ └── 0xdeadfa11 ├── PackageVersion.plist ├── WeChatHook-Prefix.pch ├── WeChatHook.mm ├── WeChatManager.h └── WeChatManager.m └── yololib /Cycript.framework/Cycript: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElegantLiar/WeChatHook/59286e6a43f9897f95579e0a5a545afd388bdbae/Cycript.framework/Cycript -------------------------------------------------------------------------------- /Cycript.framework/Headers/Cycript.h: -------------------------------------------------------------------------------- 1 | /* Cycript - Optimizing JavaScript Compiler/Runtime 2 | * Copyright (C) 2009-2013 Jay Freeman (saurik) 3 | */ 4 | 5 | /* GNU General Public License, Version 3 {{{ */ 6 | /* 7 | * Cycript is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published 9 | * by the Free Software Foundation, either version 3 of the License, 10 | * or (at your option) any later version. 11 | * 12 | * Cycript is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Cycript. If not, see . 19 | **/ 20 | /* }}} */ 21 | 22 | #ifndef CYCRIPT_CYCRIPT_H 23 | #define CYCRIPT_CYCRIPT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | void CYListenServer(short port); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif/*CYCRIPT_CYCRIPT_H*/ 36 | -------------------------------------------------------------------------------- /LatestBuild: -------------------------------------------------------------------------------- 1 | /Users/ssy/Library/Developer/Xcode/DerivedData/WeChatHook-fobaozciuweilxgekfslygizvmrz/Build/Products/Debug-iphoneos -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WeChatHook 2 | iOS非越狱 逆向微信实现防撤回, 修改步数 3 | 4 | 项目中提供了用到的Cycript.framework yololib可执行文件 5 | 6 | 具体实现方法参考 http://www.jianshu.com/p/daf4daed72db -------------------------------------------------------------------------------- /WeChatHook.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 651AB7851F6FA30100E7082C /* WeChatManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 651AB7831F6FA30100E7082C /* WeChatManager.h */; }; 11 | 651AB7861F6FA30100E7082C /* WeChatManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 651AB7841F6FA30100E7082C /* WeChatManager.m */; }; 12 | 651AB7881F6FA7A300E7082C /* Cycript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 651AB7871F6FA7A300E7082C /* Cycript.framework */; }; 13 | 651AB78A1F6FA89B00E7082C /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 651AB7891F6FA89B00E7082C /* libz.tbd */; }; 14 | 651AB78C1F6FA8A400E7082C /* libstdc++.6.0.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 651AB78B1F6FA8A400E7082C /* libstdc++.6.0.9.tbd */; }; 15 | 651AB78E1F6FA8AC00E7082C /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 651AB78D1F6FA8AC00E7082C /* libsqlite3.0.tbd */; }; 16 | 651AB7901F6FA8B700E7082C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 651AB78F1F6FA8B700E7082C /* JavaScriptCore.framework */; }; 17 | 654B3C7E1F6A627500886397 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 654B3C7D1F6A627500886397 /* Foundation.framework */; }; 18 | 654B3C801F6A627500886397 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 654B3C7F1F6A627500886397 /* UIKit.framework */; }; 19 | 654B3C8C1F6A627500886397 /* WeChatHook.mm in Sources */ = {isa = PBXBuildFile; fileRef = 654B3C8B1F6A627500886397 /* WeChatHook.mm */; }; 20 | 654B3C961F6A62BF00886397 /* CaptainHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 654B3C951F6A62BF00886397 /* CaptainHook.h */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 651AB7831F6FA30100E7082C /* WeChatManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeChatManager.h; sourceTree = ""; }; 25 | 651AB7841F6FA30100E7082C /* WeChatManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeChatManager.m; sourceTree = ""; }; 26 | 651AB7871F6FA7A300E7082C /* Cycript.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Cycript.framework; sourceTree = ""; }; 27 | 651AB7891F6FA89B00E7082C /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 28 | 651AB78B1F6FA8A400E7082C /* libstdc++.6.0.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.6.0.9.tbd"; path = "usr/lib/libstdc++.6.0.9.tbd"; sourceTree = SDKROOT; }; 29 | 651AB78D1F6FA8AC00E7082C /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; }; 30 | 651AB78F1F6FA8B700E7082C /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 31 | 654B3C7A1F6A627500886397 /* libWeChatHook.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWeChatHook.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 654B3C7D1F6A627500886397 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 33 | 654B3C7F1F6A627500886397 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 34 | 654B3C841F6A627500886397 /* control.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = control.txt; path = Package/DEBIAN/control.txt; sourceTree = ""; }; 35 | 654B3C851F6A627500886397 /* control */ = {isa = PBXFileReference; lastKnownFileType = text; name = control; path = Package/DEBIAN/control; sourceTree = ""; }; 36 | 654B3C871F6A627500886397 /* PackageVersion.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PackageVersion.plist; sourceTree = ""; }; 37 | 654B3C881F6A627500886397 /* WeChatHook-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WeChatHook-Prefix.pch"; sourceTree = ""; }; 38 | 654B3C8B1F6A627500886397 /* WeChatHook.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WeChatHook.mm; sourceTree = ""; }; 39 | 654B3C8F1F6A627500886397 /* 0xdeadfa11 */ = {isa = PBXFileReference; lastKnownFileType = text; name = 0xdeadfa11; path = Package/usr/lib/0xdeadfa11; sourceTree = ""; }; 40 | 654B3C951F6A62BF00886397 /* CaptainHook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaptainHook.h; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 654B3C761F6A627500886397 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 651AB7901F6FA8B700E7082C /* JavaScriptCore.framework in Frameworks */, 49 | 651AB78E1F6FA8AC00E7082C /* libsqlite3.0.tbd in Frameworks */, 50 | 651AB78C1F6FA8A400E7082C /* libstdc++.6.0.9.tbd in Frameworks */, 51 | 651AB78A1F6FA89B00E7082C /* libz.tbd in Frameworks */, 52 | 654B3C7E1F6A627500886397 /* Foundation.framework in Frameworks */, 53 | 651AB7881F6FA7A300E7082C /* Cycript.framework in Frameworks */, 54 | 654B3C801F6A627500886397 /* UIKit.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 654B3C701F6A627500886397 = { 62 | isa = PBXGroup; 63 | children = ( 64 | 654B3C811F6A627500886397 /* WeChatHook */, 65 | 654B3C7C1F6A627500886397 /* Frameworks */, 66 | 654B3C7B1F6A627500886397 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 654B3C7B1F6A627500886397 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 654B3C7A1F6A627500886397 /* libWeChatHook.dylib */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 654B3C7C1F6A627500886397 /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 651AB78F1F6FA8B700E7082C /* JavaScriptCore.framework */, 82 | 651AB78D1F6FA8AC00E7082C /* libsqlite3.0.tbd */, 83 | 651AB78B1F6FA8A400E7082C /* libstdc++.6.0.9.tbd */, 84 | 651AB7891F6FA89B00E7082C /* libz.tbd */, 85 | 651AB7871F6FA7A300E7082C /* Cycript.framework */, 86 | 654B3C7D1F6A627500886397 /* Foundation.framework */, 87 | 654B3C7F1F6A627500886397 /* UIKit.framework */, 88 | ); 89 | name = Frameworks; 90 | sourceTree = ""; 91 | }; 92 | 654B3C811F6A627500886397 /* WeChatHook */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 654B3C8B1F6A627500886397 /* WeChatHook.mm */, 96 | 654B3C951F6A62BF00886397 /* CaptainHook.h */, 97 | 651AB7831F6FA30100E7082C /* WeChatManager.h */, 98 | 651AB7841F6FA30100E7082C /* WeChatManager.m */, 99 | 654B3C821F6A627500886397 /* Package */, 100 | 654B3C861F6A627500886397 /* Supporting Files */, 101 | ); 102 | path = WeChatHook; 103 | sourceTree = ""; 104 | }; 105 | 654B3C821F6A627500886397 /* Package */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 654B3C831F6A627500886397 /* DEBIAN */, 109 | 654B3C8D1F6A627500886397 /* usr */, 110 | ); 111 | name = Package; 112 | sourceTree = ""; 113 | }; 114 | 654B3C831F6A627500886397 /* DEBIAN */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 654B3C841F6A627500886397 /* control.txt */, 118 | 654B3C851F6A627500886397 /* control */, 119 | ); 120 | name = DEBIAN; 121 | sourceTree = ""; 122 | }; 123 | 654B3C861F6A627500886397 /* Supporting Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 654B3C871F6A627500886397 /* PackageVersion.plist */, 127 | 654B3C881F6A627500886397 /* WeChatHook-Prefix.pch */, 128 | ); 129 | name = "Supporting Files"; 130 | sourceTree = ""; 131 | }; 132 | 654B3C8D1F6A627500886397 /* usr */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 654B3C8E1F6A627500886397 /* lib */, 136 | ); 137 | name = usr; 138 | sourceTree = ""; 139 | }; 140 | 654B3C8E1F6A627500886397 /* lib */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 654B3C8F1F6A627500886397 /* 0xdeadfa11 */, 144 | ); 145 | name = lib; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXHeadersBuildPhase section */ 151 | 654B3C771F6A627500886397 /* Headers */ = { 152 | isa = PBXHeadersBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | 651AB7851F6FA30100E7082C /* WeChatManager.h in Headers */, 156 | 654B3C961F6A62BF00886397 /* CaptainHook.h in Headers */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXHeadersBuildPhase section */ 161 | 162 | /* Begin PBXNativeTarget section */ 163 | 654B3C791F6A627500886397 /* WeChatHook */ = { 164 | isa = PBXNativeTarget; 165 | buildConfigurationList = 654B3C921F6A627500886397 /* Build configuration list for PBXNativeTarget "WeChatHook" */; 166 | buildPhases = ( 167 | 654B3C751F6A627500886397 /* Sources */, 168 | 654B3C761F6A627500886397 /* Frameworks */, 169 | 654B3C771F6A627500886397 /* Headers */, 170 | 654B3C781F6A627500886397 /* ShellScript */, 171 | ); 172 | buildRules = ( 173 | ); 174 | dependencies = ( 175 | ); 176 | name = WeChatHook; 177 | productName = WeChatHook; 178 | productReference = 654B3C7A1F6A627500886397 /* libWeChatHook.dylib */; 179 | productType = "com.apple.product-type.library.dynamic"; 180 | }; 181 | /* End PBXNativeTarget section */ 182 | 183 | /* Begin PBXProject section */ 184 | 654B3C711F6A627500886397 /* Project object */ = { 185 | isa = PBXProject; 186 | attributes = { 187 | LastUpgradeCheck = 0830; 188 | TargetAttributes = { 189 | 654B3C791F6A627500886397 = { 190 | CreatedOnToolsVersion = 8.3; 191 | DevelopmentTeam = EACARN623L; 192 | ProvisioningStyle = Automatic; 193 | }; 194 | }; 195 | }; 196 | buildConfigurationList = 654B3C741F6A627500886397 /* Build configuration list for PBXProject "WeChatHook" */; 197 | compatibilityVersion = "Xcode 3.2"; 198 | developmentRegion = English; 199 | hasScannedForEncodings = 0; 200 | knownRegions = ( 201 | en, 202 | ); 203 | mainGroup = 654B3C701F6A627500886397; 204 | productRefGroup = 654B3C7B1F6A627500886397 /* Products */; 205 | projectDirPath = ""; 206 | projectRoot = ""; 207 | targets = ( 208 | 654B3C791F6A627500886397 /* WeChatHook */, 209 | ); 210 | }; 211 | /* End PBXProject section */ 212 | 213 | /* Begin PBXShellScriptBuildPhase section */ 214 | 654B3C781F6A627500886397 /* ShellScript */ = { 215 | isa = PBXShellScriptBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | ); 219 | inputPaths = ( 220 | ); 221 | outputPaths = ( 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | shellPath = /bin/sh; 225 | shellScript = "/opt/iOSOpenDev/bin/iosod --xcbp"; 226 | }; 227 | /* End PBXShellScriptBuildPhase section */ 228 | 229 | /* Begin PBXSourcesBuildPhase section */ 230 | 654B3C751F6A627500886397 /* Sources */ = { 231 | isa = PBXSourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | 654B3C8C1F6A627500886397 /* WeChatHook.mm in Sources */, 235 | 651AB7861F6FA30100E7082C /* WeChatManager.m in Sources */, 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXSourcesBuildPhase section */ 240 | 241 | /* Begin XCBuildConfiguration section */ 242 | 654B3C901F6A627500886397 /* Debug */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | COPY_PHASE_STRIP = NO; 246 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 247 | FRAMEWORK_SEARCH_PATHS = ( 248 | "$(iOSOpenDevPath)/frameworks/**", 249 | "$(SDKROOT)/System/Library/PrivateFrameworks", 250 | ); 251 | GCC_C_LANGUAGE_STANDARD = gnu99; 252 | GCC_DYNAMIC_NO_PIC = NO; 253 | GCC_OPTIMIZATION_LEVEL = 0; 254 | GCC_PREPROCESSOR_DEFINITIONS = ( 255 | "DEBUG=1", 256 | "$(inherited)", 257 | ); 258 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 259 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 260 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 261 | GCC_WARN_UNUSED_VARIABLE = YES; 262 | HEADER_SEARCH_PATHS = "$(iOSOpenDevPath)/include/**"; 263 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 264 | LIBRARY_SEARCH_PATHS = "$(iOSOpenDevPath)/lib/**"; 265 | SDKROOT = iphoneos; 266 | TARGETED_DEVICE_FAMILY = "1,2"; 267 | VALIDATE_PRODUCT = NO; 268 | iOSOpenDevPath = /opt/iOSOpenDev; 269 | }; 270 | name = Debug; 271 | }; 272 | 654B3C911F6A627500886397 /* Release */ = { 273 | isa = XCBuildConfiguration; 274 | buildSettings = { 275 | COPY_PHASE_STRIP = YES; 276 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 277 | FRAMEWORK_SEARCH_PATHS = ( 278 | "$(iOSOpenDevPath)/frameworks/**", 279 | "$(SDKROOT)/System/Library/PrivateFrameworks", 280 | ); 281 | GCC_C_LANGUAGE_STANDARD = gnu99; 282 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 284 | GCC_WARN_UNUSED_VARIABLE = YES; 285 | HEADER_SEARCH_PATHS = "$(iOSOpenDevPath)/include/**"; 286 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 287 | LIBRARY_SEARCH_PATHS = "$(iOSOpenDevPath)/lib/**"; 288 | SDKROOT = iphoneos; 289 | TARGETED_DEVICE_FAMILY = "1,2"; 290 | VALIDATE_PRODUCT = YES; 291 | iOSOpenDevPath = /opt/iOSOpenDev; 292 | }; 293 | name = Release; 294 | }; 295 | 654B3C931F6A627500886397 /* Debug */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | CODE_SIGN_IDENTITY = ""; 299 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 300 | DEVELOPMENT_TEAM = ""; 301 | DYLIB_COMPATIBILITY_VERSION = 1; 302 | DYLIB_CURRENT_VERSION = 1; 303 | ENABLE_BITCODE = NO; 304 | EXECUTABLE_PREFIX = lib; 305 | FRAMEWORK_SEARCH_PATHS = ( 306 | "$(inherited)", 307 | "$(PROJECT_DIR)/WeChatHook", 308 | "$(PROJECT_DIR)", 309 | ); 310 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 311 | GCC_PREFIX_HEADER = "WeChatHook/WeChatHook-Prefix.pch"; 312 | INSTALL_PATH = /usr/lib; 313 | PRODUCT_NAME = "$(TARGET_NAME)"; 314 | PROVISIONING_PROFILE_SPECIFIER = ""; 315 | iOSOpenDevBuildPackageOnAnyBuild = NO; 316 | iOSOpenDevCopyOnBuild = NO; 317 | iOSOpenDevDevice = ""; 318 | iOSOpenDevInstallOnAnyBuild = NO; 319 | iOSOpenDevInstallOnProfiling = YES; 320 | iOSOpenDevRespringOnInstall = YES; 321 | iOSOpenDevUsePackageVersionPList = YES; 322 | }; 323 | name = Debug; 324 | }; 325 | 654B3C941F6A627500886397 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | CODE_SIGN_IDENTITY = ""; 329 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 330 | DEVELOPMENT_TEAM = ""; 331 | DYLIB_COMPATIBILITY_VERSION = 1; 332 | DYLIB_CURRENT_VERSION = 1; 333 | ENABLE_BITCODE = NO; 334 | EXECUTABLE_PREFIX = lib; 335 | FRAMEWORK_SEARCH_PATHS = ( 336 | "$(inherited)", 337 | "$(PROJECT_DIR)/WeChatHook", 338 | "$(PROJECT_DIR)", 339 | ); 340 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 341 | GCC_PREFIX_HEADER = "WeChatHook/WeChatHook-Prefix.pch"; 342 | INSTALL_PATH = /usr/lib; 343 | PRODUCT_NAME = "$(TARGET_NAME)"; 344 | PROVISIONING_PROFILE_SPECIFIER = ""; 345 | iOSOpenDevBuildPackageOnAnyBuild = NO; 346 | iOSOpenDevCopyOnBuild = NO; 347 | iOSOpenDevDevice = ""; 348 | iOSOpenDevInstallOnAnyBuild = NO; 349 | iOSOpenDevInstallOnProfiling = YES; 350 | iOSOpenDevRespringOnInstall = YES; 351 | iOSOpenDevUsePackageVersionPList = YES; 352 | }; 353 | name = Release; 354 | }; 355 | /* End XCBuildConfiguration section */ 356 | 357 | /* Begin XCConfigurationList section */ 358 | 654B3C741F6A627500886397 /* Build configuration list for PBXProject "WeChatHook" */ = { 359 | isa = XCConfigurationList; 360 | buildConfigurations = ( 361 | 654B3C901F6A627500886397 /* Debug */, 362 | 654B3C911F6A627500886397 /* Release */, 363 | ); 364 | defaultConfigurationIsVisible = 0; 365 | defaultConfigurationName = Release; 366 | }; 367 | 654B3C921F6A627500886397 /* Build configuration list for PBXNativeTarget "WeChatHook" */ = { 368 | isa = XCConfigurationList; 369 | buildConfigurations = ( 370 | 654B3C931F6A627500886397 /* Debug */, 371 | 654B3C941F6A627500886397 /* Release */, 372 | ); 373 | defaultConfigurationIsVisible = 0; 374 | defaultConfigurationName = Release; 375 | }; 376 | /* End XCConfigurationList section */ 377 | }; 378 | rootObject = 654B3C711F6A627500886397 /* Project object */; 379 | } 380 | -------------------------------------------------------------------------------- /WeChatHook.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WeChatHook.xcodeproj/project.xcworkspace/xcuserdata/EL.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElegantLiar/WeChatHook/59286e6a43f9897f95579e0a5a545afd388bdbae/WeChatHook.xcodeproj/project.xcworkspace/xcuserdata/EL.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WeChatHook.xcodeproj/xcuserdata/EL.xcuserdatad/xcschemes/WeChatHook.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /WeChatHook.xcodeproj/xcuserdata/EL.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeChatHook.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 654B3C791F6A627500886397 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WeChatHook/CaptainHook.h: -------------------------------------------------------------------------------- 1 | // Possible defines: 2 | // CHDebug if defined, CHDebugLog is equivalent to CHLog; else, emits no code 3 | // CHUseSubstrate if defined, uses MSMessageHookEx to hook methods, otherwise uses internal hooking routines. Warning! super call closures are only available on ARM platforms for recent releases of MobileSubstrate 4 | // CHEnableProfiling if defined, enables calls to CHProfileScope() 5 | // CHAppName should be set to the name of the application (if not, defaults to "CaptainHook"); used for logging and profiling 6 | 7 | #import 8 | #import 9 | #import 10 | #import 11 | 12 | #ifndef CHAppName 13 | #define CHAppName "CaptainHook" 14 | #endif 15 | 16 | #ifdef __clang__ 17 | #if __has_feature(objc_arc) 18 | #define CHHasARC 19 | #endif 20 | #endif 21 | 22 | // Some Debugging/Logging Commands 23 | 24 | #define CHStringify_(x) #x 25 | #define CHStringify(x) CHStringify_(x) 26 | #define CHConcat_(a, b) a ## b 27 | #define CHConcat(a, b) CHConcat_(a, b) 28 | 29 | #define CHNothing() do { } while(0) 30 | 31 | #define CHLocationInSource [NSString stringWithFormat:@CHStringify(__LINE__) " in %s", __FUNCTION__] 32 | 33 | #define CHLog(args...) NSLog(@CHAppName ": %@", [NSString stringWithFormat:args]) 34 | #define CHLogSource(args...) NSLog(@CHAppName " @ " CHStringify(__LINE__) " in %s: %@", __FUNCTION__, [NSString stringWithFormat:args]) 35 | 36 | #ifdef CHDebug 37 | #define CHDebugLog(args...) CHLog(args) 38 | #define CHDebugLogSource(args...) CHLogSource(args) 39 | #else 40 | #define CHDebugLog(args...) CHNothing() 41 | #define CHDebugLogSource(args...) CHNothing() 42 | #endif 43 | 44 | // Constructor 45 | #define CHConstructor static __attribute__((constructor)) void CHConcat(CHConstructor, __LINE__)() 46 | #define CHInline inline __attribute__((always_inline)) 47 | 48 | // Cached Class Declaration (allows hooking methods, and fast lookup of classes) 49 | struct CHClassDeclaration_ { 50 | Class class_; 51 | Class metaClass_; 52 | Class superClass_; 53 | }; 54 | typedef struct CHClassDeclaration_ CHClassDeclaration_; 55 | #define CHDeclareClass(name) \ 56 | @class name; \ 57 | static CHClassDeclaration_ name ## $; 58 | 59 | // Loading Cached Classes (use CHLoadClass when class is linkable, CHLoadLateClass when it isn't) 60 | static inline Class CHLoadClass_(CHClassDeclaration_ *declaration, Class value) 61 | { 62 | declaration->class_ = value; 63 | declaration->metaClass_ = object_getClass(value); 64 | declaration->superClass_ = class_getSuperclass(value); 65 | return value; 66 | } 67 | #define CHLoadLateClass(name) CHLoadClass_(&name ## $, objc_getClass(#name)) 68 | #define CHLoadClass(name) CHLoadClass_(&name ## $, [name class]) 69 | 70 | // Quick Lookup of cached classes, and common methods on them 71 | #define CHClass(name) name ## $.class_ 72 | #define CHMetaClass(name) name ## $.metaClass_ 73 | #define CHSuperClass(name) name ## $.superClass_ 74 | #define CHAlloc(name) ((name *)[CHClass(name) alloc]) 75 | #define CHSharedInstance(name) ((name *)[CHClass(name) sharedInstance]) 76 | #define CHIsClass(obj, name) [obj isKindOfClass:CHClass(name)] 77 | #define CHRespondsTo(obj, sel) [obj respondsToSelector:@selector(sel)] 78 | 79 | // Replacement Method Definition 80 | #define CHDeclareSig0_(return_type) \ 81 | const char *return_ = @encode(return_type); \ 82 | size_t return_len = __builtin_strlen(return_); \ 83 | char sig[return_len+2+1]; \ 84 | __builtin_memcpy(sig, return_, return_len); \ 85 | sig[return_len] = _C_ID; \ 86 | sig[return_len+1] = _C_SEL; \ 87 | sig[return_len+2] = '\0'; 88 | #define CHDeclareSig1_(return_type, type1) \ 89 | const char *return_ = @encode(return_type); \ 90 | size_t return_len = __builtin_strlen(return_); \ 91 | const char *type1_ = @encode(type1); \ 92 | size_t type1_len = __builtin_strlen(type1_); \ 93 | char sig[return_len+2+type1_len+1]; \ 94 | __builtin_memcpy(sig, return_, return_len); \ 95 | sig[return_len] = _C_ID; \ 96 | sig[return_len+1] = _C_SEL; \ 97 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 98 | sig[return_len+type1_len+2] = '\0'; 99 | #define CHDeclareSig2_(return_type, type1, type2) \ 100 | const char *return_ = @encode(return_type); \ 101 | size_t return_len = __builtin_strlen(return_); \ 102 | const char *type1_ = @encode(type1); \ 103 | size_t type1_len = __builtin_strlen(type1_); \ 104 | const char *type2_ = @encode(type2); \ 105 | size_t type2_len = __builtin_strlen(type2_); \ 106 | char sig[return_len+2+type1_len+type2_len+1]; \ 107 | __builtin_memcpy(sig, return_, return_len); \ 108 | sig[return_len] = _C_ID; \ 109 | sig[return_len+1] = _C_SEL; \ 110 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 111 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 112 | sig[return_len+type1_len+type2_len+2] = '\0'; 113 | #define CHDeclareSig3_(return_type, type1, type2, type3) \ 114 | const char *return_ = @encode(return_type); \ 115 | size_t return_len = __builtin_strlen(return_); \ 116 | const char *type1_ = @encode(type1); \ 117 | size_t type1_len = __builtin_strlen(type1_); \ 118 | const char *type2_ = @encode(type2); \ 119 | size_t type2_len = __builtin_strlen(type2_); \ 120 | const char *type3_ = @encode(type3); \ 121 | size_t type3_len = __builtin_strlen(type3_); \ 122 | char sig[return_len+2+type1_len+type2_len+type3_len+1]; \ 123 | __builtin_memcpy(sig, return_, return_len); \ 124 | sig[return_len] = _C_ID; \ 125 | sig[return_len+1] = _C_SEL; \ 126 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 127 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 128 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 129 | sig[return_len+type1_len+type2_len+type3_len+2] = '\0'; 130 | #define CHDeclareSig4_(return_type, type1, type2, type3, type4) \ 131 | const char *return_ = @encode(return_type); \ 132 | size_t return_len = __builtin_strlen(return_); \ 133 | const char *type1_ = @encode(type1); \ 134 | size_t type1_len = __builtin_strlen(type1_); \ 135 | const char *type2_ = @encode(type2); \ 136 | size_t type2_len = __builtin_strlen(type2_); \ 137 | const char *type3_ = @encode(type3); \ 138 | size_t type3_len = __builtin_strlen(type3_); \ 139 | const char *type4_ = @encode(type4); \ 140 | size_t type4_len = __builtin_strlen(type4_); \ 141 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+1]; \ 142 | __builtin_memcpy(sig, return_, return_len); \ 143 | sig[return_len] = _C_ID; \ 144 | sig[return_len+1] = _C_SEL; \ 145 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 146 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 147 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 148 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 149 | sig[return_len+type1_len+type2_len+type3_len+type4_len+2] = '\0'; 150 | #define CHDeclareSig5_(return_type, type1, type2, type3, type4, type5) \ 151 | const char *return_ = @encode(return_type); \ 152 | size_t return_len = __builtin_strlen(return_); \ 153 | const char *type1_ = @encode(type1); \ 154 | size_t type1_len = __builtin_strlen(type1_); \ 155 | const char *type2_ = @encode(type2); \ 156 | size_t type2_len = __builtin_strlen(type2_); \ 157 | const char *type3_ = @encode(type3); \ 158 | size_t type3_len = __builtin_strlen(type3_); \ 159 | const char *type4_ = @encode(type4); \ 160 | size_t type4_len = __builtin_strlen(type4_); \ 161 | const char *type5_ = @encode(type5); \ 162 | size_t type5_len = __builtin_strlen(type5_); \ 163 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+1]; \ 164 | __builtin_memcpy(sig, return_, return_len); \ 165 | sig[return_len] = _C_ID; \ 166 | sig[return_len+1] = _C_SEL; \ 167 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 168 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 169 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 170 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 171 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len], type5_, type5_len); \ 172 | sig[return_len+type1_len+type2_len+type3_len+type4_len+type5_len+2] = '\0'; 173 | #define CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6) \ 174 | const char *return_ = @encode(return_type); \ 175 | size_t return_len = __builtin_strlen(return_); \ 176 | const char *type1_ = @encode(type1); \ 177 | size_t type1_len = __builtin_strlen(type1_); \ 178 | const char *type2_ = @encode(type2); \ 179 | size_t type2_len = __builtin_strlen(type2_); \ 180 | const char *type3_ = @encode(type3); \ 181 | size_t type3_len = __builtin_strlen(type3_); \ 182 | const char *type4_ = @encode(type4); \ 183 | size_t type4_len = __builtin_strlen(type4_); \ 184 | const char *type5_ = @encode(type5); \ 185 | size_t type5_len = __builtin_strlen(type5_); \ 186 | const char *type6_ = @encode(type6); \ 187 | size_t type6_len = __builtin_strlen(type6_); \ 188 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+1]; \ 189 | __builtin_memcpy(sig, return_, return_len); \ 190 | sig[return_len] = _C_ID; \ 191 | sig[return_len+1] = _C_SEL; \ 192 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 193 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 194 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 195 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 196 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len], type5_, type5_len); \ 197 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len], type6_, type6_len); \ 198 | sig[return_len+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+2] = '\0'; 199 | #define CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7) \ 200 | const char *return_ = @encode(return_type); \ 201 | size_t return_len = __builtin_strlen(return_); \ 202 | const char *type1_ = @encode(type1); \ 203 | size_t type1_len = __builtin_strlen(type1_); \ 204 | const char *type2_ = @encode(type2); \ 205 | size_t type2_len = __builtin_strlen(type2_); \ 206 | const char *type3_ = @encode(type3); \ 207 | size_t type3_len = __builtin_strlen(type3_); \ 208 | const char *type4_ = @encode(type4); \ 209 | size_t type4_len = __builtin_strlen(type4_); \ 210 | const char *type5_ = @encode(type5); \ 211 | size_t type5_len = __builtin_strlen(type5_); \ 212 | const char *type6_ = @encode(type6); \ 213 | size_t type6_len = __builtin_strlen(type6_); \ 214 | const char *type7_ = @encode(type7); \ 215 | size_t type7_len = __builtin_strlen(type7_); \ 216 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+1]; \ 217 | __builtin_memcpy(sig, return_, return_len); \ 218 | sig[return_len] = _C_ID; \ 219 | sig[return_len+1] = _C_SEL; \ 220 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 221 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 222 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 223 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 224 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len], type5_, type5_len); \ 225 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len], type6_, type6_len); \ 226 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len], type7_, type7_len); \ 227 | sig[return_len+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+2] = '\0'; 228 | #define CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8) \ 229 | const char *return_ = @encode(return_type); \ 230 | size_t return_len = __builtin_strlen(return_); \ 231 | const char *type1_ = @encode(type1); \ 232 | size_t type1_len = __builtin_strlen(type1_); \ 233 | const char *type2_ = @encode(type2); \ 234 | size_t type2_len = __builtin_strlen(type2_); \ 235 | const char *type3_ = @encode(type3); \ 236 | size_t type3_len = __builtin_strlen(type3_); \ 237 | const char *type4_ = @encode(type4); \ 238 | size_t type4_len = __builtin_strlen(type4_); \ 239 | const char *type5_ = @encode(type5); \ 240 | size_t type5_len = __builtin_strlen(type5_); \ 241 | const char *type6_ = @encode(type6); \ 242 | size_t type6_len = __builtin_strlen(type6_); \ 243 | const char *type7_ = @encode(type7); \ 244 | size_t type7_len = __builtin_strlen(type7_); \ 245 | const char *type8_ = @encode(type8); \ 246 | size_t type8_len = __builtin_strlen(type8_); \ 247 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+type8_len+1]; \ 248 | __builtin_memcpy(sig, return_, return_len); \ 249 | sig[return_len] = _C_ID; \ 250 | sig[return_len+1] = _C_SEL; \ 251 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 252 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 253 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 254 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 255 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len], type5_, type5_len); \ 256 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len], type6_, type6_len); \ 257 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len], type7_, type7_len); \ 258 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len], type8_, type8_len); \ 259 | sig[return_len+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+type8_len+2] = '\0'; 260 | #define CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9) \ 261 | const char *return_ = @encode(return_type); \ 262 | size_t return_len = __builtin_strlen(return_); \ 263 | const char *type1_ = @encode(type1); \ 264 | size_t type1_len = __builtin_strlen(type1_); \ 265 | const char *type2_ = @encode(type2); \ 266 | size_t type2_len = __builtin_strlen(type2_); \ 267 | const char *type3_ = @encode(type3); \ 268 | size_t type3_len = __builtin_strlen(type3_); \ 269 | const char *type4_ = @encode(type4); \ 270 | size_t type4_len = __builtin_strlen(type4_); \ 271 | const char *type5_ = @encode(type5); \ 272 | size_t type5_len = __builtin_strlen(type5_); \ 273 | const char *type6_ = @encode(type6); \ 274 | size_t type6_len = __builtin_strlen(type6_); \ 275 | const char *type7_ = @encode(type7); \ 276 | size_t type7_len = __builtin_strlen(type7_); \ 277 | const char *type8_ = @encode(type8); \ 278 | size_t type8_len = __builtin_strlen(type8_); \ 279 | const char *type9_ = @encode(type9); \ 280 | size_t type9_len = __builtin_strlen(type9_); \ 281 | char sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+type8_len+type9_len+1]; \ 282 | __builtin_memcpy(sig, return_, return_len); \ 283 | sig[return_len] = _C_ID; \ 284 | sig[return_len+1] = _C_SEL; \ 285 | __builtin_memcpy(&sig[return_len+2], type1_, type1_len); \ 286 | __builtin_memcpy(&sig[return_len+2+type1_len], type2_, type2_len); \ 287 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len], type3_, type3_len); \ 288 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len], type4_, type4_len); \ 289 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len], type5_, type5_len); \ 290 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len], type6_, type6_len); \ 291 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len], type7_, type7_len); \ 292 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len], type8_, type8_len); \ 293 | __builtin_memcpy(&sig[return_len+2+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+type8_len], type9_, type9_len); \ 294 | sig[return_len+type1_len+type2_len+type3_len+type4_len+type5_len+type6_len+type7_len+type8_len+type9_len+2] = '\0'; 295 | 296 | #ifdef CHUseSubstrate 297 | #import 298 | #define CHMethod_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 299 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 300 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 301 | __attribute__((always_inline)) \ 302 | static inline void $ ## class_name ## _ ## name ## _register() { \ 303 | if (class_val) { \ 304 | MSHookMessageEx(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, (IMP *)&$ ## class_name ## _ ## name ## _super); \ 305 | if (!$ ## class_name ## _ ## name ## _super) { \ 306 | sigdef; \ 307 | class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, sig); \ 308 | } \ 309 | } \ 310 | } \ 311 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 312 | #define CHMethod_new_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 313 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 314 | __attribute__((always_inline)) \ 315 | static inline void $ ## class_name ## _ ## name ## _register() { \ 316 | sigdef; \ 317 | class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, sig); \ 318 | } \ 319 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 320 | #define CHMethod_super_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 321 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 322 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 323 | __attribute__((always_inline)) \ 324 | static inline void $ ## class_name ## _ ## name ## _register() { \ 325 | if (class_val) { \ 326 | MSHookMessageEx(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, (IMP *)&$ ## class_name ## _ ## name ## _super); \ 327 | } \ 328 | } \ 329 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 330 | #define CHMethod_self_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 331 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 332 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 333 | __attribute__((always_inline)) \ 334 | static inline void $ ## class_name ## _ ## name ## _register() { \ 335 | if (class_val) { \ 336 | MSHookMessageEx(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, (IMP *)&$ ## class_name ## _ ## name ## _super); \ 337 | } \ 338 | } \ 339 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 340 | #else 341 | #define CHMethod_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 342 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 343 | static return_type $ ## class_name ## _ ## name ## _closure(class_type self, SEL _cmd, ##args) { \ 344 | typedef return_type (*supType)(class_type, SEL, ## args); \ 345 | supType supFn = (supType)class_getMethodImplementation(super_class_val, _cmd); \ 346 | return supFn supercall; \ 347 | } \ 348 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 349 | __attribute__((always_inline)) \ 350 | static inline void $ ## class_name ## _ ## name ## _register() { \ 351 | Method method = class_getInstanceMethod(class_val, @selector(sel)); \ 352 | if (method) { \ 353 | $ ## class_name ## _ ## name ## _super = (__typeof__($ ## class_name ## _ ## name ## _super))method_getImplementation(method); \ 354 | if (class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, method_getTypeEncoding(method))) { \ 355 | $ ## class_name ## _ ## name ## _super = &$ ## class_name ## _ ## name ## _closure; \ 356 | } else { \ 357 | method_setImplementation(method, (IMP)&$ ## class_name ## _ ## name ## _method); \ 358 | } \ 359 | } else { \ 360 | sigdef; \ 361 | class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, sig); \ 362 | } \ 363 | } \ 364 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 365 | #define CHMethod_new_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 366 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 367 | __attribute__((always_inline)) \ 368 | static inline void $ ## class_name ## _ ## name ## _register() { \ 369 | sigdef; \ 370 | class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, sig); \ 371 | } \ 372 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 373 | #define CHMethod_super_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 374 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 375 | static return_type $ ## class_name ## _ ## name ## _closure(class_type self, SEL _cmd, ##args) { \ 376 | typedef return_type (*supType)(class_type, SEL, ## args); \ 377 | supType supFn = (supType)class_getMethodImplementation(super_class_val, _cmd); \ 378 | return supFn supercall; \ 379 | } \ 380 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 381 | __attribute__((always_inline)) \ 382 | static inline void $ ## class_name ## _ ## name ## _register() { \ 383 | Method method = class_getInstanceMethod(class_val, @selector(sel)); \ 384 | if (method) { \ 385 | $ ## class_name ## _ ## name ## _super = (__typeof__($ ## class_name ## _ ## name ## _super))method_getImplementation(method); \ 386 | if (class_addMethod(class_val, @selector(sel), (IMP)&$ ## class_name ## _ ## name ## _method, method_getTypeEncoding(method))) { \ 387 | $ ## class_name ## _ ## name ## _super = &$ ## class_name ## _ ## name ## _closure; \ 388 | } else { \ 389 | method_setImplementation(method, (IMP)&$ ## class_name ## _ ## name ## _method); \ 390 | } \ 391 | } \ 392 | } \ 393 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 394 | #define CHMethod_self_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 395 | static return_type (*$ ## class_name ## _ ## name ## _super)(class_type self, SEL _cmd, ##args); \ 396 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args); \ 397 | __attribute__((always_inline)) \ 398 | static inline void $ ## class_name ## _ ## name ## _register() { \ 399 | Method method = class_getInstanceMethod(class_val, @selector(sel)); \ 400 | if (method) { \ 401 | $ ## class_name ## _ ## name ## _super = (__typeof__($ ## class_name ## _ ## name ## _super))method_getImplementation(method); \ 402 | method_setImplementation(method, (IMP)&$ ## class_name ## _ ## name ## _method); \ 403 | } \ 404 | } \ 405 | static return_type $ ## class_name ## _ ## name ## _method(class_type self, SEL _cmd, ##args) 406 | #endif 407 | #define CHMethod(count, args...) \ 408 | CHMethod ## count(args) 409 | #define CHMethod0(return_type, class_type, name) \ 410 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 411 | #define CHMethod1(return_type, class_type, name1, type1, arg1) \ 412 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 413 | #define CHMethod2(return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 414 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 415 | #define CHMethod3(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 416 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 417 | #define CHMethod4(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 418 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 419 | #define CHMethod5(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 420 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 421 | #define CHMethod6(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 422 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 423 | #define CHMethod7(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 424 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 425 | #define CHMethod8(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 426 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 427 | #define CHMethod9(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 428 | CHMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 429 | #define CHClassMethod(count, args...) \ 430 | CHClassMethod ## count(args) 431 | #define CHClassMethod0(return_type, class_type, name) \ 432 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 433 | #define CHClassMethod1(return_type, class_type, name1, type1, arg1) \ 434 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 435 | #define CHClassMethod2(return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 436 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 437 | #define CHClassMethod3(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 438 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 439 | #define CHClassMethod4(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 440 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 441 | #define CHClassMethod5(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 442 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 443 | #define CHClassMethod6(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 444 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 445 | #define CHClassMethod7(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 446 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 447 | #define CHClassMethod8(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 448 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 449 | #define CHClassMethod9(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 450 | CHMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 451 | #define CHOptimizedMethod(count, args...) \ 452 | CHOptimizedMethod ## count(args) 453 | #define CHOptimizedMethod0(optimization, return_type, class_type, name) \ 454 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 455 | #define CHOptimizedMethod1(optimization, return_type, class_type, name1, type1, arg1) \ 456 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 457 | #define CHOptimizedMethod2(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 458 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 459 | #define CHOptimizedMethod3(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 460 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 461 | #define CHOptimizedMethod4(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 462 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 463 | #define CHOptimizedMethod5(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 464 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 465 | #define CHOptimizedMethod6(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 466 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 467 | #define CHOptimizedMethod7(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 468 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 469 | #define CHOptimizedMethod8(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 470 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 471 | #define CHOptimizedMethod9(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 472 | CHMethod_ ## optimization ## _(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 473 | #define CHOptimizedClassMethod(count, args...) \ 474 | CHOptimizedClassMethod ## count(args) 475 | #define CHOptimizedClassMethod0(optimization, return_type, class_type, name) \ 476 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 477 | #define CHOptimizedClassMethod1(optimization, return_type, class_type, name1, type1, arg1) \ 478 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 479 | #define CHOptimizedClassMethod2(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 480 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 481 | #define CHOptimizedClassMethod3(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 482 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 483 | #define CHOptimizedClassMethod4(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 484 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 485 | #define CHOptimizedClassMethod5(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 486 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 487 | #define CHOptimizedClassMethod6(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 488 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 489 | #define CHOptimizedClassMethod7(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 490 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 491 | #define CHOptimizedClassMethod8(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 492 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 493 | #define CHOptimizedClassMethod9(optimization, return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 494 | CHMethod_ ## optimization ## _(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 495 | 496 | // Replacement Method Registration 497 | #define CHHook_(class_name, name) \ 498 | $ ## class_name ## _ ## name ## _register() 499 | #define CHHook(count, args...) CHHook ## count(args) 500 | #define CHHook0(class, name) CHHook_(class, name) 501 | #define CHHook1(class, name1) CHHook_(class, name1 ## $) 502 | #define CHHook2(class, name1, name2) CHHook_(class, name1 ## $ ## name2 ## $) 503 | #define CHHook3(class, name1, name2, name3) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $) 504 | #define CHHook4(class, name1, name2, name3, name4) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $) 505 | #define CHHook5(class, name1, name2, name3, name4, name5) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $) 506 | #define CHHook6(class, name1, name2, name3, name4, name5, name6) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $) 507 | #define CHHook7(class, name1, name2, name3, name4, name5, name6, name7) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $) 508 | #define CHHook8(class, name1, name2, name3, name4, name5, name6, name7, name8) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $) 509 | #define CHHook9(class, name1, name2, name3, name4, name5, name6, name7, name8, name9) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $) 510 | #define CHClassHook(count, args...) CHClassHook ## count(args) 511 | #define CHClassHook0(class, name) CHHook_(class, name) 512 | #define CHClassHook1(class, name1) CHHook_(class, name1 ## $) 513 | #define CHClassHook2(class, name1, name2) CHHook_(class, name1 ## $ ## name2 ## $) 514 | #define CHClassHook3(class, name1, name2, name3) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $) 515 | #define CHClassHook4(class, name1, name2, name3, name4) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $) 516 | #define CHClassHook5(class, name1, name2, name3, name4, name5) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $) 517 | #define CHClassHook6(class, name1, name2, name3, name4, name5, name6) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $) 518 | #define CHClassHook7(class, name1, name2, name3, name4, name5, name6, name7) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $) 519 | #define CHClassHook8(class, name1, name2, name3, name4, name5, name6, name7, name8) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $) 520 | #define CHClassHook9(class, name1, name2, name3, name4, name5, name6, name7, name8, name9) CHHook_(class, name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $) 521 | 522 | // Declarative style methods (automatically calls CHHook) 523 | #define CHDeclareMethod_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, args...) \ 524 | static inline void $ ## class_name ## _ ## name ## _register(); \ 525 | __attribute__((constructor)) \ 526 | static inline void $ ## class_name ## _ ## name ## _constructor() { \ 527 | CHLoadLateClass(class_name); \ 528 | $ ## class_name ## _ ## name ## _register(); \ 529 | } \ 530 | CHMethod_(return_type, class_type, class_name, class_val, super_class_val, name, sel, sigdef, supercall, ##args) 531 | #define CHDeclareMethod(count, args...) \ 532 | CHDeclareMethod ## count(args) 533 | #define CHDeclareMethod0(return_type, class_type, name) \ 534 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 535 | #define CHDeclareMethod1(return_type, class_type, name1, type1, arg1) \ 536 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 537 | #define CHDeclareMethod2(return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 538 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 539 | #define CHDeclareMethod3(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 540 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 541 | #define CHDeclareMethod4(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 542 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 543 | #define CHDeclareMethod5(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 544 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## arg5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 545 | #define CHDeclareMethod6(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 546 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 547 | #define CHDeclareMethod7(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 548 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 549 | #define CHDeclareMethod8(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 550 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 551 | #define CHDeclareMethod9(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 552 | CHDeclareMethod_(return_type, class_type *, class_type, CHClass(class_type), CHSuperClass(class_type), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 553 | #define CHDeclareClassMethod(count, args...) \ 554 | CHDeclareClassMethod ## count(args) 555 | #define CHDeclareClassMethod0(return_type, class_type, name) \ 556 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name, name, CHDeclareSig0_(return_type), (self, _cmd)) 557 | #define CHDeclareClassMethod1(return_type, class_type, name1, type1, arg1) \ 558 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $, name1:, CHDeclareSig1_(return_type, type1), (self, _cmd, arg1), type1 arg1) 559 | #define CHDeclareClassMethod2(return_type, class_type, name1, type1, arg1, name2, type2, arg2) \ 560 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $, name1:name2:, CHDeclareSig2_(return_type, type1, type2), (self, _cmd, arg1, arg2), type1 arg1, type2 arg2) 561 | #define CHDeclareClassMethod3(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3) \ 562 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $, name1:name2:name3:, CHDeclareSig3_(return_type, type1, type2, type3), (self, _cmd, arg1, arg2, arg3), type1 arg1, type2 arg2, type3 arg3) 563 | #define CHDeclareClassMethod4(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4) \ 564 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, name1:name2:name3:name4:, CHDeclareSig4_(return_type, type1, type2, type3, type4), (self, _cmd, arg1, arg2, arg3, arg4), type1 arg1, type2 arg2, type3 arg3, type4 arg4) 565 | #define CHDeclareClassMethod5(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5) \ 566 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, name1:name2:name3:name4:name5:, CHDeclareSig5_(return_type, type1, type2, type3, type4, type5), (self, _cmd, arg1, arg2, arg3, arg4, arg5), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) 567 | #define CHDeclareClassMethod6(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6) \ 568 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, name1:name2:name3:name4:name5:name6:, CHDeclareSig6_(return_type, type1, type2, type3, type4, type5, type6), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) 569 | #define CHDeclareClassMethod7(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7) \ 570 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, name1:name2:name3:name4:name5:name6:name7:, CHDeclareSig7_(return_type, type1, type2, type3, type4, type5, type6, type7), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) 571 | #define CHDeclareClassMethod8(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8) \ 572 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, name1:name2:name3:name4:name5:name6:name7:name8:, CHDeclareSig8_(return_type, type1, type2, type3, type4, type5, type6, type7, type8), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) 573 | #define CHDeclareClassMethod9(return_type, class_type, name1, type1, arg1, name2, type2, arg2, name3, type3, arg3, name4, type4, arg4, name5, type5, arg5, name6, type6, arg6, name7, type7, arg7, name8, type8, arg8, name9, type9, arg9) \ 574 | CHDeclareMethod_(return_type, id, class_type, CHMetaClass(class_type), object_getClass(CHMetaClass(class_type)), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, name1:name2:name3:name4:name5:name6:name7:name8:name9:, CHDeclareSig9_(return_type, type1, type2, type3, type4, type5, type6, type7, type8, type9), (self, _cmd, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9), type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) 575 | 576 | // Calling super class (or the old method as the case may be) 577 | #define CHSuper_(class_type, _cmd, name, args...) \ 578 | $ ## class_type ## _ ## name ## _super(self, _cmd, ##args) 579 | #define CHSuper(count, args...) \ 580 | CHSuper ## count(args) 581 | #define CHSuper0(class_type, name) \ 582 | CHSuper_(class_type, @selector(name), name) 583 | #define CHSuper1(class_type, name1, val1) \ 584 | CHSuper_(class_type, @selector(name1:), name1 ## $, val1) 585 | #define CHSuper2(class_type, name1, val1, name2, val2) \ 586 | CHSuper_(class_type, @selector(name1:name2:), name1 ## $ ## name2 ## $, val1, val2) 587 | #define CHSuper3(class_type, name1, val1, name2, val2, name3, val3) \ 588 | CHSuper_(class_type, @selector(name1:name2:name3:), name1 ## $ ## name2 ## $ ## name3 ## $, val1, val2, val3) 589 | #define CHSuper4(class_type, name1, val1, name2, val2, name3, val3, name4, val4) \ 590 | CHSuper_(class_type, @selector(name1:name2:name3:name4:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $, val1, val2, val3, val4) 591 | #define CHSuper5(class_type, name1, val1, name2, val2, name3, val3, name4, val4, name5, val5) \ 592 | CHSuper_(class_type, @selector(name1:name2:name3:name4:name5:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $, val1, val2, val3, val4, val5) 593 | #define CHSuper6(class_type, name1, val1, name2, val2, name3, val3, name4, val4, name5, val5, name6, val6) \ 594 | CHSuper_(class_type, @selector(name1:name2:name3:name4:name5:name6:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $, val1, val2, val3, val4, val5, val6) 595 | #define CHSuper7(class_type, name1, val1, name2, val2, name3, val3, name4, val4, name5, val5, name6, val6, name7, val7) \ 596 | CHSuper_(class_type, @selector(name1:name2:name3:name4:name5:name6:name7:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $, val1, val2, val3, val4, val5, val6, val7) 597 | #define CHSuper8(class_type, name1, val1, name2, val2, name3, val3, name4, val4, name5, val5, name6, val6, name7, val7, name8, val8) \ 598 | CHSuper_(class_type, @selector(name1:name2:name3:name4:name5:name6:name7:name8:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $, val1, val2, val3, val4, val5, val6, val7, val8) 599 | #define CHSuper9(class_type, name1, val1, name2, val2, name3, val3, name4, val4, name5, val5, name6, val6, name7, val7, name8, val8, name9, val9) \ 600 | CHSuper_(class_type, @selector(name1:name2:name3:name4:name5:name6:name7:name8:name9:), name1 ## $ ## name2 ## $ ## name3 ## $ ## name4 ## $ ## name5 ## $ ## name6 ## $ ## name7 ## $ ## name8 ## $ ## name9 ## $, val1, val2, val3, val4, val5, val6, val7, val8, val9) 601 | 602 | // Create Class at Runtime (useful for creating subclasses of classes that can't be linked) 603 | #define CHRegisterClass(name, superName) for (int _tmp = ({ CHClass(name) = objc_allocateClassPair(CHClass(superName), #name, 0); CHMetaClass(name) = object_getClass(CHClass(name)); CHSuperClass(name) = class_getSuperclass(CHClass(name)); 1; }); _tmp; _tmp = ({ objc_registerClassPair(CHClass(name)), 0; })) 604 | #define CHAlignmentForSize_(size) ({ \ 605 | size_t s = size; \ 606 | __builtin_constant_p(s) ? ( \ 607 | (s) & (1 << 31) ? 31 : \ 608 | (s) & (1 << 30) ? 30 : \ 609 | (s) & (1 << 29) ? 29 : \ 610 | (s) & (1 << 28) ? 28 : \ 611 | (s) & (1 << 27) ? 27 : \ 612 | (s) & (1 << 26) ? 26 : \ 613 | (s) & (1 << 25) ? 25 : \ 614 | (s) & (1 << 24) ? 24 : \ 615 | (s) & (1 << 23) ? 23 : \ 616 | (s) & (1 << 22) ? 22 : \ 617 | (s) & (1 << 21) ? 21 : \ 618 | (s) & (1 << 20) ? 20 : \ 619 | (s) & (1 << 19) ? 19 : \ 620 | (s) & (1 << 18) ? 18 : \ 621 | (s) & (1 << 17) ? 17 : \ 622 | (s) & (1 << 16) ? 16 : \ 623 | (s) & (1 << 15) ? 15 : \ 624 | (s) & (1 << 14) ? 14 : \ 625 | (s) & (1 << 13) ? 13 : \ 626 | (s) & (1 << 12) ? 12 : \ 627 | (s) & (1 << 11) ? 11 : \ 628 | (s) & (1 << 10) ? 10 : \ 629 | (s) & (1 << 9) ? 9 : \ 630 | (s) & (1 << 8) ? 8 : \ 631 | (s) & (1 << 7) ? 7 : \ 632 | (s) & (1 << 6) ? 6 : \ 633 | (s) & (1 << 5) ? 5 : \ 634 | (s) & (1 << 4) ? 4 : \ 635 | (s) & (1 << 3) ? 3 : \ 636 | (s) & (1 << 2) ? 2 : \ 637 | (s) & (1 << 1) ? 1 : \ 638 | (s) & (1 << 0) ? 0 : \ 639 | 0 \ 640 | ) : (uint32_t)log2f(s); \ 641 | }) 642 | #define CHAddIvar(targetClass, name, type) \ 643 | class_addIvar(targetClass, #name, sizeof(type), CHAlignmentForSize_(sizeof(type)), @encode(type)) 644 | 645 | // Retrieve reference to an Ivar value (can read and assign) 646 | __attribute__((unused)) CHInline 647 | static void *CHIvar_(id object, const char *name) 648 | { 649 | Ivar ivar = class_getInstanceVariable(object_getClass(object), name); 650 | if (ivar) 651 | #ifdef CHHasARC 652 | return (void *)&((char *)(__bridge void *)object)[ivar_getOffset(ivar)]; 653 | #else 654 | return (void *)&((char *)object)[ivar_getOffset(ivar)]; 655 | #endif 656 | return NULL; 657 | } 658 | #define CHIvarRef(object, name, type) \ 659 | ((type *)CHIvar_(object, #name)) 660 | #define CHIvar(object, name, type) \ 661 | (*CHIvarRef(object, name, type)) 662 | // Warning: Dereferences NULL if object is nil or name isn't found. To avoid this save CHIvarRef(...) and test if != NULL 663 | 664 | #define CHDeclareProperty(class, name) static const char k ## class ## _ ## name; 665 | #define CHPropertyGetValue(class, name) objc_getAssociatedObject(self, &k ## class ## _ ## name ) 666 | #define CHPropertySetValue(class, name, value, policy) objc_setAssociatedObject(self, &k ## class ## _ ## name , value, policy) 667 | 668 | #define CHPropertyGetter(class, getter, type) CHOptimizedMethod0(new, type, class, getter) 669 | #define CHPropertySetter(class, setter, type, value) CHOptimizedMethod1(new, void, class, setter, type, value) 670 | 671 | // Obj-C dynamic property declaration (objects) 672 | #define CHProperty(class, type, getter, setter, policy) \ 673 | CHDeclareProperty(class, getter) \ 674 | CHPropertyGetter(class, getter, type) { \ 675 | return CHPropertyGetValue(class, getter); \ 676 | } \ 677 | CHPropertySetter(class, setter, type, getter) { \ 678 | CHPropertySetValue(class, getter, getter, policy); \ 679 | } 680 | #define CHPropertyRetain(class, type, getter, setter) CHProperty(class, type, getter, setter, OBJC_ASSOCIATION_RETAIN) 681 | #define CHPropertyRetainNonatomic(class, type, getter, setter) CHProperty(class, type, getter, setter, OBJC_ASSOCIATION_RETAIN_NONATOMIC) 682 | #define CHPropertyCopy(class, type, getter, setter) CHProperty(class, type, getter, setter, OBJC_ASSOCIATION_COPY) 683 | #define CHPropertyCopyNonatomic(class, type, getter, setter) CHProperty(class, type, getter, setter, OBJC_ASSOCIATION_COPY_NONATOMIC) 684 | #define CHPropertyAssign(class, type, getter, setter) CHProperty(class, type, getter, setter, OBJC_ASSOCIATION_ASSIGN) 685 | 686 | #define CHPrimitivePropertyGetValue(class, name, type, val, default) \ 687 | type val = default; \ 688 | do { \ 689 | NSNumber * objVal = CHPropertyGetValue(class, name); \ 690 | [objVal getValue:& val ]; \ 691 | } while(0) 692 | #define CHPrimitivePropertySetValue(class, name, type, val) \ 693 | do { \ 694 | NSValue *objVal = [NSValue value:& val withObjCType:@encode( type )]; \ 695 | CHPropertySetValue(class, name, objVal, OBJC_ASSOCIATION_RETAIN_NONATOMIC); \ 696 | } while(0) 697 | 698 | // Primitive property equivalent (ie. BOOL, int, structs) 699 | #define CHPrimitiveProperty(class, type, getter, setter, default) \ 700 | CHDeclareProperty(class, getter) \ 701 | CHOptimizedMethod0(new, type, class, getter) { \ 702 | CHPrimitivePropertyGetValue( class , getter , type , val , default ); \ 703 | return val; \ 704 | } \ 705 | CHOptimizedMethod1(new, void, class, setter, type, getter) { \ 706 | CHPrimitivePropertySetValue( class , getter, type , getter ); \ 707 | } 708 | 709 | #define CHHookProperty(class, getter, setter) \ 710 | do { \ 711 | CHHook0(class, getter); \ 712 | CHHook1(class, setter); \ 713 | } while(0) 714 | 715 | #ifndef CHHasARC 716 | // Scope Autorelease 717 | __attribute__((unused)) CHInline 718 | static void CHScopeReleased(id *sro) 719 | { 720 | [*sro release]; 721 | } 722 | #define CHScopeReleased \ 723 | __attribute__((cleanup(CHScopeReleased))) 724 | 725 | #define CHAutoreleasePoolForScope() \ 726 | NSAutoreleasePool *CHAutoreleasePoolForScope __attribute__((unused)) CHScopeReleased = [[NSAutoreleasePool alloc] init] 727 | #endif 728 | 729 | // Build Assertion 730 | #define CHBuildAssert(condition) \ 731 | ((void)sizeof(char[1 - 2*!!(condition)])) 732 | 733 | // Profiling 734 | #ifdef CHEnableProfiling 735 | #import 736 | struct CHProfileData 737 | { 738 | NSString *message; 739 | uint64_t startTime; 740 | }; 741 | __attribute__((unused)) CHInline 742 | static void CHProfileCalculateDurationAndLog_(struct CHProfileData *profileData) 743 | { 744 | uint64_t duration = mach_absolute_time() - profileData->startTime; 745 | mach_timebase_info_data_t info; 746 | mach_timebase_info(&info); 747 | duration = (duration * info.numer) / info.denom; 748 | CHLog(@"Profile time: %lldns; %@", duration, profileData->message); 749 | } 750 | #define CHProfileScopeWithString(string) \ 751 | struct CHProfileData _profileData __attribute__((cleanup(CHProfileCalculateDurationAndLog_))) = ({ struct CHProfileData _tmp; _tmp.message = (string); _tmp.startTime = mach_absolute_time(); _tmp; }) 752 | #else 753 | #define CHProfileScopeWithString(string) \ 754 | CHNothing() 755 | #endif 756 | #define CHProfileScopeWithFormat(args...) \ 757 | CHProfileScopeWithString(([NSString stringWithFormat:args])) 758 | #define CHProfileScope() \ 759 | CHProfileScopeWithFormat(@CHStringify(__LINE__) " in %s", __FUNCTION__) 760 | -------------------------------------------------------------------------------- /WeChatHook/Package/DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: cn.ss.productb.WeChatHook 2 | Name: WeChatHook 3 | Version: 0.1-1 4 | Description: 5 | Section: System 6 | Depends: firmware (>= 5.0) 7 | Conflicts: 8 | Replaces: 9 | Priority: optional 10 | Architecture: iphoneos-arm 11 | Author: EL 12 | dev: 13 | Homepage: 14 | Depiction: 15 | Maintainer: 16 | Icon: 17 | 18 | -------------------------------------------------------------------------------- /WeChatHook/Package/DEBIAN/control.txt: -------------------------------------------------------------------------------- 1 | 2 | The control file in the same directory as this file is the Debian control file that is needed 3 | to build the project's Debian package that's used by APT repositories like Cydia. 4 | 5 | For more on... 6 | Debian packages, see http://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html. 7 | Debian control files, see http://www.debian.org/doc/debian-policy/ch-controlfields.html. 8 | Cydia packages, see http://www.saurik.com/id/7. 9 | 10 | Note: This file (control.txt) was created only to provide an explaination about the Debian control file. This file can now be deleted. 11 | -------------------------------------------------------------------------------- /WeChatHook/Package/usr/lib/0xdeadfa11: -------------------------------------------------------------------------------- 1 | 2 | This file was created only to help build the project's group structure, and it can now be deleted. 3 | 4 | Why 0xdeadfa11? See http://developer.apple.com/library/ios/#technotes/tn2151/_index.html. 5 | -------------------------------------------------------------------------------- /WeChatHook/PackageVersion.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BugFix 6 | 7 | Major 8 | 1 9 | Minor 10 | 0 11 | PackageRevision 12 | 1 13 | Stage 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /WeChatHook/WeChatHook-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'WeChatHook' target in the 'WeChatHook' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /WeChatHook/WeChatHook.mm: -------------------------------------------------------------------------------- 1 | // 2 | // FishChat.mm 3 | // FishChat 4 | // 5 | // Created by 杨萧玉 on 2017/2/22. 6 | // Copyright (c) 2017年 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | // CaptainHook by Ryan Petrich 10 | // see https://github.com/rpetrich/CaptainHook/ 11 | 12 | #import 13 | #import 14 | #import "WeChatManager.h" 15 | #import 16 | #define CYCRIPT_PORT 8888 17 | 18 | CHDeclareClass(UIApplication) 19 | CHDeclareClass(MicroMessengerAppDelegate) 20 | CHDeclareClass(CMessageMgr) 21 | CHDeclareClass(WCDeviceStepObject) 22 | CHDeclareClass(NewSettingViewController) 23 | CHDeclareClass(MMTableViewInfo) 24 | CHDeclareClass(MMTableViewSectionInfo) 25 | CHDeclareClass(MMTableViewCellInfo) 26 | CHDeclareClass(MMTableView) 27 | CHDeclareClass(UIViewController) 28 | 29 | CHOptimizedMethod2(self, void, MicroMessengerAppDelegate, application, UIApplication *, application, didFinishLaunchingWithOptions, NSDictionary *, options){ 30 | CHSuper2(MicroMessengerAppDelegate, application, application, didFinishLaunchingWithOptions, options); 31 | 32 | // 监听 Cycript 8888 端口 33 | NSLog(@"## Start Cycript ##"); 34 | CYListenServer(CYCRIPT_PORT); 35 | } 36 | 37 | CHDeclareMethod1(void, MicroMessengerAppDelegate, applicationWillResignActive, UIApplication *, application){ 38 | [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:[WeChatManager manager]] forKey:kWechatSaveKey]; 39 | [[NSUserDefaults standardUserDefaults] synchronize]; 40 | } 41 | 42 | // 阻止撤回消息 43 | CHOptimizedMethod1(self, void, CMessageMgr, onRevokeMsg, id, msg){ 44 | [WeChatManager manager].revokeMsg = YES; 45 | CHSuper1(CMessageMgr, onRevokeMsg, msg); 46 | } 47 | 48 | CHDeclareMethod3(void, CMessageMgr, DelMsg, id, arg1, MsgList, id, arg2, DelAll, BOOL, arg3){ 49 | if ([WeChatManager manager].revokeMsg) { 50 | [WeChatManager manager].revokeMsg = NO; 51 | } else { 52 | CHSuper3(CMessageMgr, DelMsg, arg1, MsgList, arg2, DelAll, arg3); 53 | } 54 | } 55 | 56 | // 微信运动步数 57 | 58 | CHOptimizedMethod0(self, unsigned int, WCDeviceStepObject, m7StepCount){ 59 | NSCalendar *cal = [NSCalendar currentCalendar]; 60 | NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; 61 | NSDate *today = [cal dateFromComponents:components]; 62 | components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[WeChatManager manager].lastChangeStepCountDate]; 63 | NSDate *otherDate = [cal dateFromComponents:components]; 64 | BOOL modifyToday = NO; 65 | if([today isEqualToDate:otherDate]) modifyToday = YES; 66 | if ([WeChatManager manager].stepCount == 0 || !modifyToday) { 67 | [WeChatManager manager].stepCount = CHSuper0(WCDeviceStepObject, m7StepCount); 68 | } 69 | return [WeChatManager manager].stepCount; 70 | } 71 | 72 | // 设置 73 | 74 | CHDeclareMethod0(void, NewSettingViewController, reloadTableData){ 75 | CHSuper0(NewSettingViewController, reloadTableData); 76 | MMTableViewInfo *tableInfo = [self valueForKeyPath:@"m_tableViewInfo"]; 77 | MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut]; 78 | MMTableViewCellInfo *stepcountCellInfo = [objc_getClass("MMTableViewCellInfo") editorCellForSel:@selector(recordStepCount:) target:[WeChatManager manager] title:@"微信运动步数" margin:300.0 tip:@"请输入步数" focus:NO text:[NSString stringWithFormat:@"%ld", (long)[WeChatManager manager].stepCount]]; 79 | [sectionInfo addCell:stepcountCellInfo]; 80 | [tableInfo insertSection:sectionInfo At:0]; 81 | MMTableView *tableView = [tableInfo getTableView]; 82 | [tableView reloadData]; 83 | } 84 | 85 | CHConstructor{ 86 | @autoreleasepool{ 87 | CHLoadLateClass(MicroMessengerAppDelegate); // load class (that will be "available later") 88 | CHHook2(MicroMessengerAppDelegate, application, didFinishLaunchingWithOptions); // register hook 89 | CHLoadLateClass(CMessageMgr); 90 | CHHook1(CMessageMgr, onRevokeMsg); 91 | CHLoadLateClass(WCDeviceStepObject); 92 | CHHook0(WCDeviceStepObject, m7StepCount); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /WeChatHook/WeChatManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatManager.h 3 | // WeChatHook 4 | // 5 | // Created by EL on 2017/9/18. 6 | // 7 | // 8 | 9 | #import 10 | 11 | extern NSString * const kWechatSaveKey; 12 | 13 | @interface WeChatManager : NSObject 14 | 15 | + (WeChatManager *)manager; 16 | 17 | @property (nonatomic, assign) NSInteger stepCount; 18 | @property (nonatomic, assign) BOOL revokeMsg; 19 | @property (nonatomic, strong) NSDate *lastChangeStepCountDate; 20 | 21 | - (void)recordStepCount:(UITextField *)textfield; 22 | @end 23 | -------------------------------------------------------------------------------- /WeChatHook/WeChatManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatManager.m 3 | // WeChatHook 4 | // 5 | // Created by EL on 2017/9/18. 6 | // 7 | // 8 | 9 | #import "WeChatManager.h" 10 | 11 | NSString * const kWechatSaveKey = @"kWechatSaveKey"; 12 | 13 | @implementation WeChatManager 14 | 15 | + (WeChatManager *)manager{ 16 | static WeChatManager *manager = nil; 17 | static dispatch_once_t oncePredicate; 18 | dispatch_once(&oncePredicate, ^{ 19 | manager = [[WeChatManager alloc] init]; 20 | }); 21 | return manager; 22 | } 23 | 24 | - (instancetype)init{ 25 | if (self == [super init]) { 26 | NSData *managerData = [[NSUserDefaults standardUserDefaults] objectForKey:kWechatSaveKey]; 27 | WeChatManager *manager = [NSKeyedUnarchiver unarchiveObjectWithData:managerData]; 28 | self.lastChangeStepCountDate = manager.lastChangeStepCountDate; 29 | self.stepCount = manager.stepCount; 30 | self.revokeMsg = manager.revokeMsg; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)recordStepCount:(UITextField *)textfield{ 36 | self.stepCount = textfield.text.integerValue; 37 | self.lastChangeStepCountDate = [NSDate date]; 38 | } 39 | 40 | #pragma mark - NSCoding 41 | - (void)encodeWithCoder:(NSCoder *)aCoder 42 | { 43 | [aCoder encodeInteger:self.stepCount forKey:@"stepCount"]; 44 | [aCoder encodeBool:self.revokeMsg forKey:@"revokeMsg"]; 45 | [aCoder encodeObject:self.lastChangeStepCountDate forKey:@"lastChangeStepCountDate"]; 46 | } 47 | 48 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 49 | { 50 | if (self = [super init]) { 51 | self.stepCount = [aDecoder decodeIntegerForKey:@"stepCount"]; 52 | self.revokeMsg = [aDecoder decodeBoolForKey:@"revokeMsg"]; 53 | self.lastChangeStepCountDate = [aDecoder decodeObjectForKey:@"lastChangeStepCountDate"]; 54 | } 55 | return self; 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /yololib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ElegantLiar/WeChatHook/59286e6a43f9897f95579e0a5a545afd388bdbae/yololib --------------------------------------------------------------------------------