├── 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
--------------------------------------------------------------------------------