├── .DS_Store ├── LatestBuild ├── README.md ├── WeChatRedEnvlop.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── zhangyu.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── zhangyu.xcuserdatad │ └── xcschemes │ ├── WeChatRedEnvlop.xcscheme │ ├── WeChatRedEnvlopDylib.xcscheme │ └── xcschememanagement.plist ├── WeChatRedEnvlop ├── .DS_Store ├── .gitattributes ├── Info.plist ├── README.md └── TargetApp │ ├── .DS_Store │ └── put ipa or app here └── WeChatRedEnvlopDylib ├── .DS_Store ├── AntiAntiDebug └── AntiAntiDebug.m ├── CaptainHook └── CaptainHook.h ├── JRSwizzle ├── JRSwizzle.h └── JRSwizzle.m ├── WBRedEnvelopParamQueue.h ├── WBRedEnvelopParamQueue.m ├── WeChatRedEnvelop.h ├── WeChatRedEnvelopParam.h ├── WeChatRedEnvelopParam.m ├── WeChatRedEnvlopDylib-Prefix.pch ├── WeChatRedEnvlopDylib.h ├── WeChatRedEnvlopDylib.m └── fishhook ├── fishhook.c └── fishhook.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/.DS_Store -------------------------------------------------------------------------------- /LatestBuild: -------------------------------------------------------------------------------- 1 | /Users/allen/Library/Developer/Xcode/DerivedData/WeChatRedEnvlop-bjacyzlvpwhwyzdfhaoytultdfcj/Build/Products/Debug-iphoneos -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WeChatRedEnvlop 2 | 基于猴神的MonkeyDev插件上的抢红包、修改微信步数、非群主@所有人、防止消息撤回插件 3 | 4 | ## 使用方式 5 | 1、从PP助手下载一个破解版的微信直接放入到WeChatRedEnvlop/WeChatRedEnvlop/TargetApp/ 6 | 7 | 2、修改Bundle ID为自己的证书 8 | 9 | 当然,首先需要安装猴神的MonkeyDev,详见:https://github.com/AloneMonkey/MonkeyDev 10 | 11 | 微信抢红包插件代码来源于:https://github.com/buginux/WeChatRedEnvelop 12 | 13 | 14 | 自己给自己发消息来控制开关 15 | ```objective-c 16 | 1. 打开红包插件 17 | 2. 关闭红包插件 18 | 3. 关闭抢自己红包 19 | 4. 关闭抢自己群红包 20 | 5. 修改微信步数# 21 | 6. 恢复微信步数 22 | ``` 23 | 24 | @所有人的使用方法 25 | 26 | ```objective-c 27 | #所有人 群发消息 28 | ``` 29 | --- 30 | 31 | 如果编译报错,请记得先把破解的微信放到目录里,由于偷懒,有的地方使用的头文件,如果不先放微信,可能会报错哟~ 32 | 33 | 可能有同学复制代码到自己的工程里会报错,需要修改两处配置 34 | ![](https://github.com/z306007236/screenshotssave/blob/master/WX20170803-151834.png?raw=true) 35 | ![](https://github.com/z306007236/screenshotssave/blob/master/WX20170803-151855.png?raw=true) 36 | 37 | 38 | --- 39 | ## 如何生成ipa? 40 | 在工程目录有一个LatestBuild文件夹,进去找到createIPA.command双击即可 41 | -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2A2876081F32FEBC00356D22 /* put ipa or app here in Resources */ = {isa = PBXBuildFile; fileRef = 2A2876071F32FEBC00356D22 /* put ipa or app here */; }; 11 | 2A2876111F32FEBC00356D22 /* Cycript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A2876101F32FEBC00356D22 /* Cycript.framework */; }; 12 | 2A2876131F32FEBC00356D22 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A2876121F32FEBC00356D22 /* JavaScriptCore.framework */; }; 13 | 2A2876151F32FEBC00356D22 /* RevealServer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A2876141F32FEBC00356D22 /* RevealServer.framework */; }; 14 | 2A2876171F32FEBC00356D22 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A2876161F32FEBC00356D22 /* Foundation.framework */; }; 15 | 2A2876191F32FEBC00356D22 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A2876181F32FEBC00356D22 /* UIKit.framework */; }; 16 | 2A28761D1F32FEBC00356D22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A28761C1F32FEBC00356D22 /* JRSwizzle.h */; }; 17 | 2A28761F1F32FEBC00356D22 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A28761E1F32FEBC00356D22 /* JRSwizzle.m */; }; 18 | 2A2876221F32FEBC00356D22 /* CaptainHook.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2876211F32FEBC00356D22 /* CaptainHook.h */; }; 19 | 2A2876241F32FEBC00356D22 /* WeChatRedEnvlopDylib-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 2A2876231F32FEBC00356D22 /* WeChatRedEnvlopDylib-Prefix.pch */; }; 20 | 2A2876271F32FEBC00356D22 /* AntiAntiDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2876261F32FEBC00356D22 /* AntiAntiDebug.m */; }; 21 | 2A28762A1F32FEBC00356D22 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A2876291F32FEBC00356D22 /* fishhook.c */; }; 22 | 2A28762C1F32FEBC00356D22 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A28762B1F32FEBC00356D22 /* fishhook.h */; }; 23 | 2A28762E1F32FEBC00356D22 /* WeChatRedEnvlopDylib.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A28762D1F32FEBC00356D22 /* WeChatRedEnvlopDylib.h */; }; 24 | 2A2876301F32FEBC00356D22 /* WeChatRedEnvlopDylib.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A28762F1F32FEBC00356D22 /* WeChatRedEnvlopDylib.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 25 | 2A28763E1F32FECF00356D22 /* WeChatRedEnvelopParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2876391F32FECF00356D22 /* WeChatRedEnvelopParam.h */; }; 26 | 2A28763F1F32FECF00356D22 /* WeChatRedEnvelopParam.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A28763A1F32FECF00356D22 /* WeChatRedEnvelopParam.m */; }; 27 | 2A2876401F32FECF00356D22 /* WBRedEnvelopParamQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A28763B1F32FECF00356D22 /* WBRedEnvelopParamQueue.h */; }; 28 | 2A2876411F32FECF00356D22 /* WBRedEnvelopParamQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A28763C1F32FECF00356D22 /* WBRedEnvelopParamQueue.m */; }; 29 | 2A2876421F32FECF00356D22 /* WeChatRedEnvelop.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A28763D1F32FECF00356D22 /* WeChatRedEnvelop.h */; }; 30 | 2A2876431F32FEF500356D22 /* libWeChatRedEnvlopDylib.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A28760E1F32FEBC00356D22 /* libWeChatRedEnvlopDylib.dylib */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 2A2876031F32FEBC00356D22 /* WeChatRedEnvlop.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WeChatRedEnvlop.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 2A2876071F32FEBC00356D22 /* put ipa or app here */ = {isa = PBXFileReference; lastKnownFileType = text; name = "put ipa or app here"; path = "TargetApp/put ipa or app here"; sourceTree = ""; }; 36 | 2A2876091F32FEBC00356D22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | 2A28760E1F32FEBC00356D22 /* libWeChatRedEnvlopDylib.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWeChatRedEnvlopDylib.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 2A2876101F32FEBC00356D22 /* Cycript.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cycript.framework; path = Library/Frameworks/Cycript.framework; sourceTree = DEVELOPER_DIR; }; 39 | 2A2876121F32FEBC00356D22 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 40 | 2A2876141F32FEBC00356D22 /* RevealServer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RevealServer.framework; path = Library/Frameworks/RevealServer.framework; sourceTree = DEVELOPER_DIR; }; 41 | 2A2876161F32FEBC00356D22 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 42 | 2A2876181F32FEBC00356D22 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | 2A28761C1F32FEBC00356D22 /* JRSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JRSwizzle.h; path = JRSwizzle/JRSwizzle.h; sourceTree = ""; }; 44 | 2A28761E1F32FEBC00356D22 /* JRSwizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = JRSwizzle.m; path = JRSwizzle/JRSwizzle.m; sourceTree = ""; }; 45 | 2A2876211F32FEBC00356D22 /* CaptainHook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CaptainHook.h; path = CaptainHook/CaptainHook.h; sourceTree = ""; }; 46 | 2A2876231F32FEBC00356D22 /* WeChatRedEnvlopDylib-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WeChatRedEnvlopDylib-Prefix.pch"; sourceTree = ""; }; 47 | 2A2876261F32FEBC00356D22 /* AntiAntiDebug.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AntiAntiDebug.m; path = AntiAntiDebug/AntiAntiDebug.m; sourceTree = ""; }; 48 | 2A2876291F32FEBC00356D22 /* fishhook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = fishhook.c; path = fishhook/fishhook.c; sourceTree = ""; }; 49 | 2A28762B1F32FEBC00356D22 /* fishhook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = fishhook/fishhook.h; sourceTree = ""; }; 50 | 2A28762D1F32FEBC00356D22 /* WeChatRedEnvlopDylib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeChatRedEnvlopDylib.h; sourceTree = ""; }; 51 | 2A28762F1F32FEBC00356D22 /* WeChatRedEnvlopDylib.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WeChatRedEnvlopDylib.m; sourceTree = ""; }; 52 | 2A2876391F32FECF00356D22 /* WeChatRedEnvelopParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeChatRedEnvelopParam.h; sourceTree = ""; }; 53 | 2A28763A1F32FECF00356D22 /* WeChatRedEnvelopParam.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeChatRedEnvelopParam.m; sourceTree = ""; }; 54 | 2A28763B1F32FECF00356D22 /* WBRedEnvelopParamQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WBRedEnvelopParamQueue.h; sourceTree = ""; }; 55 | 2A28763C1F32FECF00356D22 /* WBRedEnvelopParamQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WBRedEnvelopParamQueue.m; sourceTree = ""; }; 56 | 2A28763D1F32FECF00356D22 /* WeChatRedEnvelop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeChatRedEnvelop.h; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | 2A2875FF1F32FEBC00356D22 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | 2A2876431F32FEF500356D22 /* libWeChatRedEnvlopDylib.dylib in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | 2A28760B1F32FEBC00356D22 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | 2A2876131F32FEBC00356D22 /* JavaScriptCore.framework in Frameworks */, 73 | 2A2876151F32FEBC00356D22 /* RevealServer.framework in Frameworks */, 74 | 2A2876111F32FEBC00356D22 /* Cycript.framework in Frameworks */, 75 | 2A2876171F32FEBC00356D22 /* Foundation.framework in Frameworks */, 76 | 2A2876191F32FEBC00356D22 /* UIKit.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXFrameworksBuildPhase section */ 81 | 82 | /* Begin PBXGroup section */ 83 | 2A2875F91F32FEBC00356D22 = { 84 | isa = PBXGroup; 85 | children = ( 86 | 2A2876051F32FEBC00356D22 /* WeChatRedEnvlop */, 87 | 2A28761A1F32FEBC00356D22 /* WeChatRedEnvlopDylib */, 88 | 2A28760F1F32FEBC00356D22 /* Frameworks */, 89 | 2A2876041F32FEBC00356D22 /* Products */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | 2A2876041F32FEBC00356D22 /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 2A2876031F32FEBC00356D22 /* WeChatRedEnvlop.app */, 97 | 2A28760E1F32FEBC00356D22 /* libWeChatRedEnvlopDylib.dylib */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 2A2876051F32FEBC00356D22 /* WeChatRedEnvlop */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 2A2876091F32FEBC00356D22 /* Info.plist */, 106 | 2A2876061F32FEBC00356D22 /* TargetApp */, 107 | ); 108 | path = WeChatRedEnvlop; 109 | sourceTree = ""; 110 | }; 111 | 2A2876061F32FEBC00356D22 /* TargetApp */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 2A2876071F32FEBC00356D22 /* put ipa or app here */, 115 | ); 116 | name = TargetApp; 117 | sourceTree = ""; 118 | }; 119 | 2A28760F1F32FEBC00356D22 /* Frameworks */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 2A2876101F32FEBC00356D22 /* Cycript.framework */, 123 | 2A2876121F32FEBC00356D22 /* JavaScriptCore.framework */, 124 | 2A2876141F32FEBC00356D22 /* RevealServer.framework */, 125 | 2A2876161F32FEBC00356D22 /* Foundation.framework */, 126 | 2A2876181F32FEBC00356D22 /* UIKit.framework */, 127 | ); 128 | name = Frameworks; 129 | sourceTree = ""; 130 | }; 131 | 2A28761A1F32FEBC00356D22 /* WeChatRedEnvlopDylib */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 2A2876391F32FECF00356D22 /* WeChatRedEnvelopParam.h */, 135 | 2A28763A1F32FECF00356D22 /* WeChatRedEnvelopParam.m */, 136 | 2A28763B1F32FECF00356D22 /* WBRedEnvelopParamQueue.h */, 137 | 2A28763C1F32FECF00356D22 /* WBRedEnvelopParamQueue.m */, 138 | 2A28763D1F32FECF00356D22 /* WeChatRedEnvelop.h */, 139 | 2A2876231F32FEBC00356D22 /* WeChatRedEnvlopDylib-Prefix.pch */, 140 | 2A28762D1F32FEBC00356D22 /* WeChatRedEnvlopDylib.h */, 141 | 2A28762F1F32FEBC00356D22 /* WeChatRedEnvlopDylib.m */, 142 | 2A28761B1F32FEBC00356D22 /* JRSwizzle */, 143 | 2A2876201F32FEBC00356D22 /* CaptainHook */, 144 | 2A2876251F32FEBC00356D22 /* AntiAntiDebug */, 145 | 2A2876281F32FEBC00356D22 /* fishhook */, 146 | ); 147 | path = WeChatRedEnvlopDylib; 148 | sourceTree = ""; 149 | }; 150 | 2A28761B1F32FEBC00356D22 /* JRSwizzle */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 2A28761C1F32FEBC00356D22 /* JRSwizzle.h */, 154 | 2A28761E1F32FEBC00356D22 /* JRSwizzle.m */, 155 | ); 156 | name = JRSwizzle; 157 | sourceTree = ""; 158 | }; 159 | 2A2876201F32FEBC00356D22 /* CaptainHook */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 2A2876211F32FEBC00356D22 /* CaptainHook.h */, 163 | ); 164 | name = CaptainHook; 165 | sourceTree = ""; 166 | }; 167 | 2A2876251F32FEBC00356D22 /* AntiAntiDebug */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 2A2876261F32FEBC00356D22 /* AntiAntiDebug.m */, 171 | ); 172 | name = AntiAntiDebug; 173 | sourceTree = ""; 174 | }; 175 | 2A2876281F32FEBC00356D22 /* fishhook */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 2A2876291F32FEBC00356D22 /* fishhook.c */, 179 | 2A28762B1F32FEBC00356D22 /* fishhook.h */, 180 | ); 181 | name = fishhook; 182 | sourceTree = ""; 183 | }; 184 | /* End PBXGroup section */ 185 | 186 | /* Begin PBXHeadersBuildPhase section */ 187 | 2A28760C1F32FEBC00356D22 /* Headers */ = { 188 | isa = PBXHeadersBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 2A2876421F32FECF00356D22 /* WeChatRedEnvelop.h in Headers */, 192 | 2A2876221F32FEBC00356D22 /* CaptainHook.h in Headers */, 193 | 2A2876401F32FECF00356D22 /* WBRedEnvelopParamQueue.h in Headers */, 194 | 2A28762E1F32FEBC00356D22 /* WeChatRedEnvlopDylib.h in Headers */, 195 | 2A28761D1F32FEBC00356D22 /* JRSwizzle.h in Headers */, 196 | 2A2876241F32FEBC00356D22 /* WeChatRedEnvlopDylib-Prefix.pch in Headers */, 197 | 2A28763E1F32FECF00356D22 /* WeChatRedEnvelopParam.h in Headers */, 198 | 2A28762C1F32FEBC00356D22 /* fishhook.h in Headers */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | /* End PBXHeadersBuildPhase section */ 203 | 204 | /* Begin PBXNativeTarget section */ 205 | 2A2876021F32FEBC00356D22 /* WeChatRedEnvlop */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 2A2876331F32FEBC00356D22 /* Build configuration list for PBXNativeTarget "WeChatRedEnvlop" */; 208 | buildPhases = ( 209 | 2A2875FE1F32FEBC00356D22 /* Sources */, 210 | 2A2875FF1F32FEBC00356D22 /* Frameworks */, 211 | 2A2876001F32FEBC00356D22 /* Resources */, 212 | 2A2876011F32FEBC00356D22 /* ShellScript */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | ); 218 | name = WeChatRedEnvlop; 219 | productName = WeChatRedEnvlop; 220 | productReference = 2A2876031F32FEBC00356D22 /* WeChatRedEnvlop.app */; 221 | productType = "com.apple.product-type.application"; 222 | }; 223 | 2A28760D1F32FEBC00356D22 /* WeChatRedEnvlopDylib */ = { 224 | isa = PBXNativeTarget; 225 | buildConfigurationList = 2A2876361F32FEBC00356D22 /* Build configuration list for PBXNativeTarget "WeChatRedEnvlopDylib" */; 226 | buildPhases = ( 227 | 2A28760A1F32FEBC00356D22 /* Sources */, 228 | 2A28760B1F32FEBC00356D22 /* Frameworks */, 229 | 2A28760C1F32FEBC00356D22 /* Headers */, 230 | ); 231 | buildRules = ( 232 | ); 233 | dependencies = ( 234 | ); 235 | name = WeChatRedEnvlopDylib; 236 | productName = WeChatRedEnvlopDylib; 237 | productReference = 2A28760E1F32FEBC00356D22 /* libWeChatRedEnvlopDylib.dylib */; 238 | productType = "com.apple.product-type.library.dynamic"; 239 | }; 240 | /* End PBXNativeTarget section */ 241 | 242 | /* Begin PBXProject section */ 243 | 2A2875FA1F32FEBC00356D22 /* Project object */ = { 244 | isa = PBXProject; 245 | attributes = { 246 | LastUpgradeCheck = 0830; 247 | ORGANIZATIONNAME = allen; 248 | TargetAttributes = { 249 | 2A2876021F32FEBC00356D22 = { 250 | CreatedOnToolsVersion = 8.3.2; 251 | DevelopmentTeam = Z56336Z3K8; 252 | ProvisioningStyle = Manual; 253 | }; 254 | 2A28760D1F32FEBC00356D22 = { 255 | CreatedOnToolsVersion = 8.3.2; 256 | DevelopmentTeam = 6SXXMB346X; 257 | ProvisioningStyle = Manual; 258 | }; 259 | }; 260 | }; 261 | buildConfigurationList = 2A2875FD1F32FEBC00356D22 /* Build configuration list for PBXProject "WeChatRedEnvlop" */; 262 | compatibilityVersion = "Xcode 3.2"; 263 | developmentRegion = English; 264 | hasScannedForEncodings = 0; 265 | knownRegions = ( 266 | en, 267 | ); 268 | mainGroup = 2A2875F91F32FEBC00356D22; 269 | productRefGroup = 2A2876041F32FEBC00356D22 /* Products */; 270 | projectDirPath = ""; 271 | projectRoot = ""; 272 | targets = ( 273 | 2A2876021F32FEBC00356D22 /* WeChatRedEnvlop */, 274 | 2A28760D1F32FEBC00356D22 /* WeChatRedEnvlopDylib */, 275 | ); 276 | }; 277 | /* End PBXProject section */ 278 | 279 | /* Begin PBXResourcesBuildPhase section */ 280 | 2A2876001F32FEBC00356D22 /* Resources */ = { 281 | isa = PBXResourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 2A2876081F32FEBC00356D22 /* put ipa or app here in Resources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXResourcesBuildPhase section */ 289 | 290 | /* Begin PBXShellScriptBuildPhase section */ 291 | 2A2876011F32FEBC00356D22 /* ShellScript */ = { 292 | isa = PBXShellScriptBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | inputPaths = ( 297 | ); 298 | outputPaths = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | shellPath = /bin/sh; 302 | shellScript = /opt/MonkeyDev/Tools/pack.sh; 303 | }; 304 | /* End PBXShellScriptBuildPhase section */ 305 | 306 | /* Begin PBXSourcesBuildPhase section */ 307 | 2A2875FE1F32FEBC00356D22 /* Sources */ = { 308 | isa = PBXSourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | 2A28760A1F32FEBC00356D22 /* Sources */ = { 315 | isa = PBXSourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 2A2876301F32FEBC00356D22 /* WeChatRedEnvlopDylib.m in Sources */, 319 | 2A28761F1F32FEBC00356D22 /* JRSwizzle.m in Sources */, 320 | 2A28763F1F32FECF00356D22 /* WeChatRedEnvelopParam.m in Sources */, 321 | 2A28762A1F32FEBC00356D22 /* fishhook.c in Sources */, 322 | 2A2876411F32FECF00356D22 /* WBRedEnvelopParamQueue.m in Sources */, 323 | 2A2876271F32FEBC00356D22 /* AntiAntiDebug.m in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | /* End PBXSourcesBuildPhase section */ 328 | 329 | /* Begin XCBuildConfiguration section */ 330 | 2A2876311F32FEBC00356D22 /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_ANALYZER_NONNULL = YES; 335 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 336 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 337 | CLANG_CXX_LIBRARY = "libc++"; 338 | CLANG_ENABLE_MODULES = YES; 339 | CLANG_ENABLE_OBJC_ARC = YES; 340 | CLANG_WARN_BOOL_CONVERSION = YES; 341 | CLANG_WARN_CONSTANT_CONVERSION = YES; 342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 343 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 344 | CLANG_WARN_EMPTY_BODY = YES; 345 | CLANG_WARN_ENUM_CONVERSION = YES; 346 | CLANG_WARN_INFINITE_RECURSION = YES; 347 | CLANG_WARN_INT_CONVERSION = YES; 348 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 349 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 350 | CLANG_WARN_UNREACHABLE_CODE = YES; 351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 352 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 353 | COPY_PHASE_STRIP = NO; 354 | DEBUG_INFORMATION_FORMAT = dwarf; 355 | ENABLE_STRICT_OBJC_MSGSEND = YES; 356 | ENABLE_TESTABILITY = YES; 357 | GCC_C_LANGUAGE_STANDARD = gnu99; 358 | GCC_DYNAMIC_NO_PIC = NO; 359 | GCC_NO_COMMON_BLOCKS = YES; 360 | GCC_OPTIMIZATION_LEVEL = 0; 361 | GCC_PREPROCESSOR_DEFINITIONS = ( 362 | "DEBUG=1", 363 | "$(inherited)", 364 | ); 365 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 366 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 367 | GCC_WARN_UNDECLARED_SELECTOR = YES; 368 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 369 | GCC_WARN_UNUSED_FUNCTION = YES; 370 | GCC_WARN_UNUSED_VARIABLE = YES; 371 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 372 | MTL_ENABLE_DEBUG_INFO = YES; 373 | ONLY_ACTIVE_ARCH = YES; 374 | SDKROOT = iphoneos; 375 | }; 376 | name = Debug; 377 | }; 378 | 2A2876321F32FEBC00356D22 /* Release */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | ALWAYS_SEARCH_USER_PATHS = NO; 382 | CLANG_ANALYZER_NONNULL = YES; 383 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 384 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 385 | CLANG_CXX_LIBRARY = "libc++"; 386 | CLANG_ENABLE_MODULES = YES; 387 | CLANG_ENABLE_OBJC_ARC = YES; 388 | CLANG_WARN_BOOL_CONVERSION = YES; 389 | CLANG_WARN_CONSTANT_CONVERSION = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 392 | CLANG_WARN_EMPTY_BODY = YES; 393 | CLANG_WARN_ENUM_CONVERSION = YES; 394 | CLANG_WARN_INFINITE_RECURSION = YES; 395 | CLANG_WARN_INT_CONVERSION = YES; 396 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 397 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 398 | CLANG_WARN_UNREACHABLE_CODE = YES; 399 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 400 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 401 | COPY_PHASE_STRIP = NO; 402 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 403 | ENABLE_NS_ASSERTIONS = NO; 404 | ENABLE_STRICT_OBJC_MSGSEND = YES; 405 | GCC_C_LANGUAGE_STANDARD = gnu99; 406 | GCC_NO_COMMON_BLOCKS = YES; 407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 409 | GCC_WARN_UNDECLARED_SELECTOR = YES; 410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 411 | GCC_WARN_UNUSED_FUNCTION = YES; 412 | GCC_WARN_UNUSED_VARIABLE = YES; 413 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 414 | MTL_ENABLE_DEBUG_INFO = NO; 415 | SDKROOT = iphoneos; 416 | VALIDATE_PRODUCT = YES; 417 | }; 418 | name = Release; 419 | }; 420 | 2A2876341F32FEBC00356D22 /* Debug */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | DEVELOPMENT_TEAM = Z56336Z3K8; 424 | ENABLE_BITCODE = NO; 425 | INFOPLIST_FILE = WeChatRedEnvlop/Info.plist; 426 | MONKEYDEV_CLASS_DUMP = NO; 427 | MONKEYDEV_RESTORE_SYMBOL = NO; 428 | PODS_ROOT = "${SRCROOT}/Pods"; 429 | PRODUCT_BUNDLE_IDENTIFIER = com.hehei.jumai.weichat; 430 | PRODUCT_NAME = "$(TARGET_NAME)"; 431 | PROVISIONING_PROFILE = "36d7f716-6f23-4750-8a8d-0f8e54c414bd"; 432 | PROVISIONING_PROFILE_SPECIFIER = weichat.dev; 433 | }; 434 | name = Debug; 435 | }; 436 | 2A2876351F32FEBC00356D22 /* Release */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | DEVELOPMENT_TEAM = ""; 440 | ENABLE_BITCODE = NO; 441 | INFOPLIST_FILE = WeChatRedEnvlop/Info.plist; 442 | MONKEYDEV_CLASS_DUMP = NO; 443 | MONKEYDEV_RESTORE_SYMBOL = NO; 444 | PODS_ROOT = "${SRCROOT}/Pods"; 445 | PRODUCT_BUNDLE_IDENTIFIER = com.hehei.jumai.weichat; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | PROVISIONING_PROFILE_SPECIFIER = ""; 448 | }; 449 | name = Release; 450 | }; 451 | 2A2876371F32FEBC00356D22 /* Debug */ = { 452 | isa = XCBuildConfiguration; 453 | buildSettings = { 454 | DEVELOPMENT_TEAM = 6SXXMB346X; 455 | DYLIB_COMPATIBILITY_VERSION = 1; 456 | DYLIB_CURRENT_VERSION = 1; 457 | ENABLE_BITCODE = NO; 458 | ENABLE_STRICT_OBJC_MSGSEND = NO; 459 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 460 | EXECUTABLE_PREFIX = lib; 461 | FRAMEWORK_SEARCH_PATHS = ( 462 | "$(inherited)", 463 | "$(MonkeyDevPath)/Frameworks/**", 464 | "$(MonkeyDevPath)/Librarys/**", 465 | "$(MonkeyDevTheosPath)/vendor/lib", 466 | ); 467 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 468 | GCC_PREFIX_HEADER = "WeChatRedEnvlopDylib/WeChatRedEnvlopDylib-Prefix.pch"; 469 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 470 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 471 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 472 | HEADER_SEARCH_PATHS = ( 473 | "$(inherited)", 474 | "$(MonkeyDevTheosPath)/vendor/include/**", 475 | ); 476 | INFOPLIST_FILE = "$(SRCROOT)/WeChatRedEnvlop/Info.plist"; 477 | INSTALL_PATH = /usr/lib; 478 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 479 | LIBRARY_SEARCH_PATHS = ( 480 | "$(inherited)", 481 | "$(MonkeyDevPath)/Frameworks", 482 | "$(MonkeyDevTheosPath)/vendor/lib/**", 483 | ); 484 | MonkeyDevPath = /opt/MonkeyDev; 485 | MonkeyDevTheosPath = /opt/theos; 486 | OTHER_CFLAGS = ( 487 | "$(inherited)", 488 | "-DTHEOS_INSTANCE_NAME=\"\\\"WeChatRedEnvlopDylib\\\"\"", 489 | ); 490 | OTHER_LDFLAGS = ( 491 | "$(inherited)", 492 | "-weak_library", 493 | "/usr/lib/libc++.dylib", 494 | "-weak_library", 495 | "/usr/lib/libstdc++.dylib", 496 | "-lsubstrate", 497 | ); 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | PROVISIONING_PROFILE_SPECIFIER = ""; 500 | TARGETED_DEVICE_FAMILY = "1,2"; 501 | VALIDATE_PRODUCT = NO; 502 | }; 503 | name = Debug; 504 | }; 505 | 2A2876381F32FEBC00356D22 /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | COPY_PHASE_STRIP = YES; 509 | DEVELOPMENT_TEAM = ""; 510 | DYLIB_COMPATIBILITY_VERSION = 1; 511 | DYLIB_CURRENT_VERSION = 1; 512 | ENABLE_BITCODE = NO; 513 | ENABLE_STRICT_OBJC_MSGSEND = NO; 514 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj"; 515 | EXECUTABLE_PREFIX = lib; 516 | FRAMEWORK_SEARCH_PATHS = ( 517 | "$(inherited)", 518 | "$(MonkeyDevPath)/Frameworks/**", 519 | "$(MonkeyDevPath)/Librarys/**", 520 | "$(MonkeyDevTheosPath)/vendor/lib", 521 | ); 522 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 523 | GCC_PREFIX_HEADER = "WeChatRedEnvlopDylib/WeChatRedEnvlopDylib-Prefix.pch"; 524 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 525 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 526 | HEADER_SEARCH_PATHS = ( 527 | "$(inherited)", 528 | "$(MonkeyDevTheosPath)/vendor/include/**", 529 | ); 530 | INFOPLIST_FILE = "$(SRCROOT)/WeChatRedEnvlop/Info.plist"; 531 | INSTALL_PATH = /usr/lib; 532 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 533 | LIBRARY_SEARCH_PATHS = ( 534 | "$(inherited)", 535 | "$(MonkeyDevPath)/Frameworks", 536 | "$(MonkeyDevTheosPath)/vendor/lib/**", 537 | ); 538 | MonkeyDevPath = /opt/MonkeyDev; 539 | MonkeyDevTheosPath = /opt/theos; 540 | OTHER_CFLAGS = ( 541 | "$(inherited)", 542 | "-DTHEOS_INSTANCE_NAME=\"\\\"WeChatRedEnvlopDylib\\\"\"", 543 | ); 544 | OTHER_LDFLAGS = ( 545 | "$(inherited)", 546 | "-weak_library", 547 | "/usr/lib/libc++.dylib", 548 | "-weak_library", 549 | "/usr/lib/libstdc++.dylib", 550 | "-lsubstrate", 551 | ); 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | PROVISIONING_PROFILE_SPECIFIER = ""; 554 | TARGETED_DEVICE_FAMILY = "1,2"; 555 | }; 556 | name = Release; 557 | }; 558 | /* End XCBuildConfiguration section */ 559 | 560 | /* Begin XCConfigurationList section */ 561 | 2A2875FD1F32FEBC00356D22 /* Build configuration list for PBXProject "WeChatRedEnvlop" */ = { 562 | isa = XCConfigurationList; 563 | buildConfigurations = ( 564 | 2A2876311F32FEBC00356D22 /* Debug */, 565 | 2A2876321F32FEBC00356D22 /* Release */, 566 | ); 567 | defaultConfigurationIsVisible = 0; 568 | defaultConfigurationName = Release; 569 | }; 570 | 2A2876331F32FEBC00356D22 /* Build configuration list for PBXNativeTarget "WeChatRedEnvlop" */ = { 571 | isa = XCConfigurationList; 572 | buildConfigurations = ( 573 | 2A2876341F32FEBC00356D22 /* Debug */, 574 | 2A2876351F32FEBC00356D22 /* Release */, 575 | ); 576 | defaultConfigurationIsVisible = 0; 577 | }; 578 | 2A2876361F32FEBC00356D22 /* Build configuration list for PBXNativeTarget "WeChatRedEnvlopDylib" */ = { 579 | isa = XCConfigurationList; 580 | buildConfigurations = ( 581 | 2A2876371F32FEBC00356D22 /* Debug */, 582 | 2A2876381F32FEBC00356D22 /* Release */, 583 | ); 584 | defaultConfigurationIsVisible = 0; 585 | }; 586 | /* End XCConfigurationList section */ 587 | }; 588 | rootObject = 2A2875FA1F32FEBC00356D22 /* Project object */; 589 | } 590 | -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/project.xcworkspace/xcuserdata/zhangyu.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlop.xcodeproj/project.xcworkspace/xcuserdata/zhangyu.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/xcuserdata/zhangyu.xcuserdatad/xcschemes/WeChatRedEnvlop.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/xcuserdata/zhangyu.xcuserdatad/xcschemes/WeChatRedEnvlopDylib.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 | -------------------------------------------------------------------------------- /WeChatRedEnvlop.xcodeproj/xcuserdata/zhangyu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeChatRedEnvlop.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | WeChatRedEnvlopDylib.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 2A2876021F32FEBC00356D22 21 | 22 | primary 23 | 24 | 25 | 2A28760D1F32FEBC00356D22 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /WeChatRedEnvlop/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlop/.DS_Store -------------------------------------------------------------------------------- /WeChatRedEnvlop/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /WeChatRedEnvlop/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WeChatRedEnvlop/README.md: -------------------------------------------------------------------------------- 1 | # WeChatRedEnvlop 2 | -------------------------------------------------------------------------------- /WeChatRedEnvlop/TargetApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlop/TargetApp/.DS_Store -------------------------------------------------------------------------------- /WeChatRedEnvlop/TargetApp/put ipa or app here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlop/TargetApp/put ipa or app here -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlopDylib/.DS_Store -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/AntiAntiDebug/AntiAntiDebug.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // Created by AloneMonkey on 2016/12/10. 5 | // Copyright © 2017年 Coder. All rights reserved. 6 | // 7 | 8 | #import "fishhook.h" 9 | #import 10 | #import 11 | 12 | typedef int (*ptrace_ptr_t)(int _request,pid_t _pid, caddr_t _addr,int _data); 13 | typedef void* (*dlsym_ptr_t)(void * __handle, const char* __symbol); 14 | typedef int (*syscall_ptr_t)(int, ...); 15 | typedef int (*sysctl_ptr_t)(int *,u_int, void*, size_t*,void*, size_t); 16 | 17 | 18 | static ptrace_ptr_t orig_ptrace = NULL; 19 | static dlsym_ptr_t orig_dlsym = NULL; 20 | static syscall_ptr_t origin_syscall = NULL; 21 | static sysctl_ptr_t orig_sysctl = NULL; 22 | 23 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){ 24 | if(_request != 31){ 25 | return orig_ptrace(_request,_pid,_addr,_data); 26 | } 27 | 28 | NSLog(@"[AntiAntiDebug] - ptrace request is PT_DENY_ATTACH"); 29 | 30 | return 0; 31 | } 32 | 33 | void* my_dlsym(void* __handle, const char* __symbol){ 34 | if(strcmp(__symbol, "ptrace") != 0){ 35 | return orig_dlsym(__handle, __symbol); 36 | } 37 | 38 | NSLog(@"[AntiAntiDebug] - dlsym get ptrace symbol"); 39 | 40 | return my_ptrace; 41 | } 42 | 43 | typedef struct kinfo_proc _kinfo_proc; 44 | 45 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){ 46 | int ret = orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize); 47 | if(namelen == 4 && name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID && info && infosize && (*infosize == sizeof(_kinfo_proc))){ 48 | struct kinfo_proc *info_ptr = (struct kinfo_proc *)info; 49 | if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){ 50 | NSLog(@"[AntiAntiDebug] - sysctl query trace status."); 51 | info_ptr->kp_proc.p_flag ^= P_TRACED; 52 | if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){ 53 | NSLog(@"trace status reomve success!"); 54 | } 55 | } 56 | } 57 | return ret; 58 | } 59 | 60 | #ifndef __LP64__ 61 | void * my_syscall(long code, va_list args){ 62 | int request; 63 | va_list newArgs; 64 | va_copy(newArgs, args); 65 | if(code == 26){ 66 | request = (int)args; 67 | if(request == 31){ 68 | NSLog(@"[AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH"); 69 | return nil; 70 | } 71 | } 72 | return (void*)origin_syscall(code, newArgs); 73 | } 74 | #endif 75 | 76 | __attribute__((constructor)) static void entry(){ 77 | NSLog(@"[AntiAntiDebug Init]"); 78 | 79 | rebind_symbols((struct rebinding[1]){{"ptrace", my_ptrace, (void*)&orig_ptrace}},1); 80 | 81 | rebind_symbols((struct rebinding[1]){{"dlsym", my_dlsym, (void*)&orig_dlsym}},1); 82 | 83 | //some app will crash with _dyld_debugger_notification 84 | //rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1); 85 | 86 | #ifndef __LP64__ 87 | rebind_symbols((struct rebinding[1]){{"syscall", my_syscall, (void*)&origin_syscall}},1); 88 | #endif 89 | } 90 | 91 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/CaptainHook/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 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/JRSwizzle/JRSwizzle.h: -------------------------------------------------------------------------------- 1 | // JRSwizzle.h semver:1.1.0 2 | // Copyright (c) 2007-2016 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/jrswizzle 5 | 6 | #import 7 | 8 | @interface NSObject (JRSwizzle) 9 | 10 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_; 11 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_; 12 | 13 | 14 | /** 15 | ``` 16 | __block NSInvocation *invocation = nil; 17 | invocation = [self jr_swizzleMethod:@selector(initWithCoder:) withBlock:^(id obj, NSCoder *coder) { 18 | NSLog(@"before %@, coder %@", obj, coder); 19 | 20 | [invocation setArgument:&coder atIndex:2]; 21 | [invocation invokeWithTarget:obj]; 22 | 23 | id ret = nil; 24 | [invocation getReturnValue:&ret]; 25 | 26 | NSLog(@"after %@, coder %@", obj, coder); 27 | 28 | return ret; 29 | } error:nil]; 30 | ``` 31 | */ 32 | + (NSInvocation*)jr_swizzleMethod:(SEL)origSel withBlock:(id)block error:(NSError**)error; 33 | 34 | /** 35 | ``` 36 | __block NSInvocation *classInvocation = nil; 37 | classInvocation = [self jr_swizzleClassMethod:@selector(test) withBlock:^() { 38 | NSLog(@"before"); 39 | 40 | [classInvocation invoke]; 41 | 42 | NSLog(@"after"); 43 | } error:nil]; 44 | ``` 45 | */ 46 | + (NSInvocation*)jr_swizzleClassMethod:(SEL)origSel withBlock:(id)block error:(NSError**)error; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/JRSwizzle/JRSwizzle.m: -------------------------------------------------------------------------------- 1 | // JRSwizzle.m semver:1.1.0 2 | // Copyright (c) 2007-2016 Jonathan 'Wolf' Rentzsch: http://rentzsch.com 3 | // Some rights reserved: http://opensource.org/licenses/mit 4 | // https://github.com/rentzsch/jrswizzle 5 | 6 | #import "JRSwizzle.h" 7 | 8 | #if TARGET_OS_IPHONE 9 | #import 10 | #import 11 | #else 12 | #import 13 | #endif 14 | 15 | #define SetNSErrorFor(FUNC, ERROR_VAR, FORMAT,...) \ 16 | if (ERROR_VAR) { \ 17 | NSString *errStr = [NSString stringWithFormat:@"%s: " FORMAT,FUNC,##__VA_ARGS__]; \ 18 | *ERROR_VAR = [NSError errorWithDomain:@"NSCocoaErrorDomain" \ 19 | code:-1 \ 20 | userInfo:[NSDictionary dictionaryWithObject:errStr forKey:NSLocalizedDescriptionKey]]; \ 21 | } 22 | #define SetNSError(ERROR_VAR, FORMAT,...) SetNSErrorFor(__func__, ERROR_VAR, FORMAT, ##__VA_ARGS__) 23 | 24 | #if OBJC_API_VERSION >= 2 25 | #define GetClass(obj) object_getClass(obj) 26 | #else 27 | #define GetClass(obj) (obj ? obj->isa : Nil) 28 | #endif 29 | 30 | @implementation NSObject (JRSwizzle) 31 | 32 | + (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ { 33 | #if OBJC_API_VERSION >= 2 34 | Method origMethod = class_getInstanceMethod(self, origSel_); 35 | if (!origMethod) { 36 | #if TARGET_OS_IPHONE 37 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]); 38 | #else 39 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 40 | #endif 41 | return NO; 42 | } 43 | 44 | Method altMethod = class_getInstanceMethod(self, altSel_); 45 | if (!altMethod) { 46 | #if TARGET_OS_IPHONE 47 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]); 48 | #else 49 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 50 | #endif 51 | return NO; 52 | } 53 | 54 | class_addMethod(self, 55 | origSel_, 56 | class_getMethodImplementation(self, origSel_), 57 | method_getTypeEncoding(origMethod)); 58 | class_addMethod(self, 59 | altSel_, 60 | class_getMethodImplementation(self, altSel_), 61 | method_getTypeEncoding(altMethod)); 62 | 63 | method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_)); 64 | return YES; 65 | #else 66 | // Scan for non-inherited methods. 67 | Method directOriginalMethod = NULL, directAlternateMethod = NULL; 68 | 69 | void *iterator = NULL; 70 | struct objc_method_list *mlist = class_nextMethodList(self, &iterator); 71 | while (mlist) { 72 | int method_index = 0; 73 | for (; method_index < mlist->method_count; method_index++) { 74 | if (mlist->method_list[method_index].method_name == origSel_) { 75 | assert(!directOriginalMethod); 76 | directOriginalMethod = &mlist->method_list[method_index]; 77 | } 78 | if (mlist->method_list[method_index].method_name == altSel_) { 79 | assert(!directAlternateMethod); 80 | directAlternateMethod = &mlist->method_list[method_index]; 81 | } 82 | } 83 | mlist = class_nextMethodList(self, &iterator); 84 | } 85 | 86 | // If either method is inherited, copy it up to the target class to make it non-inherited. 87 | if (!directOriginalMethod || !directAlternateMethod) { 88 | Method inheritedOriginalMethod = NULL, inheritedAlternateMethod = NULL; 89 | if (!directOriginalMethod) { 90 | inheritedOriginalMethod = class_getInstanceMethod(self, origSel_); 91 | if (!inheritedOriginalMethod) { 92 | #if TARGET_OS_IPHONE 93 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]); 94 | #else 95 | SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]); 96 | #endif 97 | return NO; 98 | } 99 | } 100 | if (!directAlternateMethod) { 101 | inheritedAlternateMethod = class_getInstanceMethod(self, altSel_); 102 | if (!inheritedAlternateMethod) { 103 | #if TARGET_OS_IPHONE 104 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]); 105 | #else 106 | SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]); 107 | #endif 108 | return NO; 109 | } 110 | } 111 | 112 | int hoisted_method_count = !directOriginalMethod && !directAlternateMethod ? 2 : 1; 113 | struct objc_method_list *hoisted_method_list = malloc(sizeof(struct objc_method_list) + (sizeof(struct objc_method)*(hoisted_method_count-1))); 114 | hoisted_method_list->obsolete = NULL; // soothe valgrind - apparently ObjC runtime accesses this value and it shows as uninitialized in valgrind 115 | hoisted_method_list->method_count = hoisted_method_count; 116 | Method hoisted_method = hoisted_method_list->method_list; 117 | 118 | if (!directOriginalMethod) { 119 | bcopy(inheritedOriginalMethod, hoisted_method, sizeof(struct objc_method)); 120 | directOriginalMethod = hoisted_method++; 121 | } 122 | if (!directAlternateMethod) { 123 | bcopy(inheritedAlternateMethod, hoisted_method, sizeof(struct objc_method)); 124 | directAlternateMethod = hoisted_method; 125 | } 126 | class_addMethods(self, hoisted_method_list); 127 | } 128 | 129 | // Swizzle. 130 | IMP temp = directOriginalMethod->method_imp; 131 | directOriginalMethod->method_imp = directAlternateMethod->method_imp; 132 | directAlternateMethod->method_imp = temp; 133 | 134 | return YES; 135 | #endif 136 | } 137 | 138 | + (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ { 139 | return [GetClass((id)self) jr_swizzleMethod:origSel_ withMethod:altSel_ error:error_]; 140 | } 141 | 142 | + (NSInvocation*)jr_swizzleMethod:(SEL)origSel withBlock:(id)block error:(NSError**)error { 143 | IMP blockIMP = imp_implementationWithBlock(block); 144 | NSString *blockSelectorString = [NSString stringWithFormat:@"_jr_block_%@_%p", NSStringFromSelector(origSel), block]; 145 | SEL blockSel = sel_registerName([blockSelectorString cStringUsingEncoding:NSUTF8StringEncoding]); 146 | Method origSelMethod = class_getInstanceMethod(self, origSel); 147 | const char* origSelMethodArgs = method_getTypeEncoding(origSelMethod); 148 | class_addMethod(self, blockSel, blockIMP, origSelMethodArgs); 149 | 150 | NSMethodSignature *origSig = [NSMethodSignature signatureWithObjCTypes:origSelMethodArgs]; 151 | NSInvocation *origInvocation = [NSInvocation invocationWithMethodSignature:origSig]; 152 | origInvocation.selector = blockSel; 153 | 154 | [self jr_swizzleMethod:origSel withMethod:blockSel error:nil]; 155 | 156 | return origInvocation; 157 | } 158 | 159 | + (NSInvocation*)jr_swizzleClassMethod:(SEL)origSel withBlock:(id)block error:(NSError**)error { 160 | NSInvocation *invocation = [GetClass((id)self) jr_swizzleMethod:origSel withBlock:block error:error]; 161 | invocation.target = self; 162 | 163 | return invocation; 164 | } 165 | 166 | @end 167 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WBRedEnvelopParamQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBRedEnvelopParamQueue.h 3 | // WeChatRedEnvelop 4 | // 5 | // Created by 杨志超 on 2017/2/22. 6 | // Copyright © 2017年 swiftyper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class WeChatRedEnvelopParam; 12 | @interface WBRedEnvelopParamQueue : NSObject 13 | 14 | + (instancetype)sharedQueue; 15 | 16 | - (void)enqueue:(WeChatRedEnvelopParam *)param; 17 | - (WeChatRedEnvelopParam *)dequeue; 18 | - (WeChatRedEnvelopParam *)peek; 19 | - (BOOL)isEmpty; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WBRedEnvelopParamQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // WBRedEnvelopParamQueue.m 3 | // WeChatRedEnvelop 4 | // 5 | // Created by 杨志超 on 2017/2/22. 6 | // Copyright © 2017年 swiftyper. All rights reserved. 7 | // 8 | 9 | #import "WBRedEnvelopParamQueue.h" 10 | #import "WeChatRedEnvelopParam.h" 11 | 12 | @interface WBRedEnvelopParamQueue () 13 | 14 | @property (strong, nonatomic) NSMutableArray *queue; 15 | 16 | @end 17 | 18 | @implementation WBRedEnvelopParamQueue 19 | 20 | + (instancetype)sharedQueue { 21 | static WBRedEnvelopParamQueue *queue = nil; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | queue = [[WBRedEnvelopParamQueue alloc] init]; 25 | }); 26 | return queue; 27 | } 28 | 29 | - (instancetype)init { 30 | if (self = [super init]) { 31 | _queue = [[NSMutableArray alloc] init]; 32 | } 33 | return self; 34 | } 35 | 36 | - (void)enqueue:(WeChatRedEnvelopParam *)param { 37 | [self.queue addObject:param]; 38 | } 39 | 40 | - (WeChatRedEnvelopParam *)dequeue { 41 | if (self.queue.count == 0 && !self.queue.firstObject) { 42 | return nil; 43 | } 44 | 45 | WeChatRedEnvelopParam *first = self.queue.firstObject; 46 | 47 | [self.queue removeObjectAtIndex:0]; 48 | 49 | return first; 50 | } 51 | 52 | - (WeChatRedEnvelopParam *)peek { 53 | if (self.queue.count == 0) { 54 | return nil; 55 | } 56 | 57 | return self.queue.firstObject; 58 | } 59 | 60 | - (BOOL)isEmpty { 61 | return self.queue.count == 0; 62 | } 63 | 64 | 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvelop.h: -------------------------------------------------------------------------------- 1 | #pragma mark - Util 2 | 3 | @interface WCBizUtil : NSObject 4 | 5 | + (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2; 6 | 7 | @end 8 | 9 | @interface SKBuiltinBuffer_t : NSObject 10 | 11 | @property(retain, nonatomic) NSData *buffer; // @dynamic buffer; 12 | 13 | @end 14 | 15 | #pragma mark - Message 16 | 17 | @interface WCPayInfoItem: NSObject 18 | 19 | @property(retain, nonatomic) NSString *m_c2cNativeUrl; 20 | 21 | @end 22 | 23 | @interface CMessageMgr : NSObject 24 | 25 | - (void)AddLocalMsg:(id)arg1 MsgWrap:(id)arg2 fixTime:(_Bool)arg3 NewMsgArriveNotify:(_Bool)arg4; 26 | 27 | @end 28 | 29 | @interface CMessageWrap : NSObject 30 | 31 | @property (retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem; 32 | @property (assign, nonatomic) NSUInteger m_uiMesLocalID; 33 | @property (retain, nonatomic) NSString* m_nsFromUsr; ///< 发信人,可能是群或个人 34 | @property (retain, nonatomic) NSString* m_nsToUsr; ///< 收信人 35 | @property (assign, nonatomic) NSUInteger m_uiStatus; 36 | @property (retain, nonatomic) NSString* m_nsContent; ///< 消息内容 37 | @property (retain, nonatomic) NSString* m_nsRealChatUsr; ///< 群消息的发信人,具体是群里的哪个人 38 | @property (assign, nonatomic) NSUInteger m_uiMessageType; 39 | @property (assign, nonatomic) long long m_n64MesSvrID; 40 | @property (assign, nonatomic) NSUInteger m_uiCreateTime; 41 | @property (retain, nonatomic) NSString *m_nsDesc; 42 | @property (retain, nonatomic) NSString *m_nsAppExtInfo; 43 | @property (assign, nonatomic) NSUInteger m_uiAppDataSize; 44 | @property (assign, nonatomic) NSUInteger m_uiAppMsgInnerType; 45 | @property (retain, nonatomic) NSString *m_nsShareOpenUrl; 46 | @property (retain, nonatomic) NSString *m_nsShareOriginUrl; 47 | @property (retain, nonatomic) NSString *m_nsJsAppId; 48 | @property (retain, nonatomic) NSString *m_nsPrePublishId; 49 | @property (retain, nonatomic) NSString *m_nsAppID; 50 | @property (retain, nonatomic) NSString *m_nsAppName; 51 | @property (retain, nonatomic) NSString *m_nsThumbUrl; 52 | @property (retain, nonatomic) NSString *m_nsAppMediaUrl; 53 | @property (retain, nonatomic) NSData *m_dtThumbnail; 54 | @property (retain, nonatomic) NSString *m_nsTitle; 55 | @property (retain, nonatomic) NSString *m_nsMsgSource; 56 | 57 | - (id)initWithMsgType:(long long)arg1; 58 | + (_Bool)isSenderFromMsgWrap:(id)arg1; 59 | 60 | @end 61 | 62 | @interface MMServiceCenter : NSObject 63 | 64 | + (instancetype)defaultCenter; 65 | - (id)getService:(Class)service; 66 | 67 | @end 68 | 69 | @interface MMLanguageMgr: NSObject 70 | 71 | - (id)getStringForCurLanguage:(id)arg1 defaultTo:(id)arg2; 72 | 73 | 74 | @end 75 | 76 | #pragma mark - RedEnvelop 77 | 78 | @interface WCRedEnvelopesControlData : NSObject 79 | 80 | @property(retain, nonatomic) CMessageWrap *m_oSelectedMessageWrap; 81 | 82 | @end 83 | 84 | @interface WCRedEnvelopesLogicMgr: NSObject 85 | 86 | - (void)OpenRedEnvelopesRequest:(id)params; 87 | - (void)ReceiverQueryRedEnvelopesRequest:(id)arg1; 88 | - (void)GetHongbaoBusinessRequest:(id)arg1 CMDID:(unsigned int)arg2 OutputType:(unsigned int)arg3; 89 | 90 | /** Added Methods */ 91 | - (unsigned int)calculateDelaySeconds; 92 | 93 | @end 94 | 95 | @interface HongBaoRes : NSObject 96 | 97 | @property(retain, nonatomic) SKBuiltinBuffer_t *retText; // @dynamic retText; 98 | @property(nonatomic) int cgiCmdid; // @dynamic cgiCmdid; 99 | 100 | @end 101 | 102 | @interface HongBaoReq : NSObject 103 | 104 | @property(retain, nonatomic) SKBuiltinBuffer_t *reqText; // @dynamic reqText; 105 | 106 | @end 107 | 108 | #pragma mark - Contact 109 | 110 | @interface CContact: NSObject 111 | 112 | @property(retain, nonatomic) NSString *m_nsUsrName; 113 | @property(retain, nonatomic) NSString *m_nsHeadImgUrl; 114 | @property(retain, nonatomic) NSString *m_nsNickName; 115 | 116 | - (id)getContactDisplayName; 117 | 118 | @end 119 | 120 | @interface CContactMgr : NSObject 121 | 122 | - (id)getSelfContact; 123 | - (id)getContactByName:(id)arg1; 124 | - (id)getContactForSearchByName:(id)arg1; 125 | - (_Bool)getContactsFromServer:(id)arg1; 126 | - (_Bool)isInContactList:(id)arg1; 127 | - (_Bool)addLocalContact:(id)arg1 listType:(unsigned int)arg2; 128 | 129 | @end 130 | 131 | 132 | #pragma mark - QRCode 133 | 134 | @interface ScanQRCodeLogicController: NSObject 135 | 136 | @property(nonatomic) unsigned int fromScene; 137 | - (id)initWithViewController:(id)arg1 CodeType:(int)arg2; 138 | - (void)tryScanOnePicture:(id)arg1; 139 | - (void)doScanQRCode:(id)arg1; 140 | - (void)showScanResult; 141 | 142 | @end 143 | 144 | @interface NewQRCodeScanner: NSObject 145 | 146 | - (id)initWithDelegate:(id)arg1 CodeType:(int)arg2; 147 | - (void)notifyResult:(id)arg1 type:(id)arg2 version:(int)arg3; 148 | 149 | @end 150 | 151 | #pragma mark - MMTableView 152 | 153 | @interface MMTableViewInfo 154 | 155 | - (id)getTableView; 156 | - (void)clearAllSection; 157 | - (void)addSection:(id)arg1; 158 | - (void)insertSection:(id)arg1 At:(unsigned int)arg2; 159 | 160 | @end 161 | 162 | @interface MMTableViewSectionInfo 163 | 164 | + (id)sectionInfoDefaut; 165 | + (id)sectionInfoHeader:(id)arg1; 166 | + (id)sectionInfoHeader:(id)arg1 Footer:(id)arg2; 167 | - (void)addCell:(id)arg1; 168 | 169 | @end 170 | 171 | @interface MMTableViewCellInfo 172 | 173 | + (id)normalCellForSel:(SEL)arg1 target:(id)arg2 title:(id)arg3 accessoryType:(long long)arg4; 174 | + (id)switchCellForSel:(SEL)arg1 target:(id)arg2 title:(id)arg3 on:(_Bool)arg4; 175 | + (id)normalCellForSel:(SEL)arg1 target:(id)arg2 title:(id)arg3 rightValue:(id)arg4 accessoryType:(long long)arg5; 176 | + (id)normalCellForTitle:(id)arg1 rightValue:(id)arg2; 177 | + (id)urlCellForTitle:(id)arg1 url:(id)arg2; 178 | 179 | @end 180 | 181 | @interface MMTableView: UITableView 182 | 183 | @end 184 | 185 | #pragma mark - UI 186 | @interface MMUICommonUtil : NSObject 187 | 188 | + (id)getBarButtonWithTitle:(id)arg1 target:(id)arg2 action:(SEL)arg3 style:(int)arg4; 189 | 190 | @end 191 | 192 | @interface MMLoadingView : UIView 193 | 194 | @property(retain, nonatomic) UILabel *m_label; // @synthesize m_label; 195 | @property (assign, nonatomic) BOOL m_bIgnoringInteractionEventsWhenLoading; // @synthesize m_bIgnoringInteractionEventsWhenLoading; 196 | 197 | - (void)setFitFrame:(long long)arg1; 198 | - (void)startLoading; 199 | - (void)stopLoading; 200 | - (void)stopLoadingAndShowError:(id)arg1; 201 | - (void)stopLoadingAndShowOK:(id)arg1; 202 | 203 | 204 | @end 205 | 206 | @interface MMWebViewController: NSObject 207 | 208 | - (id)initWithURL:(id)arg1 presentModal:(_Bool)arg2 extraInfo:(id)arg3; 209 | 210 | @end 211 | 212 | 213 | @protocol ContactSelectViewDelegate 214 | 215 | - (void)onSelectContact:(CContact *)arg1; 216 | 217 | @end 218 | 219 | @interface ContactSelectView : UIView 220 | 221 | @property(nonatomic) unsigned int m_uiGroupScene; // @synthesize m_uiGroupScene; 222 | @property(nonatomic) _Bool m_bMultiSelect; // @synthesize m_bMultiSelect; 223 | @property(retain, nonatomic) NSMutableDictionary *m_dicMultiSelect; // @synthesize m_dicMultiSelect; 224 | 225 | - (id)initWithFrame:(struct CGRect)arg1 delegate:(id)arg2; 226 | - (void)initData:(unsigned int)arg1; 227 | - (void)initView; 228 | - (void)addSelect:(id)arg1; 229 | 230 | @end 231 | 232 | @interface ContactsDataLogic : NSObject 233 | 234 | @property(nonatomic) unsigned int m_uiScene; // @synthesize m_uiScene; 235 | 236 | @end 237 | 238 | @interface MMUINavigationController : UINavigationController 239 | 240 | @end 241 | 242 | #pragma mark - UtilCategory 243 | 244 | @interface NSMutableDictionary (SafeInsert) 245 | 246 | - (void)safeSetObject:(id)arg1 forKey:(id)arg2; 247 | 248 | @end 249 | 250 | @interface NSDictionary (NSDictionary_SafeJSON) 251 | 252 | - (id)arrayForKey:(id)arg1; 253 | - (id)dictionaryForKey:(id)arg1; 254 | - (double)doubleForKey:(id)arg1; 255 | - (float)floatForKey:(id)arg1; 256 | - (long long)int64ForKey:(id)arg1; 257 | - (long long)integerForKey:(id)arg1; 258 | - (id)stringForKey:(id)arg1; 259 | 260 | @end 261 | 262 | @interface NSString (NSString_SBJSON) 263 | 264 | - (id)JSONArray; 265 | - (id)JSONDictionary; 266 | - (id)JSONValue; 267 | 268 | @end 269 | 270 | #pragma mark - UICategory 271 | 272 | @interface UINavigationController (LogicController) 273 | 274 | - (void)PushViewController:(id)arg1 animated:(_Bool)arg2; 275 | 276 | @end 277 | 278 | @interface MMUIViewController : UIViewController 279 | 280 | - (void)startLoadingBlocked; 281 | - (void)startLoadingNonBlock; 282 | - (void)startLoadingWithText:(NSString *)text; 283 | - (void)stopLoading; 284 | - (void)stopLoadingWithFailText:(NSString *)text; 285 | - (void)stopLoadingWithOKText:(NSString *)text; 286 | 287 | @end 288 | 289 | @interface NewSettingViewController: MMUIViewController 290 | 291 | - (void)reloadTableData; 292 | 293 | @end 294 | 295 | @interface ContactInfoViewController : MMUIViewController 296 | 297 | @property(retain, nonatomic) CContact *m_contact; // @synthesize m_contact; 298 | 299 | @end 300 | 301 | @protocol MultiSelectContactsViewControllerDelegate 302 | - (void)onMultiSelectContactReturn:(NSArray *)arg1; 303 | 304 | @optional 305 | - (int)getFTSCommonScene; 306 | - (void)onMultiSelectContactCancelForSns; 307 | - (void)onMultiSelectContactReturnForSns:(NSArray *)arg1; 308 | @end 309 | 310 | @interface MultiSelectContactsViewController : UIViewController 311 | 312 | @property(nonatomic) _Bool m_bKeepCurViewAfterSelect; // @synthesize m_bKeepCurViewAfterSelect=_m_bKeepCurViewAfterSelect; 313 | @property(nonatomic) unsigned int m_uiGroupScene; // @synthesize m_uiGroupScene; 314 | 315 | @property(nonatomic, weak) id m_delegate; // @synthesize m_delegate; 316 | 317 | @end 318 | 319 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvelopParam.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatRedEnvelopParam.h 3 | // WeChatRedEnvelop 4 | // 5 | // Created by 杨志超 on 2017/1/22. 6 | // Copyright © 2017年 swiftyper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WeChatRedEnvelopParam : NSObject 12 | 13 | - (NSDictionary *)toParams; 14 | 15 | - (instancetype)initWithDictionary:(NSDictionary *)params; 16 | 17 | @property (strong, nonatomic) NSString *msgType; 18 | @property (strong, nonatomic) NSString *sendId; 19 | @property (strong, nonatomic) NSString *channelId; 20 | @property (strong, nonatomic) NSString *nickName; 21 | @property (strong, nonatomic) NSString *headImg; 22 | @property (strong, nonatomic) NSString *nativeUrl; 23 | @property (strong, nonatomic) NSString *sessionUserName; 24 | @property (strong, nonatomic) NSString *sign; 25 | @property (strong, nonatomic) NSString *timingIdentifier; 26 | 27 | @property (assign, nonatomic) BOOL isGroupSender; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvelopParam.m: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatRedEnvelopParam.m 3 | // WeChatRedEnvelop 4 | // 5 | // Created by 杨志超 on 2017/1/22. 6 | // Copyright © 2017年 swiftyper. All rights reserved. 7 | // 8 | 9 | #import "WeChatRedEnvelopParam.h" 10 | 11 | @implementation WeChatRedEnvelopParam 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)params { 14 | self = [super init]; 15 | if (self) { 16 | self.msgType = [params objectForKey:@"msgType"]; 17 | self.sendId = [params objectForKey:@"sendId"]; 18 | self.channelId = [params objectForKey:@"channelId"]; 19 | self.nickName = [params objectForKey:@"nickName"]; 20 | self.headImg = [params objectForKey:@"headImg"]; 21 | self.nativeUrl = [params objectForKey:@"nativeUrl"]; 22 | self.sessionUserName = [params objectForKey:@"sessionUserName"]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (NSDictionary *)toParams { 29 | return @{ 30 | @"msgType": self.msgType, 31 | @"sendId": self.sendId, 32 | @"channelId": self.channelId, 33 | @"nickName": self.nickName, 34 | @"headImg": self.headImg, 35 | @"nativeUrl": self.nativeUrl, 36 | @"sessionUserName": self.sessionUserName, 37 | @"timingIdentifier": self.timingIdentifier 38 | }; 39 | } 40 | 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvlopDylib-Prefix.pch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G5t4r/WeChatRedEnvlop/efc4969a89eece4d0717f3134dbf10d5e02f324f/WeChatRedEnvlopDylib/WeChatRedEnvlopDylib-Prefix.pch -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvlopDylib.h: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // WeChatRedEnvlopDylib.h 5 | // WeChatRedEnvlopDylib 6 | // 7 | // Created by allen on 2017/8/3. 8 | // Copyright (c) 2017年 allen. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | 14 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/WeChatRedEnvlopDylib.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // WeChatRedEnvlopDylib.m 5 | // WeChatRedEnvlopDylib 6 | // 7 | // Created by allen on 2017/8/3. 8 | // Copyright (c) 2017年 allen. All rights reserved. 9 | // 10 | 11 | #import "WeChatRedEnvlopDylib.h" 12 | #import "CaptainHook.h" 13 | #import 14 | #import 15 | #import "WeChatRedEnvelop.h" 16 | #import "WBRedEnvelopParamQueue.h" 17 | #import "WeChatRedEnvelopParam.h" 18 | 19 | void initCycriptServer(){ 20 | [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { 21 | 22 | CYListenServer(6666); 23 | }]; 24 | } 25 | 26 | static __attribute__((constructor)) void entry(){ 27 | NSLog(@"\n 🎉!!!congratulations!!!🎉\n👍----------------insert dylib success----------------👍"); 28 | 29 | initCycriptServer(); 30 | } 31 | 32 | /******************************************微信修改运动步数**********************************************************/ 33 | #define SAVESETTINGS(key, value, fileName) { \ 34 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); \ 35 | NSString *docDir = [paths objectAtIndex:0]; \ 36 | if (!docDir){ return;} \ 37 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; \ 38 | NSString *path = [docDir stringByAppendingPathComponent:fileName]; \ 39 | [dict setObject:value forKey:key]; \ 40 | [dict writeToFile:path atomically:YES]; \ 41 | } 42 | 43 | static int StepCount = 6666; 44 | static NSString *WeRunStepKey = @"WeRunStepKey"; 45 | static NSString *WeRunSettingFile = @"WeRunSettingFile.txt"; 46 | static NSString *HBPluginTypeKey = @"HBPluginType"; 47 | static NSString *HBPluginSettingFile = @"HBPluginSettingFile.txt"; 48 | 49 | //这里只是修改微信运动的步数,步数的设置放在放在抢红包功能(普通消息处理)里面 50 | CHDeclareClass(WCDeviceStepObject) 51 | CHMethod0(unsigned int, WCDeviceStepObject, m7StepCount) { 52 | NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 53 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithContentsOfFile:[docDir stringByAppendingPathComponent:WeRunSettingFile]]; 54 | if (!dic){ return StepCount;} 55 | int value = ((NSNumber *)dic[WeRunStepKey]).intValue; 56 | if (value < 0) { 57 | return CHSuper(0, WCDeviceStepObject, m7StepCount); 58 | } 59 | return value; 60 | } 61 | 62 | CHDeclareClass(WCRedEnvelopesLogicMgr) 63 | 64 | CHOptimizedMethod(2, self, void, WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, HongBaoRes *, arg1, Request, id, arg2) { 65 | CHSuper(2, WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, arg1, Request, arg2); 66 | NSDictionary *responseDict = [[[NSString alloc] initWithData:arg1.retText.buffer encoding:NSUTF8StringEncoding] JSONDictionary]; 67 | if ([responseDict[@"receiveStatus"] integerValue] == 2) { return; } 68 | if ([responseDict[@"hbStatus"] integerValue] == 4) { return; } 69 | if (!responseDict[@"timingIdentifier"]) { return; } 70 | 71 | WeChatRedEnvelopParam *mgrParams = [[WBRedEnvelopParamQueue sharedQueue] dequeue]; 72 | mgrParams.timingIdentifier = responseDict[@"timingIdentifier"]; 73 | WCRedEnvelopesLogicMgr *logicMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("WCRedEnvelopesLogicMgr") class]]; 74 | [logicMgr OpenRedEnvelopesRequest:mgrParams.toParams]; 75 | 76 | } 77 | 78 | 79 | 80 | /******************************************微信自动抢红包**********************************************************/ 81 | static int const kCloseRedEnvPlugin = 0;//关闭红包插件 82 | static int const kOpenRedEnvPlugin = 1;//打开红包插件 83 | static int const kCloseRedEnvPluginForMyself = 2;//不抢自己的红包 84 | static int const kCloseRedEnvPluginForMyselfFromChatroom = 3;//不抢群里自己发的红包 85 | static int HBPluginType = 0; 86 | 87 | CHDeclareClass(CMessageMgr); 88 | 89 | 90 | CHOptimizedMethod(1, self, void, CMessageMgr, onRevokeMsg, CMessageWrap *, arg1){ 91 | 92 | if ([arg1.m_nsContent rangeOfString:@""].location == NSNotFound) { return; } 93 | if ([arg1.m_nsContent rangeOfString:@""].location == NSNotFound) { return; } 94 | 95 | NSString *(^parseSession)() = ^NSString *() { 96 | NSUInteger startIndex = [arg1.m_nsContent rangeOfString:@""].location + @"".length; 97 | NSUInteger endIndex = [arg1.m_nsContent rangeOfString:@""].location; 98 | NSRange range = NSMakeRange(startIndex, endIndex - startIndex); 99 | return [arg1.m_nsContent substringWithRange:range]; 100 | }; 101 | 102 | NSString *(^parseSenderName)() = ^NSString *() { 103 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"" options:NSRegularExpressionCaseInsensitive error:nil]; 104 | 105 | NSRange range = NSMakeRange(0, arg1.m_nsContent.length); 106 | NSTextCheckingResult *result = [regex matchesInString:arg1.m_nsContent options:0 range:range].firstObject; 107 | if (result.numberOfRanges < 2) { return nil; } 108 | 109 | return [arg1.m_nsContent substringWithRange:[result rangeAtIndex:1]]; 110 | }; 111 | 112 | CMessageWrap *msgWrap = [[objc_getClass("CMessageWrap") alloc] initWithMsgType:0x2710]; 113 | BOOL isSender = [objc_getClass("CMessageWrap") isSenderFromMsgWrap:arg1]; 114 | 115 | NSString *sendContent; 116 | if (isSender) { 117 | [msgWrap setM_nsFromUsr:arg1.m_nsToUsr]; 118 | [msgWrap setM_nsToUsr:arg1.m_nsFromUsr]; 119 | sendContent = @"你撤回一条消息"; 120 | } else { 121 | [msgWrap setM_nsToUsr:arg1.m_nsToUsr]; 122 | [msgWrap setM_nsFromUsr:arg1.m_nsFromUsr]; 123 | 124 | NSString *name = parseSenderName(); 125 | sendContent = [NSString stringWithFormat:@"拦截 %@ 的一条撤回消息", name ? name : arg1.m_nsFromUsr]; 126 | } 127 | [msgWrap setM_uiStatus:0x4]; 128 | [msgWrap setM_nsContent:sendContent]; 129 | [msgWrap setM_uiCreateTime:[arg1 m_uiCreateTime]]; 130 | 131 | [self AddLocalMsg:parseSession() MsgWrap:msgWrap fixTime:0x1 NewMsgArriveNotify:0x0]; 132 | } 133 | 134 | 135 | 136 | 137 | CHMethod2(void, CMessageMgr, AsyncOnAddMsg, id, arg1, MsgWrap, CMessageWrap *, arg2) { 138 | CHSuper2(CMessageMgr, AsyncOnAddMsg, arg1, MsgWrap, arg2); 139 | Ivar uiMessageTypeIvar = class_getInstanceVariable(objc_getClass("CMessageWrap"), "m_uiMessageType"); 140 | ptrdiff_t offset = ivar_getOffset(uiMessageTypeIvar); 141 | unsigned char *stuffBytes = (unsigned char *)(__bridge void *)arg2; 142 | NSUInteger m_uiMessageType = * ((NSUInteger *)(stuffBytes + offset)); 143 | 144 | Ivar nsFromUsrIvar = class_getInstanceVariable(objc_getClass("CMessageWrap"), "m_nsFromUsr"); 145 | id m_nsFromUsr = object_getIvar(arg2, nsFromUsrIvar); 146 | 147 | Ivar nsContentIvar = class_getInstanceVariable(objc_getClass("CMessageWrap"), "m_nsContent"); 148 | id m_nsContent = object_getIvar(arg2, nsContentIvar); 149 | 150 | 151 | 152 | NSString *fromUser = arg2.m_nsFromUsr ; 153 | if ([fromUser hasSuffix:@"@chatroom"]) { 154 | NSLog(@"chatroom found"); 155 | NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject; 156 | NSString *plistPath = [path stringByAppendingPathComponent:@"data.plist"]; 157 | NSMutableArray *arrayM = [NSMutableArray array]; 158 | NSArray *storArray = [NSArray arrayWithContentsOfFile:plistPath]; 159 | [arrayM addObjectsFromArray:storArray]; 160 | if (![arrayM containsObject:fromUser]){ 161 | [arrayM addObject:fromUser]; 162 | NSLog(@"存储数据"); 163 | NSLog(@"arrayM ==== %@",arrayM); 164 | [arrayM writeToFile:plistPath atomically:YES]; 165 | } 166 | } 167 | 168 | 169 | 170 | 171 | 172 | 173 | switch(m_uiMessageType) { 174 | case 1://普通消息,打开或者关闭插件功能 175 | { 176 | //微信的服务中心 177 | Method methodMMServiceCenter = class_getClassMethod(objc_getClass("MMServiceCenter"), @selector(defaultCenter)); 178 | IMP impMMSC = method_getImplementation(methodMMServiceCenter); 179 | id MMServiceCenter = impMMSC(objc_getClass("MMServiceCenter"), @selector(defaultCenter)); 180 | //通讯录管理器 181 | id contactManager = ((id (*)(id, SEL, Class))objc_msgSend)(MMServiceCenter, @selector(getService:),objc_getClass("CContactMgr")); 182 | id selfContact = objc_msgSend(contactManager, @selector(getSelfContact)); 183 | 184 | Ivar nsUsrNameIvar = class_getInstanceVariable([selfContact class], "m_nsUsrName"); 185 | id m_nsUsrName = object_getIvar(selfContact, nsUsrNameIvar); 186 | BOOL isMesasgeFromMe = NO; 187 | if ([m_nsFromUsr isEqualToString:m_nsUsrName]) { 188 | //发给自己的消息 189 | isMesasgeFromMe = YES; 190 | } 191 | 192 | if (isMesasgeFromMe) 193 | { 194 | if ([m_nsContent rangeOfString:@"打开红包插件"].location != NSNotFound) 195 | { 196 | HBPluginType = kOpenRedEnvPlugin; 197 | } 198 | else if ([m_nsContent rangeOfString:@"关闭红包插件"].location != NSNotFound) 199 | { 200 | HBPluginType = kCloseRedEnvPlugin; 201 | } 202 | else if ([m_nsContent rangeOfString:@"关闭抢自己红包"].location != NSNotFound) 203 | { 204 | HBPluginType = kCloseRedEnvPluginForMyself; 205 | } 206 | else if ([m_nsContent rangeOfString:@"关闭抢自己群红包"].location != NSNotFound) 207 | { 208 | HBPluginType = kCloseRedEnvPluginForMyselfFromChatroom; 209 | }else if ([m_nsContent rangeOfString:@"修改微信步数#"].location != NSNotFound) 210 | { 211 | NSArray *array = [m_nsContent componentsSeparatedByString:@"#"]; 212 | if (array.count == 2) { 213 | StepCount = ((NSNumber *)array[1]).intValue; 214 | } 215 | } else if([m_nsContent rangeOfString:@"恢复微信步数"].location != NSNotFound) { 216 | StepCount = -1; 217 | } 218 | //保存修改微信步数设置 219 | SAVESETTINGS(WeRunStepKey, [NSNumber numberWithInt:StepCount], WeRunSettingFile) 220 | //保存抢红包设置 221 | SAVESETTINGS(HBPluginTypeKey, [NSNumber numberWithInt:HBPluginType], HBPluginSettingFile); 222 | } 223 | } 224 | break; 225 | case 49://红包消息 226 | { 227 | NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 228 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:[docDir stringByAppendingPathComponent:HBPluginSettingFile]]; 229 | if (dict){ 230 | HBPluginType = ((NSNumber *)dict[HBPluginTypeKey]).intValue; 231 | } 232 | //微信的服务中心 233 | Method methodMMServiceCenter = class_getClassMethod(objc_getClass("MMServiceCenter"), @selector(defaultCenter)); 234 | IMP impMMSC = method_getImplementation(methodMMServiceCenter); 235 | id MMServiceCenter = impMMSC(objc_getClass("MMServiceCenter"), @selector(defaultCenter)); 236 | //红包控制器 237 | id logicMgr = ((id (*)(id, SEL, Class))objc_msgSend)(MMServiceCenter, @selector(getService:),objc_getClass("WCRedEnvelopesLogicMgr")); 238 | //通讯录管理器 239 | id contactManager = ((id (*)(id, SEL, Class))objc_msgSend)(MMServiceCenter, @selector(getService:),objc_getClass("CContactMgr")); 240 | 241 | Method methodGetSelfContact = class_getInstanceMethod(objc_getClass("CContactMgr"), @selector(getSelfContact)); 242 | IMP impGS = method_getImplementation(methodGetSelfContact); 243 | id selfContact = impGS(contactManager, @selector(getSelfContact)); 244 | 245 | Ivar nsUsrNameIvar = class_getInstanceVariable([selfContact class], "m_nsUsrName"); 246 | id m_nsUsrName = object_getIvar(selfContact, nsUsrNameIvar); 247 | BOOL isMesasgeFromMe = NO; 248 | BOOL isChatroom = NO; 249 | if ([m_nsFromUsr isEqualToString:m_nsUsrName]) { 250 | isMesasgeFromMe = YES; 251 | } 252 | if ([m_nsFromUsr rangeOfString:@"@chatroom"].location != NSNotFound) 253 | { 254 | isChatroom = YES; 255 | } 256 | if (isMesasgeFromMe && kCloseRedEnvPluginForMyself == HBPluginType && !isChatroom) { 257 | //不抢自己的红包 258 | break; 259 | } 260 | else if(isMesasgeFromMe && kCloseRedEnvPluginForMyselfFromChatroom == HBPluginType && isChatroom) 261 | { 262 | //不抢群里自己的红包 263 | break; 264 | } 265 | 266 | if ([m_nsContent rangeOfString:@"wxpay://"].location != NSNotFound) 267 | { 268 | NSString *nativeUrl = m_nsContent; 269 | NSRange rangeStart = [m_nsContent rangeOfString:@"wxpay://c2cbizmessagehandler/hongbao"]; 270 | if (rangeStart.location != NSNotFound) 271 | { 272 | NSUInteger locationStart = rangeStart.location; 273 | nativeUrl = [nativeUrl substringFromIndex:locationStart]; 274 | } 275 | 276 | NSRange rangeEnd = [nativeUrl rangeOfString:@"]]"]; 277 | if (rangeEnd.location != NSNotFound) 278 | { 279 | NSUInteger locationEnd = rangeEnd.location; 280 | nativeUrl = [nativeUrl substringToIndex:locationEnd]; 281 | } 282 | 283 | NSString *naUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]]; 284 | 285 | NSArray *parameterPairs =[naUrl componentsSeparatedByString:@"&"]; 286 | 287 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:[parameterPairs count]]; 288 | for (NSString *currentPair in parameterPairs) { 289 | NSRange range = [currentPair rangeOfString:@"="]; 290 | if(range.location == NSNotFound) 291 | continue; 292 | NSString *key = [currentPair substringToIndex:range.location]; 293 | NSString *value =[currentPair substringFromIndex:range.location + 1]; 294 | [parameters setObject:value forKey:key]; 295 | } 296 | 297 | //红包参数 298 | NSMutableDictionary *params = [@{} mutableCopy]; 299 | 300 | [params setObject:parameters[@"msgtype"]?:@"null" forKey:@"msgType"]; 301 | [params setObject:parameters[@"sendid"]?:@"null" forKey:@"sendId"]; 302 | [params setObject:parameters[@"channelid"]?:@"null" forKey:@"channelId"]; 303 | 304 | id getContactDisplayName = objc_msgSend(selfContact, @selector(getContactDisplayName)); 305 | id m_nsHeadImgUrl = objc_msgSend(selfContact, @selector(m_nsHeadImgUrl)); 306 | 307 | [params setObject:getContactDisplayName forKey:@"nickName"]; 308 | [params setObject:m_nsHeadImgUrl forKey:@"headImg"]; 309 | [params setObject:[NSString stringWithFormat:@"%@", nativeUrl]?:@"null" forKey:@"nativeUrl"]; 310 | [params setObject:m_nsFromUsr?:@"null" forKey:@"sessionUserName"]; 311 | 312 | 313 | WeChatRedEnvelopParam *mgrParams = [[WeChatRedEnvelopParam alloc] initWithDictionary:params]; 314 | [[WBRedEnvelopParamQueue sharedQueue] enqueue:mgrParams]; 315 | 316 | 317 | if (kCloseRedEnvPlugin != HBPluginType) { 318 | 319 | //自动抢红包 320 | WCRedEnvelopesLogicMgr *logicMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("WCRedEnvelopesLogicMgr") class]]; 321 | [logicMgr ReceiverQueryRedEnvelopesRequest:params]; 322 | 323 | 324 | } 325 | return; 326 | } 327 | 328 | break; 329 | } 330 | default: 331 | break; 332 | } 333 | } 334 | 335 | CHOptimizedMethod(2, self, void, CMessageMgr, AddMsg, id, arg1, MsgWrap, CMessageWrap *, wrap){ 336 | int type = wrap.m_uiMessageType; 337 | NSString *knFromUser = wrap.m_nsFromUsr; 338 | NSString *knToUsr = wrap.m_nsToUsr; 339 | NSString *knContent = wrap.m_nsContent; 340 | NSString *knSource = wrap.m_nsMsgSource; 341 | CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]]; 342 | CContact *selfContact = [contactManager getSelfContact]; 343 | if (type == 1){ 344 | if ([knFromUser isEqualToString:selfContact.m_nsUsrName]) { 345 | if ([knToUsr hasSuffix:@"@chatroom"]) { 346 | NSLog(@"selfContact ==== %@",selfContact); 347 | if( knSource == nil){ 348 | NSString *aaa = [selfContact.m_nsUsrName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"length=%lu,%@",(unsigned long)aaa.length,aaa); 349 | NSArray *result = (NSArray *)[objc_getClass("CContact") getChatRoomMemberWithoutMyself:knToUsr]; 350 | if ([knContent hasPrefix:@"#所有人"]){ 351 | // 前缀要求 352 | NSString *subStr = [knContent substringFromIndex:4]; 353 | NSMutableString *string = [NSMutableString string]; 354 | [result enumerateObjectsUsingBlock:^(CContact *obj, NSUInteger idx, BOOL * _Nonnull stop) { 355 | [string appendFormat:@",%@",obj.m_nsUsrName]; 356 | }]; 357 | NSString *sourceString = [string substringFromIndex:1]; 358 | wrap.m_uiStatus = 3; 359 | wrap.m_nsContent = subStr; 360 | wrap.m_nsMsgSource = [NSString stringWithFormat:@"%@",sourceString]; 361 | } 362 | } 363 | } 364 | } 365 | } 366 | CHSuper(2, CMessageMgr,AddMsg,arg1,MsgWrap,wrap); 367 | } 368 | 369 | 370 | 371 | //所有被hook的类和函数放在这里的构造函数中 372 | CHConstructor 373 | { 374 | @autoreleasepool 375 | { 376 | CHLoadLateClass(WCDeviceStepObject); 377 | CHHook0(WCDeviceStepObject, m7StepCount); 378 | 379 | CHLoadLateClass(CMessageMgr); 380 | CHHook2(CMessageMgr, AsyncOnAddMsg, MsgWrap); 381 | CHHook(1, CMessageMgr, onRevokeMsg); 382 | CHHook(2, CMessageMgr, AddMsg, MsgWrap); 383 | 384 | CHLoadLateClass(WCRedEnvelopesLogicMgr); 385 | CHHook(2, WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, Request); 386 | 387 | } 388 | } 389 | 390 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/fishhook/fishhook.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #import "fishhook.h" 25 | 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | 34 | #ifdef __LP64__ 35 | typedef struct mach_header_64 mach_header_t; 36 | typedef struct segment_command_64 segment_command_t; 37 | typedef struct section_64 section_t; 38 | typedef struct nlist_64 nlist_t; 39 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 40 | #else 41 | typedef struct mach_header mach_header_t; 42 | typedef struct segment_command segment_command_t; 43 | typedef struct section section_t; 44 | typedef struct nlist nlist_t; 45 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 46 | #endif 47 | 48 | #ifndef SEG_DATA_CONST 49 | #define SEG_DATA_CONST "__DATA_CONST" 50 | #endif 51 | 52 | struct rebindings_entry { 53 | struct rebinding *rebindings; 54 | size_t rebindings_nel; 55 | struct rebindings_entry *next; 56 | }; 57 | 58 | static struct rebindings_entry *_rebindings_head; 59 | 60 | static int prepend_rebindings(struct rebindings_entry **rebindings_head, 61 | struct rebinding rebindings[], 62 | size_t nel) { 63 | struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); 64 | if (!new_entry) { 65 | return -1; 66 | } 67 | new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); 68 | if (!new_entry->rebindings) { 69 | free(new_entry); 70 | return -1; 71 | } 72 | memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); 73 | new_entry->rebindings_nel = nel; 74 | new_entry->next = *rebindings_head; 75 | *rebindings_head = new_entry; 76 | return 0; 77 | } 78 | 79 | static void perform_rebinding_with_section(struct rebindings_entry *rebindings, 80 | section_t *section, 81 | intptr_t slide, 82 | nlist_t *symtab, 83 | char *strtab, 84 | uint32_t *indirect_symtab) { 85 | uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; 86 | void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); 87 | for (uint i = 0; i < section->size / sizeof(void *); i++) { 88 | uint32_t symtab_index = indirect_symbol_indices[i]; 89 | if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || 90 | symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { 91 | continue; 92 | } 93 | uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; 94 | char *symbol_name = strtab + strtab_offset; 95 | if (strnlen(symbol_name, 2) < 2) { 96 | continue; 97 | } 98 | struct rebindings_entry *cur = rebindings; 99 | while (cur) { 100 | for (uint j = 0; j < cur->rebindings_nel; j++) { 101 | if (strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { 102 | if (cur->rebindings[j].replaced != NULL && 103 | indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { 104 | *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; 105 | } 106 | indirect_symbol_bindings[i] = cur->rebindings[j].replacement; 107 | goto symbol_loop; 108 | } 109 | } 110 | cur = cur->next; 111 | } 112 | symbol_loop:; 113 | } 114 | } 115 | 116 | static void rebind_symbols_for_image(struct rebindings_entry *rebindings, 117 | const struct mach_header *header, 118 | intptr_t slide) { 119 | Dl_info info; 120 | if (dladdr(header, &info) == 0) { 121 | return; 122 | } 123 | 124 | segment_command_t *cur_seg_cmd; 125 | segment_command_t *linkedit_segment = NULL; 126 | struct symtab_command* symtab_cmd = NULL; 127 | struct dysymtab_command* dysymtab_cmd = NULL; 128 | 129 | uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); 130 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 131 | cur_seg_cmd = (segment_command_t *)cur; 132 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 133 | if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { 134 | linkedit_segment = cur_seg_cmd; 135 | } 136 | } else if (cur_seg_cmd->cmd == LC_SYMTAB) { 137 | symtab_cmd = (struct symtab_command*)cur_seg_cmd; 138 | } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { 139 | dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; 140 | } 141 | } 142 | 143 | if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || 144 | !dysymtab_cmd->nindirectsyms) { 145 | return; 146 | } 147 | 148 | // Find base symbol/string table addresses 149 | uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; 150 | nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); 151 | char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); 152 | 153 | // Get indirect symbol table (array of uint32_t indices into symbol table) 154 | uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); 155 | 156 | cur = (uintptr_t)header + sizeof(mach_header_t); 157 | for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { 158 | cur_seg_cmd = (segment_command_t *)cur; 159 | if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 160 | if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && 161 | strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { 162 | continue; 163 | } 164 | for (uint j = 0; j < cur_seg_cmd->nsects; j++) { 165 | section_t *sect = 166 | (section_t *)(cur + sizeof(segment_command_t)) + j; 167 | if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { 168 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 169 | } 170 | if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { 171 | perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab); 172 | } 173 | } 174 | } 175 | } 176 | } 177 | 178 | static void _rebind_symbols_for_image(const struct mach_header *header, 179 | intptr_t slide) { 180 | rebind_symbols_for_image(_rebindings_head, header, slide); 181 | } 182 | 183 | int rebind_symbols_image(void *header, 184 | intptr_t slide, 185 | struct rebinding rebindings[], 186 | size_t rebindings_nel) { 187 | struct rebindings_entry *rebindings_head = NULL; 188 | int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); 189 | rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); 190 | free(rebindings_head); 191 | return retval; 192 | } 193 | 194 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { 195 | int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel); 196 | if (retval < 0) { 197 | return retval; 198 | } 199 | // If this was the first call, register callback for image additions (which is also invoked for 200 | // existing images, otherwise, just run on existing images 201 | if (!_rebindings_head->next) { 202 | _dyld_register_func_for_add_image(_rebind_symbols_for_image); 203 | } else { 204 | uint32_t c = _dyld_image_count(); 205 | for (uint32_t i = 0; i < c; i++) { 206 | _rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); 207 | } 208 | } 209 | return retval; 210 | } 211 | -------------------------------------------------------------------------------- /WeChatRedEnvlopDylib/fishhook/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | --------------------------------------------------------------------------------