├── .gitignore
├── ELWeChat
├── ELWeChat.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── cuishengyu.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── cuishengyu.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── ELWeChat.xcscheme
│ │ └── xcschememanagement.plist
├── ELWeChat.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── cuishengyu.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
├── ELWeChat
│ ├── Config
│ │ └── MDConfig.plist
│ ├── Info.plist
│ ├── Main
│ │ ├── ELSettingViewController
│ │ │ ├── ELSettingViewController.h
│ │ │ ├── ELSettingViewController.m
│ │ │ ├── WBMultiSelectGroupsViewController.h
│ │ │ └── WBMultiSelectGroupsViewController.m
│ │ ├── ELWeChatConfig
│ │ │ ├── ELAppManage.h
│ │ │ ├── ELAppManage.m
│ │ │ ├── ELRedEnvelopInfo.h
│ │ │ ├── ELRedEnvelopInfo.m
│ │ │ ├── ELWeChatConfig.h
│ │ │ └── ELWeChatConfig.m
│ │ └── ELWeChatHeaderinfo
│ │ │ └── ELWeChatHeaderinfo.h
│ ├── Scripts
│ │ └── quick-resign.sh
│ ├── Target.plist
│ ├── TargetApp
│ │ └── put ipa or app here
│ └── icon.png
├── ELWeChatDylib
│ ├── AntiAntiDebug
│ │ └── AntiAntiDebug.m
│ ├── Config
│ │ ├── ANYMethodLog.h
│ │ ├── ANYMethodLog.m
│ │ ├── MDConfigManager.h
│ │ ├── MDConfigManager.m
│ │ ├── MDCycriptManager.h
│ │ ├── MDCycriptManager.m
│ │ ├── MDMethodTrace.h
│ │ └── MDMethodTrace.m
│ ├── ELWeChatDylib-Prefix.pch
│ ├── ELWeChatDylib.h
│ ├── ELWeChatDylib.m
│ ├── Logos
│ │ ├── ELWeChatDylib.mm
│ │ └── ELWeChatDylib.xm
│ ├── Tools
│ │ ├── LLDBTools.h
│ │ └── LLDBTools.mm
│ └── fishhook
│ │ ├── fishhook.c
│ │ └── fishhook.h
├── LatestBuild
├── MUHook
│ ├── MUHRuntime.h
│ ├── MUHook.h
│ ├── MUHook.m
│ ├── NSObject+MUHook.h
│ └── NSObject+MUHook.m
├── Podfile
├── Podfile.lock
└── Pods
│ ├── CYMHUD
│ ├── CYMHUD
│ │ └── Classes
│ │ │ └── HUD
│ │ │ ├── HUD.h
│ │ │ └── HUD.m
│ ├── LICENSE
│ └── README.md
│ ├── MBProgressHUD
│ ├── LICENSE
│ ├── MBProgressHUD.h
│ ├── MBProgressHUD.m
│ └── README.mdown
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ ├── project.pbxproj
│ └── xcuserdata
│ │ └── cuishengyu.xcuserdatad
│ │ └── xcschemes
│ │ ├── CYMHUD.xcscheme
│ │ ├── MBProgressHUD.xcscheme
│ │ ├── Pods-ELWeChatDylib.xcscheme
│ │ ├── YYModel.xcscheme
│ │ └── xcschememanagement.plist
│ ├── Target Support Files
│ ├── CYMHUD
│ │ ├── CYMHUD-Info.plist
│ │ ├── CYMHUD-dummy.m
│ │ ├── CYMHUD-prefix.pch
│ │ ├── CYMHUD-umbrella.h
│ │ ├── CYMHUD.modulemap
│ │ └── CYMHUD.xcconfig
│ ├── MBProgressHUD
│ │ ├── MBProgressHUD-Info.plist
│ │ ├── MBProgressHUD-dummy.m
│ │ ├── MBProgressHUD-prefix.pch
│ │ ├── MBProgressHUD-umbrella.h
│ │ ├── MBProgressHUD.modulemap
│ │ └── MBProgressHUD.xcconfig
│ ├── Pods-ELWeChatDylib
│ │ ├── Pods-ELWeChatDylib-Info.plist
│ │ ├── Pods-ELWeChatDylib-acknowledgements.markdown
│ │ ├── Pods-ELWeChatDylib-acknowledgements.plist
│ │ ├── Pods-ELWeChatDylib-dummy.m
│ │ ├── Pods-ELWeChatDylib-frameworks.sh
│ │ ├── Pods-ELWeChatDylib-umbrella.h
│ │ ├── Pods-ELWeChatDylib.debug.xcconfig
│ │ ├── Pods-ELWeChatDylib.modulemap
│ │ └── Pods-ELWeChatDylib.release.xcconfig
│ └── YYModel
│ │ ├── YYModel-Info.plist
│ │ ├── YYModel-dummy.m
│ │ ├── YYModel-prefix.pch
│ │ ├── YYModel-umbrella.h
│ │ ├── YYModel.modulemap
│ │ └── YYModel.xcconfig
│ └── YYModel
│ ├── LICENSE
│ ├── README.md
│ └── YYModel
│ ├── NSObject+YYModel.h
│ ├── NSObject+YYModel.m
│ ├── YYClassInfo.h
│ ├── YYClassInfo.m
│ └── YYModel.h
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Other
10 | *.moved-aside
11 | *.xccheckout
12 | *.xcscmblueprint
13 |
14 | ## Obj-C/Swift specific
15 | *.hmap
16 | *.ipa
17 | *.dSYM.zip
18 | *.dSYM
19 | *.app
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/project.xcworkspace/xcuserdata/cuishengyu.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuiyu8580/ELWeChat/376e57ee92ec4744faa85825ed6712ee3bfabc6b/ELWeChat/ELWeChat.xcodeproj/project.xcworkspace/xcuserdata/cuishengyu.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/ELWeChat.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 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ELWeChat.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | ELWeChatDylib.xcscheme
13 |
14 | orderHint
15 | 5
16 |
17 | ELWeChatDylib.xcscheme_^#shared#^_
18 |
19 | orderHint
20 | 5
21 |
22 |
23 | SuppressBuildableAutocreation
24 |
25 | 3816BA94216C9E9B00030C99
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcworkspace/xcuserdata/cuishengyu.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuiyu8580/ELWeChat/376e57ee92ec4744faa85825ed6712ee3bfabc6b/ELWeChat/ELWeChat.xcworkspace/xcuserdata/cuishengyu.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat.xcworkspace/xcuserdata/cuishengyu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Config/MDConfig.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | MethodTrace
6 |
7 | ENABLE
8 |
9 | CLASS_LIST
10 |
11 | AddFriendEntryViewController
12 |
13 | CSearchedContact
14 |
15 | FindContactSearchViewCellInfo
16 |
17 | SearchContactDataProvider
18 |
19 | CContactVerifyLogic
20 |
21 | ContactInfoViewController
22 |
23 | SendVerifyMsgViewController
24 |
25 | CBaseContactInfoAssist
26 |
27 | ContactInfoAssistDelegate
28 |
29 |
30 |
31 | Cycript
32 |
33 | nslog
34 |
35 | LoadAtLaunch
36 |
37 | priority
38 | 0
39 | content
40 | NSLog = function() { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(dlsym(RTLD_DEFAULT, "NSLog"), types).apply(null, args); }
41 |
42 | ms
43 |
44 | LoadAtLaunch
45 |
46 | priority
47 | 1
48 | url
49 | https://raw.githubusercontent.com/AloneMonkey/MDCycript/master/MS.cy
50 |
51 | hook
52 |
53 | LoadAtLaunch
54 |
55 | priority
56 | 2
57 | content
58 | try{
59 | var oldm = {};
60 | HookMessage(CustomViewController, @selector(showChangeLog:), function(log) {
61 | NSLog("hooked by cycript!!!");
62 | return oldm->call(this,log);
63 | }, oldm);
64 | }catch(err){
65 | NSLog(err.toString())
66 | }
67 |
68 | md
69 |
70 | LoadAtLaunch
71 |
72 | priority
73 | 3
74 | url
75 | https://raw.githubusercontent.com/AloneMonkey/MDCycript/master/md.cy
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 17C2120
7 | CFBundleDevelopmentRegion
8 | zh_CN
9 | CFBundleDisplayName
10 | 微信
11 | CFBundleDocumentTypes
12 |
13 |
14 | CFBundleTypeName
15 | officeopenxml
16 | LSHandlerRank
17 | Owner
18 | LSItemContentTypes
19 |
20 | org.openxmlformats.openxml
21 |
22 |
23 |
24 | CFBundleTypeName
25 | data
26 | LSHandlerRank
27 | Owner
28 | LSItemContentTypes
29 |
30 | public.data
31 |
32 |
33 |
34 | CFBundleTypeName
35 | ppt
36 | LSHandlerRank
37 | Owner
38 | LSItemContentTypes
39 |
40 | com.microsoft.powerpoint.ppt
41 |
42 |
43 |
44 | CFBundleTypeName
45 | doc
46 | LSHandlerRank
47 | Owner
48 | LSItemContentTypes
49 |
50 | com.microsoft.word.doc
51 |
52 |
53 |
54 | CFBundleTypeName
55 | xls
56 | LSHandlerRank
57 | Owner
58 | LSItemContentTypes
59 |
60 | com.microsoft.excel.xls
61 |
62 |
63 |
64 | CFBundleTypeName
65 | pdf
66 | LSHandlerRank
67 | Owner
68 | LSItemContentTypes
69 |
70 | com.adobe.pdf
71 |
72 |
73 |
74 | CFBundleTypeName
75 | archive
76 | LSHandlerRank
77 | Owner
78 | LSItemContentTypes
79 |
80 | org.gnu.gnu-tar-archive
81 |
82 |
83 |
84 | CFBundleTypeName
85 | audivideo
86 | LSHandlerRank
87 | Owner
88 | LSItemContentTypes
89 |
90 | public.audiovisual-content
91 |
92 |
93 |
94 | CFBundleTypeName
95 | image
96 | LSHandlerRank
97 | Owner
98 | LSItemContentTypes
99 |
100 | public.image
101 |
102 |
103 |
104 | CFBundleTypeName
105 | txt
106 | LSHandlerRank
107 | Owner
108 | LSItemContentTypes
109 |
110 | public.text
111 |
112 |
113 |
114 | CFBundleExecutable
115 | WeChat
116 | CFBundleIconFiles
117 |
118 | ELWeChat/icon.png
119 |
120 | CFBundleIcons
121 |
122 | CFBundlePrimaryIcon
123 |
124 | CFBundleIconFiles
125 |
126 | AppIcon60x60
127 |
128 | CFBundleIconName
129 | AppIcon
130 |
131 |
132 | CFBundleIcons~ipad
133 |
134 | CFBundlePrimaryIcon
135 |
136 | CFBundleIconFiles
137 |
138 | AppIcon60x60
139 | AppIcon76x76
140 | AppIcon83.5x83.5
141 |
142 | CFBundleIconName
143 | AppIcon
144 |
145 |
146 | CFBundleIdentifier
147 | com.eli.ELWeChat
148 | CFBundleInfoDictionaryVersion
149 | 6.0
150 | CFBundleName
151 | WeChat
152 | CFBundlePackageType
153 | APPL
154 | CFBundleShortVersionString
155 | 6.7.3
156 | CFBundleSignature
157 | ????
158 | CFBundleSupportedPlatforms
159 |
160 | iPhoneOS
161 |
162 | CFBundleURLTypes
163 |
164 |
165 | CFBundleTypeRole
166 | Editor
167 | CFBundleURLName
168 | com.tencent.xin
169 | CFBundleURLSchemes
170 |
171 | wexinVideoAPI
172 | weixin
173 | weixinapp
174 | fb290293790992170
175 | wechat
176 | QQ41C152CF
177 | prefs
178 |
179 |
180 |
181 | CFBundleVersion
182 | 6.7.3.33
183 | DTAppStoreToolsBuild
184 | 10A247
185 | DTCompiler
186 | com.apple.compilers.llvm.clang.1_0
187 | DTPlatformBuild
188 | 15F79
189 | DTPlatformName
190 | iphoneos
191 | DTPlatformVersion
192 | 11.4
193 | DTSDKBuild
194 | 15F79
195 | DTSDKName
196 | iphoneos11.4
197 | DTXcode
198 | 0940
199 | DTXcodeBuild
200 | 9F1027a
201 | FacebookAppID
202 | 290293790992170
203 | LSApplicationQueriesSchemes
204 |
205 | qqnews
206 | weixinbeta
207 | qqnewshd
208 | qqmail
209 | whatsapp
210 | wxwork
211 | wxworklocal
212 | wxcphonebook
213 | mttbrowser
214 | mqqapi
215 | mqzonev2
216 | qqmusic
217 | tenvideo2
218 | tenvideohd
219 | qnreading
220 | weread
221 | sosomap
222 | comgooglemaps
223 | iosamap
224 | baidumap
225 | sgmap
226 | fbauth
227 | wx76fc280041c16519
228 | wx3bef52104e238bff
229 | wx369f9a611589ad83
230 | wx95a3a4d7c627e07d
231 | wx44b60f3ea0534cd7
232 | wxacbfe7e1bb3e800f
233 | wxfdab5af74990787a
234 | wx58164a91f1821369
235 | wxd477edab60670232
236 | wx82dd7436af5db835
237 | qqstock
238 | openApp.jdMobile
239 | openapp.toplife
240 | qmkege
241 | mqzonex
242 | txvp
243 | sybapp
244 | wx5a4a8ac0fd48303a
245 | qqsports
246 | qqcar
247 | tencentedu
248 | wemusic
249 | qqmap
250 | mqq
251 | webank
252 | weiyun
253 | weishi
254 |
255 | LSRequiresIPhoneOS
256 |
257 | MinimumOSVersion
258 | 8.0
259 | NSAppTransportSecurity
260 |
261 | NSAllowsArbitraryLoads
262 |
263 |
264 | NSBluetoothPeripheralUsageDescription
265 | Allow WeChat Use Bluetooth Peripheral.
266 | NSCameraUsageDescription
267 | Use your Camera to record video, using VoIP features.
268 | NSContactsUsageDescription
269 | Allow WeChat Use your Contact.
270 | NSFaceIDUsageDescription
271 | Allow WeChat Use FaceID.
272 | NSHealthShareUsageDescription
273 | Allow WeChat Use Health Share.
274 | NSHealthUpdateUsageDescription
275 | Allow WeChat Use Health Update.
276 | NSLocationAlwaysUsageDescription
277 | Allow WeChat Use your Location always.
278 | NSLocationUsageDescription
279 | Allow WeChat Use your Location.
280 | NSLocationWhenInUseUsageDescription
281 | Allow WeChat Use your Location when in use.
282 | NSMicrophoneUsageDescription
283 | Use your Microphone to record voice messages, using VoIP features.
284 | NSMotionUsageDescription
285 | Allow WeChat Use Motion.
286 | NSPhotoLibraryAddUsageDescription
287 | Allow WeChat Save Photo.
288 | NSPhotoLibraryUsageDescription
289 | Allow WeChat Use your PhotoLibrary.
290 | NSSiriUsageDescription
291 | Allow WeChat Use Siri.
292 | NSUserActivityTypes
293 |
294 | com.tencent.xin
295 | com.tencent.xin.watch
296 |
297 | UIAppFonts
298 |
299 | WeChatSansStd-Bold.ttf
300 | WeChatSansStd-Medium.ttf
301 | WeChatSansStd-Regular.ttf
302 | WeChatSansSuperscript-Bold.ttf
303 | WeChatSansSuperscript-Regular.ttf
304 | WeChatSansSuperscript-Medium.ttf
305 |
306 | UIBackgroundModes
307 |
308 | location
309 | audio
310 | fetch
311 | voip
312 | remote-notification
313 | network-authentication
314 |
315 | UIDeviceFamily
316 |
317 | 1
318 | 2
319 |
320 | UILaunchStoryboardName
321 | Launch Screen
322 | UIPrerenderedIcon
323 |
324 | UIStatusBarHidden
325 |
326 | UIStatusBarStyle
327 | UIStatusBarStyleBlackOpaque
328 | UISupportedInterfaceOrientations
329 |
330 | UIInterfaceOrientationPortrait
331 | UIInterfaceOrientationLandscapeLeft
332 | UIInterfaceOrientationLandscapeRight
333 |
334 | UISupportedInterfaceOrientations~ipad
335 |
336 | UIInterfaceOrientationPortrait
337 | UIInterfaceOrientationLandscapeLeft
338 | UIInterfaceOrientationLandscapeRight
339 | UIInterfaceOrientationPortraitUpsideDown
340 |
341 | UIViewControllerBasedStatusBarAppearance
342 |
343 | WeChatBundleVersion
344 | 6.7.3.33
345 |
346 |
347 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELSettingViewController/ELSettingViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ELSettingViewController.h
3 | // ELWeChat
4 | //
5 | // Created by Eli on 2018/10/9.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ELSettingViewController : UIViewController
12 |
13 |
14 |
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELSettingViewController/ELSettingViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ELSettingViewController.m
3 | // ELWeChat
4 | //
5 | // Created by Eli on 2018/10/9.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import "ELSettingViewController.h"
10 | #import
11 | #import "ELWeChatConfig.h"
12 | #import "ELWeChatHeaderinfo.h"
13 | #import "WBMultiSelectGroupsViewController.h"
14 |
15 | @interface ELSettingViewController ()
16 |
17 | @property (nonatomic, strong) MMTableViewInfo *tableViewInfo;
18 |
19 | @end
20 |
21 | @implementation ELSettingViewController
22 |
23 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
24 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
25 | _tableViewInfo = [[objc_getClass("MMTableViewInfo") alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStyleGrouped];
26 | }
27 | return self;
28 | }
29 |
30 |
31 | - (void)viewDidLoad {
32 | [super viewDidLoad];
33 | // Do any additional setup after loading the view.
34 |
35 |
36 | self.title = @"微信助手";
37 |
38 | [self reloadTableViewData];
39 |
40 | MMTableView *tableView = [self.tableViewInfo getTableView];
41 | [self.view addSubview:tableView];
42 | }
43 |
44 | - (void)reloadTableViewData
45 | {
46 | [self.tableViewInfo clearAllSection];
47 |
48 | [self addRedEnvelopSection];
49 |
50 | [self addGroupManageSection];
51 |
52 | [self addMessageSection];
53 |
54 | [self addStepSection];
55 |
56 | self.edgesForExtendedLayout = UIRectEdgeNone;
57 |
58 | MMTableView *tableView = [self.tableViewInfo getTableView];
59 | [tableView reloadData];
60 |
61 | }
62 |
63 |
64 |
65 |
66 | - (void)addStepSection
67 | {
68 |
69 | MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut];
70 |
71 | [sectionInfo addCell:[self addStepSectionCell]];
72 |
73 | if ([ELAppManage sharedManage].appConfig.StepManage)
74 | {
75 | [sectionInfo addCell:[self addStepNumberSectionCell]];
76 | }
77 |
78 |
79 | [self.tableViewInfo addSection:sectionInfo];
80 |
81 | }
82 |
83 |
84 | - (MMTableViewCellInfo *)addStepSectionCell
85 | {
86 |
87 | return [objc_getClass("MMTableViewCellInfo") switchCellForSel:@selector(SetpClick:) target:self title:@"修改步数" on:[ELAppManage sharedManage].appConfig.StepManage];
88 |
89 | }
90 |
91 | - (void)SetpClick:(UISwitch *)setpSwitch
92 | {
93 | [ELAppManage sharedManage].appConfig.StepManage = setpSwitch.on;
94 |
95 | [self reloadTableViewData];
96 | }
97 |
98 |
99 |
100 | - (MMTableViewCellInfo *)addStepNumberSectionCell
101 | {
102 |
103 |
104 | WCDeviceBrandMgr *BrandMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("WCDeviceBrandMgr")];
105 |
106 |
107 | NSInteger LastSetp = [BrandMgr getLastM7Step];
108 |
109 | NSInteger curSetp = LastSetp > [ELAppManage sharedManage].appConfig.ResetStepNum ? LastSetp : [ELAppManage sharedManage].appConfig.ResetStepNum;
110 |
111 |
112 | return [objc_getClass("MMTableViewCellInfo") normalCellForSel:@selector(setStepNumber) target:self title:@"微信运动步数" rightValue:[NSString stringWithFormat:@"%ld",(long)curSetp] accessoryType:1];
113 |
114 | }
115 |
116 |
117 | - (void)addRedEnvelopSection
118 | {
119 | MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut];
120 |
121 | [sectionInfo addCell:[self addRedEnvelopSectionCell]];
122 |
123 | if ([ELAppManage sharedManage].appConfig.autoRedEnvelop)
124 | {
125 | [sectionInfo addCell:[self addBlackListCell]];
126 | }
127 |
128 | [self.tableViewInfo addSection:sectionInfo];
129 |
130 | }
131 |
132 |
133 | - (MMTableViewCellInfo *)addRedEnvelopSectionCell
134 | {
135 |
136 | return [objc_getClass("MMTableViewCellInfo") switchCellForSel:@selector(RedEnvelopClick:) target:self title:@"自动抢红包" on:[ELAppManage sharedManage].appConfig.autoRedEnvelop];
137 |
138 | }
139 |
140 | - (MMTableViewCellInfo *)addBlackListCell
141 | {
142 |
143 | if ([ELAppManage sharedManage].appConfig.blackList.count == 0) {
144 | return [objc_getClass("MMTableViewCellInfo") normalCellForSel:@selector(showBlackList) target:self title:@"群聊过滤" rightValue:@"已关闭" accessoryType:1];
145 | } else {
146 | NSString *blackListCountStr = [NSString stringWithFormat:@"已选择 %lu 个群", (unsigned long)[ELAppManage sharedManage].appConfig.blackList.count];
147 | return [objc_getClass("MMTableViewCellInfo") normalCellForSel:@selector(showBlackList) target:self title:@"群聊过滤" rightValue:blackListCountStr accessoryType:1];
148 | }
149 |
150 |
151 | }
152 |
153 |
154 | - (void)showBlackList {
155 | WBMultiSelectGroupsViewController *contactsViewController = [[WBMultiSelectGroupsViewController alloc] initWithBlackList:[ELAppManage sharedManage].appConfig.blackList];
156 | contactsViewController.delegate = self;
157 |
158 | MMUINavigationController *navigationController = [[objc_getClass("MMUINavigationController") alloc] initWithRootViewController:contactsViewController];
159 |
160 | [self presentViewController:navigationController animated:YES completion:nil];
161 | }
162 |
163 |
164 | - (void)RedEnvelopClick:(UISwitch *)RedEnvelopSwitch
165 | {
166 |
167 | [ELAppManage sharedManage].appConfig.autoRedEnvelop = RedEnvelopSwitch.on;
168 |
169 | [self reloadTableViewData];
170 | }
171 |
172 | - (void)addGroupManageSection
173 | {
174 |
175 | MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut];
176 |
177 | [sectionInfo addCell:[self addGroupManageSectionCell]];
178 |
179 | [self.tableViewInfo addSection:sectionInfo];
180 | }
181 |
182 | - (MMTableViewCellInfo *)addGroupManageSectionCell
183 | {
184 |
185 | return [objc_getClass("MMTableViewCellInfo") switchCellForSel:@selector(GroupManageClick:) target:self title:@"群管理" on:[ELAppManage sharedManage].appConfig.groupManage];
186 |
187 | }
188 |
189 | - (void)GroupManageClick:(UISwitch *)GroupManageSwitch
190 | {
191 |
192 | [ELAppManage sharedManage].appConfig.groupManage = GroupManageSwitch.on;
193 |
194 |
195 | }
196 |
197 |
198 | - (void)addMessageSection
199 | {
200 |
201 | MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut];
202 |
203 | [sectionInfo addCell:[self addMessageSectionCell]];
204 |
205 | [self.tableViewInfo addSection:sectionInfo];
206 | }
207 |
208 | - (MMTableViewCellInfo *)addMessageSectionCell
209 | {
210 |
211 | return [objc_getClass("MMTableViewCellInfo") switchCellForSel:@selector(MessageClick:) target:self title:@"消息防撤回" on:[ELAppManage sharedManage].appConfig.Message];
212 |
213 | }
214 |
215 | - (void)MessageClick:(UISwitch *)MessageSwitch
216 | {
217 |
218 | [ELAppManage sharedManage].appConfig.Message = MessageSwitch.on;
219 |
220 |
221 | }
222 |
223 |
224 | - (void)setStepNumber
225 | {
226 |
227 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"微信运动设置" message:@"微信最大步数98800,请输入比当前步数更大的步数" preferredStyle:UIAlertControllerStyleAlert];
228 |
229 | [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
230 | textField.placeholder = @"请输入步数";
231 | textField.keyboardType = UIKeyboardTypePhonePad;
232 | }];
233 |
234 | UIAlertAction *sure = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
235 |
236 | NSString *step = alertController.textFields[0].text;
237 |
238 | [ELAppManage sharedManage].appConfig.ResetStepNum = [step integerValue];
239 |
240 | [self reloadTableViewData];
241 |
242 | }];
243 |
244 | UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
245 |
246 | }];
247 |
248 | [alertController addAction:cancel];
249 |
250 | [alertController addAction:sure];
251 |
252 | [self presentViewController:alertController animated:YES completion:nil];
253 |
254 |
255 | }
256 | - (void)didReceiveMemoryWarning {
257 | [super didReceiveMemoryWarning];
258 | // Dispose of any resources that can be recreated.
259 | }
260 |
261 |
262 | #pragma mark - MultiSelectGroupsViewControllerDelegate
263 | - (void)onMultiSelectGroupCancel {
264 | [self dismissViewControllerAnimated:YES completion:nil];
265 | }
266 | - (void)onMultiSelectGroupReturn:(NSArray *)arg1 {
267 | [ELAppManage sharedManage].appConfig.blackList = arg1;
268 |
269 | [self reloadTableViewData];
270 |
271 | [self dismissViewControllerAnimated:YES completion:nil];
272 | }
273 |
274 | /*
275 | #pragma mark - Navigation
276 |
277 | // In a storyboard-based application, you will often want to do a little preparation before navigation
278 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
279 | // Get the new view controller using [segue destinationViewController].
280 | // Pass the selected object to the new view controller.
281 | }
282 | */
283 |
284 | @end
285 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELSettingViewController/WBMultiSelectGroupsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // WBMultiSelectGroupsViewController.h
3 | // WeChatRedEnvelop
4 | //
5 | // Created by 杨志超 on 2017/2/24.
6 | // Copyright © 2017年 swiftyper. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol MultiSelectGroupsViewControllerDelegate
12 | - (void)onMultiSelectGroupReturn:(NSArray *)arg1;
13 |
14 | @optional
15 | - (void)onMultiSelectGroupCancel;
16 | @end
17 |
18 | @interface WBMultiSelectGroupsViewController : UIViewController
19 |
20 | - (instancetype)initWithBlackList:(NSArray *)blackList;
21 |
22 | @property (nonatomic, assign) id delegate;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELSettingViewController/WBMultiSelectGroupsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // WBMultiSelectGroupsViewController.m
3 | // WeChatRedEnvelop
4 | //
5 | // Created by 杨志超 on 2017/2/24.
6 | // Copyright © 2017年 swiftyper. All rights reserved.
7 | //
8 |
9 | #import "WBMultiSelectGroupsViewController.h"
10 | #import "ELWeChatHeaderinfo.h"
11 | #import
12 |
13 | @interface WBMultiSelectGroupsViewController ()
14 |
15 | @property (strong, nonatomic) ContactSelectView *selectView;
16 | @property (strong, nonatomic) NSArray *blackList;
17 |
18 | @end
19 |
20 | @implementation WBMultiSelectGroupsViewController
21 |
22 | - (instancetype)initWithBlackList:(NSArray *)blackList {
23 | if (self = [super initWithNibName:nil bundle:nil]) {
24 | _blackList = blackList;
25 | }
26 | return self;
27 | }
28 |
29 | - (void)viewDidLoad {
30 | [super viewDidLoad];
31 |
32 | [self initTitleArea];
33 | [self initSelectView];
34 | }
35 |
36 | - (void)viewWillAppear:(BOOL)animated {
37 | [super viewWillAppear:animated];
38 |
39 | MMServiceCenter *serviceCenter = [objc_getClass("MMServiceCenter") defaultCenter];
40 | CContactMgr *contactMgr = [serviceCenter getService:objc_getClass("CContactMgr")];
41 |
42 | for (NSString *contactName in self.blackList) {
43 | CContact *contact = [contactMgr getContactByName:contactName];
44 | [self.selectView addSelect:contact];
45 | }
46 | }
47 |
48 | - (void)initTitleArea {
49 | self.navigationItem.leftBarButtonItem = [objc_getClass("MMUICommonUtil") getBarButtonWithTitle:@"取消" target:self action:@selector(onCancel:) style:0];
50 |
51 | self.navigationItem.rightBarButtonItem = [self rightBarButtonWithSelectCount:self.blackList.count];
52 |
53 | self.title = @"黑名单";
54 |
55 | [self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName: [UIFont boldSystemFontOfSize:18.0]}];
56 | }
57 |
58 | - (UIBarButtonItem *)rightBarButtonWithSelectCount:(unsigned long)selectCount {
59 |
60 | UIBarButtonItem *barButtonItem;
61 | if (selectCount == 0) {
62 | barButtonItem = [objc_getClass("MMUICommonUtil") getBarButtonWithTitle:@"确定" target:self action:@selector(onDone:) style:2];
63 | } else {
64 | NSString *title = [NSString stringWithFormat:@"确定(%lu)", selectCount];
65 | barButtonItem = [objc_getClass("MMUICommonUtil") getBarButtonWithTitle:title target:self action:@selector(onDone:) style:4];
66 | }
67 | return barButtonItem;
68 | }
69 |
70 | - (void)onCancel:(UIBarButtonItem *)item {
71 | if ([self.delegate respondsToSelector:@selector(onMultiSelectGroupCancel)]) {
72 | [self.delegate onMultiSelectGroupCancel];
73 | }
74 | }
75 |
76 | - (void)onDone:(UIBarButtonItem *)item {
77 | if ([self.delegate respondsToSelector:@selector(onMultiSelectGroupReturn:)]) {
78 | NSArray *blacklist = [[self.selectView.m_dicMultiSelect allKeys] copy];
79 | [self.delegate onMultiSelectGroupReturn:blacklist];
80 | }
81 | }
82 |
83 | - (void)initSelectView {
84 | self.selectView = [[objc_getClass("ContactSelectView") alloc] initWithFrame:[UIScreen mainScreen].bounds delegate:self];
85 |
86 | self.selectView.m_uiGroupScene = 5;
87 | self.selectView.m_bMultiSelect = YES;
88 | [self.selectView initData:5];
89 | [self.selectView initView];
90 |
91 | [self.view addSubview:self.selectView];
92 | }
93 |
94 | #pragma mark - ContactSelectViewDelegate
95 | - (void)onSelectContact:(CContact *)arg1 {
96 | self.navigationItem.rightBarButtonItem = [self rightBarButtonWithSelectCount:[self getTotalSelectCount]];
97 | }
98 |
99 | - (unsigned long)getTotalSelectCount {
100 | return (unsigned long)[self.selectView.m_dicMultiSelect count];
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELAppManage.h:
--------------------------------------------------------------------------------
1 | //
2 | // ELAppManange.h
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/10.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ELRedEnvelopInfo.h"
11 | #import "ELWeChatConfig.h"
12 |
13 |
14 | @interface ELAppManage : NSObject
15 |
16 |
17 | + (instancetype)sharedManage;
18 |
19 | @property (nonatomic,strong) ELWeChatConfig *appConfig;
20 |
21 | @property (nonatomic,strong) ELRedEnvelopInfo *redInfo;
22 |
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELAppManage.m:
--------------------------------------------------------------------------------
1 | //
2 | // ELAppManange.m
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/10.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import "ELAppManage.h"
10 |
11 | #import
12 | @implementation ELAppManage
13 |
14 | +(id)sharedManage
15 | {
16 | static ELAppManage *manage = nil;
17 |
18 | static dispatch_once_t onceToken;
19 | dispatch_once(&onceToken, ^{
20 | manage = [ELAppManage new];
21 | });
22 | return manage;
23 | }
24 |
25 | - (id)init
26 | {
27 | if (self = [super init])
28 | {
29 | self.appConfig = [NSKeyedUnarchiver unarchiveObjectWithFile:kAppDataPath];
30 | if (!self.appConfig)
31 | {
32 | self.appConfig = [[ELWeChatConfig alloc] init];
33 | }
34 |
35 |
36 |
37 | self.redInfo = [NSKeyedUnarchiver unarchiveObjectWithFile:kRedInfoPath];
38 | }
39 |
40 | return self;
41 |
42 | }
43 |
44 |
45 |
46 |
47 |
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELRedEnvelopInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // ELRedEnvelopInfo.h
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/10.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface ELRedEnvelopInfo : NSObject
13 |
14 | @property(nonatomic,copy)NSString *msgtype;
15 |
16 | @property(nonatomic,copy)NSString *channelid;
17 |
18 | @property(nonatomic,copy)NSString *sendid;
19 |
20 | @property(nonatomic,copy)NSString *nickName;
21 |
22 | @property(nonatomic,copy)NSString *headImg;
23 |
24 | @property(nonatomic,copy)NSString *nativeUrl;
25 |
26 | @property(nonatomic,copy)NSString *sessionUserName;
27 |
28 | @property(nonatomic,copy)NSString *timingIdentifier;
29 |
30 | @property(nonatomic,copy)NSString *sendusername;
31 |
32 | @property(nonatomic,copy)NSString *ver;
33 |
34 | @property(nonatomic,copy)NSString *sign;
35 |
36 | @property(nonatomic,assign)BOOL isMyself;
37 |
38 |
39 | - (BOOL)saveRedInfo:(ELRedEnvelopInfo *)info;
40 |
41 | - (NSDictionary *)requestDict;
42 |
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELRedEnvelopInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // ELRedEnvelopInfo.m
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/10.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import "ELRedEnvelopInfo.h"
10 |
11 | @implementation ELRedEnvelopInfo
12 |
13 | - (void)encodeWithCoder:(NSCoder *)aCoder
14 | {
15 |
16 | [self yy_modelEncodeWithCoder:aCoder];
17 |
18 | }
19 |
20 |
21 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
22 | {
23 | self = [super init];
24 |
25 | return [self yy_modelInitWithCoder:aDecoder];
26 |
27 | }
28 |
29 |
30 | -(id)copyWithZone:(NSZone *)zone
31 | {
32 |
33 | return [self yy_modelCopy];
34 | }
35 |
36 |
37 | - (BOOL)saveRedInfo:(ELRedEnvelopInfo *)info
38 | {
39 |
40 | return [NSKeyedArchiver archiveRootObject:info toFile:kRedInfoPath];
41 |
42 | }
43 |
44 | - (NSDictionary *)requestDict
45 | {
46 | return @{
47 | @"channelId": self.channelid,
48 | @"headImg": self.headImg,
49 | @"msgType": self.msgtype,
50 | @"nativeUrl": self.nativeUrl,
51 | @"nickName": self.nickName,
52 | @"sendId": self.sendid,
53 | @"sessionUserName": self.sessionUserName,
54 | @"timingIdentifier": self.timingIdentifier
55 | };
56 |
57 | }
58 |
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELWeChatConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // ELWeChatConfig.h
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/9.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import
10 | //#import "ELWeChatHeaderinfo.h"
11 |
12 | @interface ELWeChatConfig : NSObject
13 |
14 | @property (nonatomic,assign) BOOL autoRedEnvelop;
15 |
16 | @property (strong, nonatomic) NSArray *blackList;
17 |
18 | @property (nonatomic,assign) BOOL groupManage;
19 |
20 | @property (nonatomic,assign) BOOL Message;
21 |
22 | @property (nonatomic,assign) BOOL StepManage;
23 |
24 | @property (nonatomic,assign) NSInteger ResetStepNum;
25 |
26 |
27 | @property (nonatomic) id Infor;
28 |
29 | - (BOOL)saveAppInfo:(ELWeChatConfig *)Config;
30 |
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Main/ELWeChatConfig/ELWeChatConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // ELWeChatConfig.m
3 | // ELWeChatDylib
4 | //
5 | // Created by Eli on 2018/10/9.
6 | // Copyright © 2018年 eli. All rights reserved.
7 | //
8 |
9 | #import "ELWeChatConfig.h"
10 |
11 |
12 |
13 | @implementation ELWeChatConfig
14 |
15 | - (void)encodeWithCoder:(NSCoder *)aCoder
16 | {
17 |
18 | [self yy_modelEncodeWithCoder:aCoder];
19 |
20 | }
21 |
22 |
23 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
24 | {
25 | self = [super init];
26 |
27 | return [self yy_modelInitWithCoder:aDecoder];
28 |
29 | }
30 |
31 |
32 | -(id)copyWithZone:(NSZone *)zone
33 | {
34 |
35 | return [self yy_modelCopy];
36 | }
37 |
38 | - (BOOL)saveAppInfo:(ELWeChatConfig *)Config
39 | {
40 |
41 | return [NSKeyedArchiver archiveRootObject:Config toFile:kAppDataPath];
42 |
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Scripts/quick-resign.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Usage
4 | # Must be an absolute path
5 |
6 | # ./quick-resign.sh [insert] "origin.ipa path" "resign.ipa path"
7 |
8 | INSERT_DYLIB=NO
9 | INPUT_PATH=$1
10 | OUTPUT_PATH=$2
11 |
12 | if [[ $1 == "insert" ]];then
13 | INSERT_DYLIB=YES
14 | INPUT_PATH=$2
15 | OUTPUT_PATH=$3
16 | fi
17 |
18 | if [[ ! $OUTPUT_PATH ]];then
19 | OUTPUT_PATH=$PWD
20 | fi
21 |
22 | cp -rf $INPUT_PATH ../TargetApp/
23 | cd ../../
24 | xcodebuild MONKEYDEV_INSERT_DYLIB=$INSERT_DYLIB | xcpretty
25 | cd LatestBuild
26 | ./createIPA.command
27 | cp -rf Target.ipa $OUTPUT_PATH
28 | exit 0
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/Target.plist:
--------------------------------------------------------------------------------
1 | /Users/cuishengyu/Desktop/ELWeChatApp/ELWeChat/ELWeChat/TargetApp/WeChat.app/Info.plist
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/TargetApp/put ipa or app here:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuiyu8580/ELWeChat/376e57ee92ec4744faa85825ed6712ee3bfabc6b/ELWeChat/ELWeChat/TargetApp/put ipa or app here
--------------------------------------------------------------------------------
/ELWeChat/ELWeChat/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuiyu8580/ELWeChat/376e57ee92ec4744faa85825ed6712ee3bfabc6b/ELWeChat/ELWeChat/icon.png
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/AntiAntiDebug/AntiAntiDebug.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // AntiAntiDebug.m
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2016/12/10.
8 | // Copyright © 2017年 MonkeyDev. All rights reserved.
9 | //
10 |
11 | #if TARGET_OS_SIMULATOR
12 | #error Do not support the simulator, please use the real iPhone Device.
13 | #endif
14 |
15 | #import "fishhook.h"
16 | #import
17 | #import
18 |
19 | typedef int (*ptrace_ptr_t)(int _request,pid_t _pid, caddr_t _addr,int _data);
20 | typedef void* (*dlsym_ptr_t)(void * __handle, const char* __symbol);
21 | typedef int (*syscall_ptr_t)(int, ...);
22 | typedef int (*sysctl_ptr_t)(int *,u_int, void*, size_t*,void*, size_t);
23 |
24 |
25 | static ptrace_ptr_t orig_ptrace = NULL;
26 | static dlsym_ptr_t orig_dlsym = NULL;
27 | static sysctl_ptr_t orig_sysctl = NULL;
28 | static syscall_ptr_t orig_syscall = NULL;
29 |
30 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
31 | void* my_dlsym(void* __handle, const char* __symbol);
32 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize);
33 | int my_syscall(int code, va_list args);
34 |
35 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){
36 | if(_request != 31){
37 | return orig_ptrace(_request,_pid,_addr,_data);
38 | }
39 |
40 | NSLog(@"[AntiAntiDebug] - ptrace request is PT_DENY_ATTACH");
41 |
42 | return 0;
43 | }
44 |
45 | void* my_dlsym(void* __handle, const char* __symbol){
46 | if(strcmp(__symbol, "ptrace") != 0){
47 | return orig_dlsym(__handle, __symbol);
48 | }
49 |
50 | NSLog(@"[AntiAntiDebug] - dlsym get ptrace symbol");
51 |
52 | return my_ptrace;
53 | }
54 |
55 | typedef struct kinfo_proc _kinfo_proc;
56 |
57 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){
58 | if(namelen == 4 && name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID && info && infosize && ((int)*infosize == sizeof(_kinfo_proc))){
59 | int ret = orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize);
60 | struct kinfo_proc *info_ptr = (struct kinfo_proc *)info;
61 | if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){
62 | NSLog(@"[AntiAntiDebug] - sysctl query trace status.");
63 | info_ptr->kp_proc.p_flag ^= P_TRACED;
64 | if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){
65 | NSLog(@"trace status reomve success!");
66 | }
67 | }
68 | return ret;
69 | }
70 | return orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize);
71 | }
72 |
73 | int my_syscall(int code, va_list args){
74 | int request;
75 | va_list newArgs;
76 | va_copy(newArgs, args);
77 | if(code == 26){
78 | #ifdef __LP64__
79 | __asm__(
80 | "ldr %w[result], [fp, #0x10]\n"
81 | : [result] "=r" (request)
82 | :
83 | :
84 | );
85 | #else
86 | request = va_arg(args, int);
87 | #endif
88 | if(request == 31){
89 | NSLog(@"[AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH");
90 | return 0;
91 | }
92 | }
93 | return orig_syscall(code, newArgs);
94 | }
95 |
96 | __attribute__((constructor)) static void entry(){
97 | NSLog(@"[AntiAntiDebug Init]");
98 |
99 | rebind_symbols((struct rebinding[1]){{"ptrace", my_ptrace, (void*)&orig_ptrace}},1);
100 |
101 | rebind_symbols((struct rebinding[1]){{"dlsym", my_dlsym, (void*)&orig_dlsym}},1);
102 |
103 | //some app will crash with _dyld_debugger_notification
104 | // rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1);
105 |
106 | rebind_symbols((struct rebinding[1]){{"syscall", my_syscall, (void*)&orig_syscall}},1);
107 | }
108 |
109 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/ANYMethodLog.h:
--------------------------------------------------------------------------------
1 | //
2 | // ANYMethodLog.h
3 | // ANYMethodLog
4 | //
5 | // Created by qiuhaodong on 2017/1/14.
6 | // Copyright © 2017年 qiuhaodong. All rights reserved.
7 | //
8 | // https://github.com/qhd/ANYMethodLog.git
9 | //
10 |
11 | #import
12 |
13 | typedef BOOL (^ConditionBlock)(SEL sel);
14 | typedef void (^BeforeBlock)(id target, SEL sel, NSArray *args, int deep);
15 | typedef void (^AfterBlock)(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue);
16 |
17 | @interface ANYMethodLog : NSObject
18 |
19 | /**
20 | 打印对象的方法调用
21 |
22 | @param aClass 要打印的类
23 | @param condition 根据此 block 来决定是否追踪方法(sel 是方法名)
24 | @param before 方法调用前会调用该 block(target 是检测的对象,sel 是方法名,args 是参数列表)
25 | @param after 方法调用后会调用该 block(interval 是执行方法的耗时)
26 | */
27 | + (void)logMethodWithClass:(Class)aClass
28 | condition:(ConditionBlock) condition
29 | before:(BeforeBlock) before
30 | after:(AfterBlock) after;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDConfigManager.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDConfigManager.h
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/4/24.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #import
12 |
13 | #define MDCONFIG_CYCRIPT_KEY @"Cycript"
14 | #define MDCONFIG_TRACE_KEY @"MethodTrace"
15 | #define MDCONFIG_ENABLE_KEY @"ENABLE"
16 | #define MDCONFIG_CLASS_LIST @"CLASS_LIST"
17 | #define MDCONFIG_LOADATLAUNCH_KEY @"LoadAtLaunch"
18 |
19 | @interface MDConfigManager : NSObject
20 |
21 | + (instancetype)sharedInstance;
22 |
23 | - (NSDictionary*)readConfigByKey:(NSString*) key;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDConfigManager.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDConfigManager.m
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/4/24.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #define CONFIG_FILE_NAME @"MDConfig"
12 |
13 | #import "MDConfigManager.h"
14 |
15 | @implementation MDConfigManager{
16 | NSString* _filepath;
17 | }
18 |
19 | + (instancetype)sharedInstance{
20 | static MDConfigManager *sharedInstance = nil;
21 | if (!sharedInstance){
22 | sharedInstance = [[MDConfigManager alloc] init];
23 | }
24 | return sharedInstance;
25 | }
26 |
27 | - (BOOL)isActive{
28 | _filepath = [[NSBundle mainBundle] pathForResource:CONFIG_FILE_NAME ofType:@"plist"];
29 | if(_filepath == nil){
30 | return NO;
31 | }
32 | return YES;
33 | }
34 |
35 | - (NSDictionary*) readConfigByKey:(NSString*) key{
36 | if([self isActive]){
37 | NSDictionary* contentDict = [NSDictionary dictionaryWithContentsOfFile:_filepath];
38 | if([contentDict.allKeys containsObject:key]){
39 | return contentDict[key];
40 | }else{
41 | return nil;
42 | }
43 | }else{
44 | return nil;
45 | }
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDCycriptManager.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDCycriptManager.h
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/3/8.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #ifndef __OPTIMIZE__
12 |
13 | #import
14 |
15 | #define PORT 6666
16 |
17 | @interface MDCycriptManager : NSObject
18 |
19 | + (instancetype)sharedInstance;
20 |
21 |
22 | /**
23 | Download script by config.plist
24 |
25 | @param update Force update of all scripts
26 | */
27 | -(void)loadCycript:(BOOL) update;
28 |
29 | /**
30 | eval javascript by cycript
31 |
32 | @param cycript javascript string
33 | @param error error happened
34 | @return eval result
35 | */
36 | -(NSString*)evaluateCycript:(NSString*) cycript error:(NSError **) error;
37 |
38 | @end
39 |
40 | #endif
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDCycriptManager.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDCycriptManager.m
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/3/8.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #ifndef __OPTIMIZE__
12 |
13 | #import "MDCycriptManager.h"
14 | #import "MDConfigManager.h"
15 | #import
16 | #import
17 | #import
18 | #import
19 |
20 | #define IOS_CELLULAR @"pdp_ip0"
21 | #define IOS_WIFI @"en0"
22 | #define IP_ADDR_IPv4 @"ipv4"
23 | #define IP_ADDR_IPv6 @"ipv6"
24 | #define MDLog(fmt, ...) NSLog((@"[Cycript] " fmt), ##__VA_ARGS__)
25 |
26 | extern JSGlobalContextRef CYGetJSContext(void);
27 | extern void CydgetMemoryParse(const uint16_t **data, size_t *size);
28 |
29 | NSString * const CYErrorLineKey = @"CYErrorLineKey";
30 | NSString * const CYErrorNameKey = @"CYErrorNameKey";
31 | NSString * const CYErrorMessageKey = @"CYErrorMessageKey";
32 |
33 | @interface MDSettingObject : NSObject
34 |
35 | @property (nonatomic, assign) NSInteger priority;
36 | @property (nonatomic, copy) NSString* url;
37 | @property (nonatomic, copy) NSString* content;
38 | @property (nonatomic, assign) BOOL loadAtLaunch;
39 |
40 | -(instancetype)initWithDicationary:(NSDictionary*) dictionary;
41 |
42 | @end
43 |
44 | @implementation MDSettingObject
45 |
46 | -(instancetype)initWithDicationary:(NSDictionary *)dictionary{
47 | self = [super init];
48 | if(self){
49 | self.priority = [dictionary[@"priority"] integerValue];
50 | self.url = dictionary[@"url"];
51 | self.content = dictionary[@"content"];
52 | self.loadAtLaunch = [dictionary objectForKey:MDCONFIG_LOADATLAUNCH_KEY] && [dictionary[MDCONFIG_LOADATLAUNCH_KEY] boolValue];
53 | }
54 | return self;
55 | }
56 |
57 | @end
58 |
59 | @interface MDCycriptManager()
60 |
61 | @property (nonatomic, strong) NSDictionary* configItem;
62 | @property (nonatomic, copy) NSString* cycriptDirectory;
63 | @property (nonatomic, strong) NSMutableArray* downloading;
64 | @property (nonatomic, strong) NSMutableDictionary* loadAtLaunchModules;
65 |
66 | @end
67 |
68 | @implementation MDCycriptManager
69 |
70 | + (instancetype)sharedInstance{
71 | static MDCycriptManager *sharedInstance = nil;
72 | if (!sharedInstance){
73 | sharedInstance = [[MDCycriptManager alloc] init];
74 | }
75 | return sharedInstance;
76 | }
77 |
78 | - (instancetype)init
79 | {
80 | self = [super init];
81 | if (self) {
82 | _loadAtLaunchModules = [NSMutableDictionary dictionary];
83 | _downloading = [NSMutableArray array];
84 | [self check];
85 | [self readConfigFile];
86 | }
87 | return self;
88 | }
89 |
90 | -(void)check{
91 | NSString* ip = [self getIPAddress];
92 | if(ip != nil){
93 | printf("\nDownload cycript(https://cydia.saurik.com/api/latest/3) then run: ./cycript -r %s:%d\n\n", [ip UTF8String], PORT);
94 | }else{
95 | printf("\nPlease connect wifi before using cycript!\n\n");
96 | }
97 |
98 | NSFileManager *fileManager = [NSFileManager defaultManager];
99 | NSString *documentsPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject];
100 | _cycriptDirectory = [documentsPath stringByAppendingPathComponent:@"cycript"];
101 | [fileManager createDirectoryAtPath:_cycriptDirectory withIntermediateDirectories:YES attributes:nil error:nil];
102 | }
103 |
104 | -(NSArray*)sortedArray:(NSDictionary*) dictionary{
105 | NSMutableArray* result = [NSMutableArray arrayWithCapacity:10];
106 |
107 | NSArray* sortedArray = [dictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSNumber* _Nonnull number1, NSNumber* _Nonnull number2) {
108 | if ([number1 integerValue] > [number2 integerValue])
109 | return NSOrderedDescending;
110 | return NSOrderedAscending;
111 | }];
112 |
113 | for (NSNumber* item in sortedArray) {
114 | [result addObject:dictionary[item]];
115 | }
116 |
117 | return [result copy];
118 | }
119 |
120 | -(void)readConfigFile{
121 | MDConfigManager * configManager = [MDConfigManager sharedInstance];
122 | _configItem = [configManager readConfigByKey:MDCONFIG_CYCRIPT_KEY];
123 | }
124 |
125 | -(void)loadCycript:(BOOL) update{
126 | NSFileManager *fileManager = [NSFileManager defaultManager];
127 |
128 | if(_configItem && _configItem.count > 0){
129 |
130 | BOOL download = NO;
131 |
132 | for (NSString* moduleName in _configItem.allKeys) {
133 | MDSettingObject * item = [[MDSettingObject alloc] initWithDicationary:_configItem[moduleName]];
134 | NSString *fullPath = [[_cycriptDirectory stringByAppendingPathComponent:moduleName] stringByAppendingPathExtension:@"cy"];
135 |
136 | if(item.url){
137 | if(![fileManager fileExistsAtPath:fullPath] || update){
138 | download = YES;
139 | [self.downloading addObject:moduleName];
140 | [self downLoadUrl:item.url saveName:moduleName];
141 | }
142 | }
143 |
144 | if(item.content){
145 | if(![fileManager fileExistsAtPath:fullPath] || update){
146 | NSString* writeContent = [NSString stringWithFormat:@"(function(exports) { %@ })(exports);", item.content];
147 | [writeContent writeToFile:fullPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
148 | }
149 | }
150 |
151 | if(item.loadAtLaunch){
152 | [_loadAtLaunchModules setObject:fullPath forKey:@(item.priority)];
153 | }
154 | }
155 |
156 | if(!download){
157 | [self finishDownload];
158 | }
159 | }
160 | }
161 |
162 | -(void)finishDownload{
163 | MDLog(@"Finish download all script!");
164 | NSArray* sortedArray = [self sortedArray:_loadAtLaunchModules];
165 | for (NSString* fullPath in sortedArray) {
166 | NSError* error;
167 | [self evaluateCycript:[NSString stringWithFormat:@"require('%@');",fullPath] error:&error];
168 | if(error.code != 0){
169 | MDLog(@"%@", error.localizedDescription);
170 | }
171 | }
172 | }
173 |
174 | -(void)downLoadUrl:(NSString*) urlString saveName:(NSString*) filename{
175 | __weak typeof(self) weakSelf = self;
176 | NSURLSession *session = [NSURLSession sharedSession];
177 | NSURL *url = [NSURL URLWithString:urlString];
178 | NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
179 |
180 | if(error){
181 | MDLog(@"Failed download script [%@]: %@", filename, error.localizedDescription);
182 | }else{
183 | NSString *fullPath = [[weakSelf.cycriptDirectory stringByAppendingPathComponent:filename] stringByAppendingPathExtension:@"cy"];
184 | [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
185 |
186 | MDLog(@"Successful download script [%@]", filename);
187 | }
188 |
189 | [weakSelf.downloading removeObject:filename];
190 |
191 | if(!weakSelf.downloading.count){
192 | [weakSelf finishDownload];
193 | }
194 | }];
195 | [downloadTask resume];
196 | }
197 |
198 | -(NSString *)evaluateCycript:(NSString *)cycript error:(NSError *__autoreleasing *)error{
199 | JSGlobalContextRef context = CYGetJSContext();
200 |
201 | size_t length = cycript.length;
202 | unichar *buffer = malloc(length * sizeof(unichar));
203 | [cycript getCharacters:buffer range:NSMakeRange(0, length)];
204 | const uint16_t *characters = buffer;
205 | CydgetMemoryParse(&characters, &length);
206 | JSStringRef expression = JSStringCreateWithCharacters(characters, length);
207 |
208 | // Evaluate the Javascript
209 | JSValueRef exception = NULL;
210 | JSValueRef result = JSEvaluateScript(context, expression, NULL, NULL, 0, &exception);
211 | JSStringRelease(expression);
212 |
213 | NSString *resultString = nil;
214 |
215 | // If a result was returned, convert it into an NSString
216 | if (result) {
217 | JSStringRef string = JSValueToStringCopy(context, result, &exception);
218 | if (string) {
219 | resultString = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string);
220 | JSStringRelease(string);
221 | }
222 | }
223 |
224 | // If an exception was thrown, convert it into an NSError
225 | if (exception && error) {
226 | JSObjectRef exceptionObject = JSValueToObject(context, exception, NULL);
227 |
228 | NSInteger line = (NSInteger)JSValueToNumber(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("line"), NULL), NULL);
229 | JSStringRef string = JSValueToStringCopy(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("name"), NULL), NULL);
230 | NSString *name = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string);
231 | JSStringRelease(string);
232 | string = JSValueToStringCopy(context, JSObjectGetProperty(context, exceptionObject, JSStringCreateWithUTF8CString("message"), NULL), NULL);
233 | NSString *message = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string);
234 | JSStringRelease(string);
235 | string = JSValueToStringCopy(context, exception, NULL);
236 | NSString *description = (__bridge_transfer NSString *)JSStringCopyCFString(kCFAllocatorDefault, string);
237 | JSStringRelease(string);
238 |
239 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
240 | [userInfo setValue:@(line) forKey:CYErrorLineKey];
241 | [userInfo setValue:name forKey:CYErrorNameKey];
242 | [userInfo setValue:message forKey:CYErrorMessageKey];
243 | [userInfo setValue:description forKey:NSLocalizedDescriptionKey];
244 | *error = [NSError errorWithDomain:@"CYContextDomain" code:0 userInfo:userInfo];
245 | }
246 |
247 | return resultString;
248 | }
249 |
250 | - (NSString *)getIPAddress{
251 |
252 | NSDictionary *addresses = [self getIPAddresses];
253 |
254 | if([addresses.allKeys containsObject:IOS_WIFI @"/" IP_ADDR_IPv4]){
255 | return addresses[IOS_WIFI @"/" IP_ADDR_IPv4];
256 | }
257 |
258 | return nil;
259 | }
260 |
261 | - (NSDictionary *)getIPAddresses{
262 | NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
263 |
264 | // retrieve the current interfaces - returns 0 on success
265 | struct ifaddrs *interfaces;
266 | if(!getifaddrs(&interfaces)) {
267 | // Loop through linked list of interfaces
268 | struct ifaddrs *interface;
269 | for(interface=interfaces; interface; interface=interface->ifa_next) {
270 | if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
271 | continue; // deeply nested code harder to read
272 | }
273 | const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
274 | char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
275 | if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
276 | NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
277 | NSString *type;
278 | if(addr->sin_family == AF_INET) {
279 | if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
280 | type = IP_ADDR_IPv4;
281 | }
282 | } else {
283 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
284 | if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
285 | type = IP_ADDR_IPv6;
286 | }
287 | }
288 | if(type) {
289 | NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
290 | addresses[key] = [NSString stringWithUTF8String:addrBuf];
291 | }
292 | }
293 | }
294 | // Free memory
295 | freeifaddrs(interfaces);
296 | }
297 | return [addresses count] ? addresses : nil;
298 | }
299 |
300 | @end
301 |
302 | #endif
303 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDMethodTrace.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDMethodTrace.h
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2017/9/7.
8 | // Copyright © 2017年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #ifndef MethodTrace_h
12 | #define MethodTrace_h
13 |
14 | #import
15 |
16 | @interface MDMethodTrace : NSObject
17 |
18 | + (void)addClassTrace:(NSString*) className;
19 |
20 | + (void)addClassTrace:(NSString *)className methodName:(NSString*) methodName;
21 |
22 | + (void)addClassTrace:(NSString *)className methodList:(NSArray*) methodList;
23 |
24 | @end
25 |
26 | #endif /* MethodTrace_h */
27 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Config/MDMethodTrace.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // MDMethodTrace.m
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2017/9/6.
8 | // Copyright © 2017年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #import "ANYMethodLog.h"
12 | #import "MDMethodTrace.h"
13 | #import
14 | #import
15 | #import "MDConfigManager.h"
16 |
17 | #define MDLog(fmt, ...) NSLog((@"[MethodTrace] " fmt), ##__VA_ARGS__)
18 |
19 | @implementation MDMethodTrace : NSObject
20 |
21 | +(void)addClassTrace:(NSString *)className{
22 | [self addClassTrace:className methodList:nil];
23 | }
24 |
25 | +(void)addClassTrace:(NSString *)className methodName:(NSString *)methodName{
26 | [self addClassTrace:className methodList:@[methodName]];
27 | }
28 |
29 | +(void)addClassTrace:(NSString *)className methodList:(NSArray *)methodList{
30 | Class targetClass = objc_getClass([className UTF8String]);
31 | if(targetClass != nil){
32 | [ANYMethodLog logMethodWithClass:NSClassFromString(className) condition:^BOOL(SEL sel) {
33 | return (methodList == nil || methodList.count == 0) ? YES : [methodList containsObject:NSStringFromSelector(sel)];
34 | } before:^(id target, SEL sel, NSArray *args, int deep) {
35 | NSString *selector = NSStringFromSelector(sel);
36 | NSMutableString *selectorString = [NSMutableString new];
37 | if([selector containsString:@":"]){
38 | NSArray *selectorArrary = [selector componentsSeparatedByString:@":"];
39 | selectorArrary = [selectorArrary filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];
40 | for (int i = 0; i < selectorArrary.count; i++) {
41 | [selectorString appendFormat:@"%@:%@ ", selectorArrary[i], args[i]];
42 | }
43 | }else{
44 | [selectorString appendString:selector];
45 | }
46 |
47 | NSMutableString *deepString = [NSMutableString new];
48 | for (int i = 0; i < deep; i++) {
49 | [deepString appendString:@"-"];
50 | }
51 | NSLog(@"%@[%@ %@]", deepString , target, selectorString);
52 | } after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval,int deep, id retValue) {
53 | NSMutableString *deepString = [NSMutableString new];
54 | for (int i = 0; i < deep; i++) {
55 | [deepString appendString:@"-"];
56 | }
57 | NSLog(@"%@ret:%@", deepString, retValue);
58 | }];
59 | }else{
60 | MDLog(@"canot find class %@", className);
61 | }
62 | }
63 |
64 | @end
65 |
66 | static __attribute__((constructor)) void entry(){
67 | MDConfigManager * configManager = [MDConfigManager sharedInstance];
68 | NSDictionary* content = [configManager readConfigByKey:MDCONFIG_TRACE_KEY];
69 |
70 | if(content && [content valueForKey:MDCONFIG_ENABLE_KEY] && [content[MDCONFIG_ENABLE_KEY] boolValue]){
71 | NSDictionary* classListDictionary = [content valueForKey:MDCONFIG_CLASS_LIST];
72 | if(classListDictionary && classListDictionary.count > 0){
73 | for (NSString* className in classListDictionary.allKeys) {
74 | Class targetClass = objc_getClass([className UTF8String]);
75 | if(targetClass != nil){
76 | id methodList = [classListDictionary valueForKey:className];
77 | if([methodList isKindOfClass:[NSArray class]]){
78 | [MDMethodTrace addClassTrace:className methodList:methodList];
79 | }else{
80 | [MDMethodTrace addClassTrace:className];
81 | }
82 | }else{
83 | MDLog(@"Canot find class %@", className);
84 | }
85 | }
86 | }
87 | }else{
88 | MDLog(@"Method Trace is disabled");
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/ELWeChatDylib-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'ELWeChatDylib' target in the 'ELWeChatDylib' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "/opt/theos/Prefix.pch" //path/to/theos/Prefix.pch
8 | #import "ELAppManage.h"
9 | #import "YYModel.h"
10 | #import "HUD.h"
11 | #import "MUHook.h"
12 |
13 | #define kDocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
14 |
15 |
16 | //红包信息
17 | #define kRedInfoPath [kDocumentPath stringByAppendingPathComponent:@"KRedInfo.data"]
18 |
19 | #define kAppDataPath [kDocumentPath stringByAppendingPathComponent:@"KAppData.data"]
20 |
21 |
22 | #define UIColorFromHex(s) [UIColor colorWithRed:(((s & 0xFF0000) >> 16))/255.0 green:(((s &0xFF00) >>8))/255.0 blue:((s &0xFF))/255.0 alpha:1.0]
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/ELWeChatDylib.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // ELWeChatDylib.h
5 | // ELWeChatDylib
6 | //
7 | // Created by Eli on 2018/10/9.
8 | // Copyright (c) 2018年 eli. All rights reserved.
9 | //
10 |
11 | #import
12 |
13 | #define INSERT_SUCCESS_WELCOME @"\n 🎉!!!congratulations!!!🎉\n👍----------------insert dylib success----------------👍"
14 |
15 | @interface CustomViewController
16 |
17 | @property (nonatomic, copy) NSString* newProperty;
18 |
19 | + (void)classMethod;
20 |
21 | - (NSString*)getMyName;
22 |
23 | - (void)newMethod:(NSString*) output;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Logos/ELWeChatDylib.mm:
--------------------------------------------------------------------------------
1 | #line 1 "/Users/cuishengyu/Desktop/ELWeChatApp/ELWeChat/ELWeChatDylib/Logos/ELWeChatDylib.xm"
2 |
3 |
4 | #import
5 |
6 | @interface CustomViewController
7 |
8 | @property (nonatomic, copy) NSString* newProperty;
9 |
10 | + (void)classMethod;
11 |
12 | - (NSString*)getMyName;
13 |
14 | - (void)newMethod:(NSString*) output;
15 |
16 | @end
17 |
18 |
19 | #include
20 | #if defined(__clang__)
21 | #if __has_feature(objc_arc)
22 | #define _LOGOS_SELF_TYPE_NORMAL __unsafe_unretained
23 | #define _LOGOS_SELF_TYPE_INIT __attribute__((ns_consumed))
24 | #define _LOGOS_SELF_CONST const
25 | #define _LOGOS_RETURN_RETAINED __attribute__((ns_returns_retained))
26 | #else
27 | #define _LOGOS_SELF_TYPE_NORMAL
28 | #define _LOGOS_SELF_TYPE_INIT
29 | #define _LOGOS_SELF_CONST
30 | #define _LOGOS_RETURN_RETAINED
31 | #endif
32 | #else
33 | #define _LOGOS_SELF_TYPE_NORMAL
34 | #define _LOGOS_SELF_TYPE_INIT
35 | #define _LOGOS_SELF_CONST
36 | #define _LOGOS_RETURN_RETAINED
37 | #endif
38 |
39 | @class CustomViewController;
40 | static void (*_logos_meta_orig$_ungrouped$CustomViewController$classMethod)(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST, SEL); static void _logos_meta_method$_ungrouped$CustomViewController$classMethod(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST, SEL); static void _logos_method$_ungrouped$CustomViewController$newMethod$(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST, SEL, NSString*); static id _logos_method$_ungrouped$CustomViewController$newProperty(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST, SEL); static void _logos_method$_ungrouped$CustomViewController$setNewProperty$(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST, SEL, id); static NSString* (*_logos_orig$_ungrouped$CustomViewController$getMyName)(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST, SEL); static NSString* _logos_method$_ungrouped$CustomViewController$getMyName(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST, SEL);
41 | static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$CustomViewController(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("CustomViewController"); } return _klass; }
42 | #line 17 "/Users/cuishengyu/Desktop/ELWeChatApp/ELWeChat/ELWeChatDylib/Logos/ELWeChatDylib.xm"
43 |
44 |
45 |
46 | static void _logos_meta_method$_ungrouped$CustomViewController$classMethod(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
47 | HBLogDebug(@"+[ classMethod]", self);
48 |
49 | _logos_meta_orig$_ungrouped$CustomViewController$classMethod(self, _cmd);
50 | }
51 |
52 |
53 | static void _logos_method$_ungrouped$CustomViewController$newMethod$(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, NSString* output){
54 | NSLog(@"This is a new method : %@", output);
55 | }
56 |
57 |
58 | static id _logos_method$_ungrouped$CustomViewController$newProperty(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
59 | return objc_getAssociatedObject(self, @selector(newProperty));
60 | }
61 |
62 |
63 | static void _logos_method$_ungrouped$CustomViewController$setNewProperty$(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, id value) {
64 | objc_setAssociatedObject(self, @selector(newProperty), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
65 | }
66 |
67 |
68 | static NSString* _logos_method$_ungrouped$CustomViewController$getMyName(_LOGOS_SELF_TYPE_NORMAL CustomViewController* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
69 | HBLogDebug(@"-[ getMyName]", self);
70 |
71 | NSString* password = MSHookIvar(self,"_password");
72 |
73 | NSLog(@"password:%@", password);
74 |
75 | [_logos_static_class_lookup$CustomViewController() classMethod];
76 |
77 | [self newMethod:@"output"];
78 |
79 | self.newProperty = @"newProperty";
80 |
81 | NSLog(@"newProperty : %@", self.newProperty);
82 |
83 | return _logos_orig$_ungrouped$CustomViewController$getMyName(self, _cmd);
84 | }
85 |
86 |
87 |
88 | static __attribute__((constructor)) void _logosLocalInit() {
89 | {Class _logos_class$_ungrouped$CustomViewController = objc_getClass("CustomViewController"); Class _logos_metaclass$_ungrouped$CustomViewController = object_getClass(_logos_class$_ungrouped$CustomViewController); MSHookMessageEx(_logos_metaclass$_ungrouped$CustomViewController, @selector(classMethod), (IMP)&_logos_meta_method$_ungrouped$CustomViewController$classMethod, (IMP*)&_logos_meta_orig$_ungrouped$CustomViewController$classMethod);{ char _typeEncoding[1024]; unsigned int i = 0; _typeEncoding[i] = 'v'; i += 1; _typeEncoding[i] = '@'; i += 1; _typeEncoding[i] = ':'; i += 1; memcpy(_typeEncoding + i, @encode(NSString*), strlen(@encode(NSString*))); i += strlen(@encode(NSString*)); _typeEncoding[i] = '\0'; class_addMethod(_logos_class$_ungrouped$CustomViewController, @selector(newMethod:), (IMP)&_logos_method$_ungrouped$CustomViewController$newMethod$, _typeEncoding); }{ char _typeEncoding[1024]; unsigned int i = 0; _typeEncoding[i] = '@'; i += 1; _typeEncoding[i] = '@'; i += 1; _typeEncoding[i] = ':'; i += 1; _typeEncoding[i] = '\0'; class_addMethod(_logos_class$_ungrouped$CustomViewController, @selector(newProperty), (IMP)&_logos_method$_ungrouped$CustomViewController$newProperty, _typeEncoding); }{ char _typeEncoding[1024]; unsigned int i = 0; _typeEncoding[i] = 'v'; i += 1; _typeEncoding[i] = '@'; i += 1; _typeEncoding[i] = ':'; i += 1; _typeEncoding[i] = '@'; i += 1; _typeEncoding[i] = '\0'; class_addMethod(_logos_class$_ungrouped$CustomViewController, @selector(setNewProperty:), (IMP)&_logos_method$_ungrouped$CustomViewController$setNewProperty$, _typeEncoding); }MSHookMessageEx(_logos_class$_ungrouped$CustomViewController, @selector(getMyName), (IMP)&_logos_method$_ungrouped$CustomViewController$getMyName, (IMP*)&_logos_orig$_ungrouped$CustomViewController$getMyName);} }
90 | #line 62 "/Users/cuishengyu/Desktop/ELWeChatApp/ELWeChat/ELWeChatDylib/Logos/ELWeChatDylib.xm"
91 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Logos/ELWeChatDylib.xm:
--------------------------------------------------------------------------------
1 | // See http://iphonedevwiki.net/index.php/Logos
2 |
3 | #import
4 |
5 | @interface CustomViewController
6 |
7 | @property (nonatomic, copy) NSString* newProperty;
8 |
9 | + (void)classMethod;
10 |
11 | - (NSString*)getMyName;
12 |
13 | - (void)newMethod:(NSString*) output;
14 |
15 | @end
16 |
17 | %hook CustomViewController
18 |
19 | + (void)classMethod
20 | {
21 | %log;
22 |
23 | %orig;
24 | }
25 |
26 | %new
27 | -(void)newMethod:(NSString*) output{
28 | NSLog(@"This is a new method : %@", output);
29 | }
30 |
31 | %new
32 | - (id)newProperty {
33 | return objc_getAssociatedObject(self, @selector(newProperty));
34 | }
35 |
36 | %new
37 | - (void)setNewProperty:(id)value {
38 | objc_setAssociatedObject(self, @selector(newProperty), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
39 | }
40 |
41 | - (NSString*)getMyName
42 | {
43 | %log;
44 |
45 | NSString* password = MSHookIvar(self,"_password");
46 |
47 | NSLog(@"password:%@", password);
48 |
49 | [%c(CustomViewController) classMethod];
50 |
51 | [self newMethod:@"output"];
52 |
53 | self.newProperty = @"newProperty";
54 |
55 | NSLog(@"newProperty : %@", self.newProperty);
56 |
57 | return %orig();
58 | }
59 |
60 | %end
61 |
62 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Tools/LLDBTools.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // LLDBTools.h
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/3/8.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #import
12 | #import
13 |
14 | //(lldb) po pviews()
15 |
16 | NSString* pvc(void);
17 |
18 | NSString* pviews(void);
19 |
20 | NSString* pactions(vm_address_t address);
21 |
22 | NSString* pblock(vm_address_t address);
23 |
24 | NSString* methods(const char * classname);
25 |
26 | NSString* ivars(vm_address_t address);
27 |
28 | NSString* choose(const char* classname);
29 |
30 | NSString* vmmap();
31 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/Tools/LLDBTools.mm:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // LLDBTools.m
5 | // MonkeyDev
6 | //
7 | // Created by AloneMonkey on 2018/3/8.
8 | // Copyright © 2018年 AloneMonkey. All rights reserved.
9 | //
10 |
11 | #pragma GCC diagnostic ignored "-Wundeclared-selector"
12 |
13 | #import "LLDBTools.h"
14 | #import
15 | #import
16 | #import
17 | #import
18 | #import
19 | #import
20 |
21 | enum {
22 | BLOCK_HAS_COPY_DISPOSE = (1 << 25),
23 | BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
24 | BLOCK_IS_GLOBAL = (1 << 28),
25 | BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
26 | BLOCK_HAS_SIGNATURE = (1 << 30),
27 | };
28 |
29 | struct Block_literal_1 {
30 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
31 | int flags;
32 | int reserved;
33 | void (*invoke)(void *, ...);
34 | struct Block_descriptor_1 {
35 | unsigned long int reserved; // NULL
36 | unsigned long int size; // sizeof(struct Block_literal_1)
37 | // optional helper functions
38 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25)
39 | void (*dispose_helper)(void *src); // IFF (1<<25)
40 | // required ABI.2010.3.16
41 | const char *signature; // IFF (1<<30)
42 | } *descriptor;
43 | // imported variables
44 | };
45 |
46 | NSString* decode(NSString* code);
47 | NSArray* choose_inner(const char * classname);
48 | char * protection_bits_to_rwx (vm_prot_t p);
49 | const char * unparse_inheritance (vm_inherit_t i);
50 | char * behavior_to_text (vm_behavior_t b);
51 |
52 | NSString* decode(NSString* code){
53 | NSDictionary * encodeMap = @{
54 | @"c": @"char",
55 | @"i": @"int",
56 | @"s": @"short",
57 | @"l": @"long",
58 | @"q": @"long long",
59 |
60 | @"C": @"unsigned char",
61 | @"I": @"unsigned int",
62 | @"S": @"unsigned short",
63 | @"L": @"unsigned long",
64 | @"Q": @"unsigned long long",
65 |
66 | @"f": @"float",
67 | @"d": @"double",
68 | @"B": @"bool",
69 | @"v": @"void",
70 | @"*": @"char *",
71 | @"@": @"id",
72 | @"#": @"Class",
73 | @":": @"SEL"
74 | };
75 |
76 | if(encodeMap[code]){
77 | return encodeMap[code];
78 | }else if([code characterAtIndex:0] == '@'){
79 | if([code characterAtIndex:1] == '?'){
80 | return code;
81 | }else if([code characterAtIndex:2] == '<'){
82 | return [NSString stringWithFormat:@"id%@", [[code substringWithRange:NSMakeRange(2, code.length-3)] stringByReplacingOccurrencesOfString:@"><" withString:@", "]];
83 | }else{
84 | return [NSString stringWithFormat:@"%@ *", [code substringWithRange:NSMakeRange(2, code.length-3)]];
85 | }
86 | }else if([code characterAtIndex:0] == '^'){
87 | return [NSString stringWithFormat:@"%@ *", decode([code substringFromIndex:1])];
88 | }
89 | return code;
90 | }
91 |
92 | NSString* pvc(){
93 | return [[[UIWindow performSelector:@selector(keyWindow)] performSelector:@selector(rootViewController)] performSelector:@selector(_printHierarchy)];
94 | }
95 |
96 | NSString* pviews(){
97 | return [[[UIApplication sharedApplication] keyWindow] performSelector:@selector(recursiveDescription)];
98 | }
99 |
100 | NSString* pactions(vm_address_t address){
101 | NSMutableString* result = [NSMutableString new];
102 | UIControl* control = (__bridge UIControl*)(void*)address;
103 | NSArray* targets = [[control allTargets] allObjects];
104 | for (id item in targets) {
105 | NSArray* actions = [control actionsForTarget:item forControlEvent:0];
106 | [result appendFormat:@"<%s: 0x%lx>: %@\n", object_getClassName(item), (unsigned long)item, [actions componentsJoinedByString:@","]];
107 | }
108 | return result;
109 | }
110 |
111 | NSString* pblock(vm_address_t address){
112 | struct Block_literal_1 real = *((struct Block_literal_1 *)(void*)address);
113 | NSMutableDictionary *dict = [NSMutableDictionary dictionary];
114 | [dict setObject:[NSNumber numberWithLong:(long)real.invoke] forKey:@"invoke"];
115 | if (real.flags & BLOCK_HAS_SIGNATURE) {
116 | char *signature;
117 | if (real.flags & BLOCK_HAS_COPY_DISPOSE) {
118 | signature = (char *)(real.descriptor)->signature;
119 | } else {
120 | signature = (char *)(real.descriptor)->copy_helper;
121 | }
122 |
123 | NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:signature];
124 | NSMutableArray *types = [NSMutableArray array];
125 |
126 | [types addObject:[NSString stringWithUTF8String:(char *)[sig methodReturnType]]];
127 |
128 | for (NSUInteger i = 0; i < sig.numberOfArguments; i++) {
129 | char *type = (char *)[sig getArgumentTypeAtIndex:i];
130 | [types addObject:[NSString stringWithUTF8String:type]];
131 | }
132 |
133 | [dict setObject:types forKey:@"signature"];
134 | }
135 |
136 | NSMutableArray* sigArr = dict[@"signature"];
137 |
138 | if(!sigArr){
139 | return [NSString stringWithFormat:@"Imp: 0x%lx", [dict[@"invoke"] longValue]];
140 | }else{
141 | NSMutableString* sig = [NSMutableString stringWithFormat:@"%@ ^(", decode(sigArr[0])];
142 | for (int i = 2; i < sigArr.count; i++) {
143 | if(i == sigArr.count - 1){
144 | [sig appendFormat:@"%@", decode(sigArr[i])];
145 | }else{
146 | [sig appendFormat:@"%@ ,", decode(sigArr[i])];
147 | }
148 | }
149 | [sig appendString:@");"];
150 | return [NSString stringWithFormat:@"Imp: 0x%lx Signature: %s", [dict[@"invoke"] longValue], [sig UTF8String]];
151 | }
152 | }
153 |
154 | struct CYChoice {
155 | std::set query_;
156 | std::set results_;
157 | };
158 |
159 | struct CYObjectStruct {
160 | Class isa_;
161 | };
162 |
163 | static void choose_(task_t task, void *baton, unsigned type, vm_range_t *ranges, unsigned count) {
164 | CYChoice *choice(reinterpret_cast(baton));
165 |
166 | for (unsigned i(0); i != count; ++i) {
167 | vm_range_t &range(ranges[i]);
168 | void *data(reinterpret_cast(range.address));
169 | size_t size(range.size);
170 |
171 | if (size < sizeof(CYObjectStruct))
172 | continue;
173 |
174 | uintptr_t *pointers(reinterpret_cast(data));
175 | #ifdef __arm64__
176 | Class isa = (__bridge Class)((void *)(pointers[0] & 0x1fffffff8));
177 | #else
178 | Class isa =(__bridge Class)(void *)pointers[0];
179 | #endif
180 | std::set::const_iterator result(choice->query_.find(isa));
181 | if (result == choice->query_.end())
182 | continue;
183 |
184 | size_t needed(class_getInstanceSize(*result));
185 | // XXX: if (size < needed)
186 |
187 | size_t boundary(496);
188 | #ifdef __LP64__
189 | boundary *= 2;
190 | #endif
191 | if ((needed <= boundary && (needed + 15) / 16 * 16 != size) || (needed > boundary && (needed + 511) / 512 * 512 != size))
192 | continue;
193 | choice->results_.insert((__bridge id)(data));
194 | }
195 | }
196 |
197 | static Class *CYCopyClassList(size_t &size) {
198 | size = objc_getClassList(NULL, 0);
199 | Class *data(reinterpret_cast(malloc(sizeof(Class) * size)));
200 |
201 | for (;;) {
202 | size_t writ(objc_getClassList(data, (int)size));
203 | if (writ <= size) {
204 | size = writ;
205 | return data;
206 | }
207 |
208 | Class *copy(reinterpret_cast(realloc(data, sizeof(Class) * writ)));
209 | if (copy == NULL) {
210 | free(data);
211 | return NULL;
212 | }
213 |
214 | data = copy;
215 | size = writ;
216 | }
217 | }
218 |
219 | static kern_return_t CYReadMemory(task_t task, vm_address_t address, vm_size_t size, void **data) {
220 | *data = reinterpret_cast(address);
221 | return KERN_SUCCESS;
222 | }
223 |
224 | NSArray* choose_inner(const char * classname){
225 |
226 | Class _class = NSClassFromString([NSString stringWithUTF8String:classname]);
227 |
228 | vm_address_t *zones = NULL;
229 | unsigned size = 0;
230 | //获取所有的zone信息 堆上的区域
231 | kern_return_t error = malloc_get_all_zones(mach_task_self(), &CYReadMemory, &zones, &size);
232 | assert(error == KERN_SUCCESS);
233 |
234 | size_t number;
235 | Class *classes(CYCopyClassList(number));
236 | assert(classes != NULL);
237 |
238 | CYChoice choice;
239 |
240 | //找到目标Class
241 | for (size_t i(0); i != number; ++i)
242 | for (Class current(classes[i]); current != Nil; current = class_getSuperclass(current))
243 | if (current == _class) {
244 | choice.query_.insert(classes[i]);
245 | break;
246 | }
247 |
248 | for (unsigned i(0); i != size; ++i) {
249 | const malloc_zone_t *zone(reinterpret_cast(zones[i]));
250 | if (zone == NULL || zone->introspect == NULL)
251 | continue;
252 |
253 | //枚举堆上的对象
254 | zone->introspect->enumerator(mach_task_self(), &choice, MALLOC_PTR_IN_USE_RANGE_TYPE, zones[i], &CYReadMemory, &choose_);
255 | }
256 | NSMutableArray * result = [[NSMutableArray alloc] init];
257 |
258 | for (auto iter = choice.results_.begin(); iter != choice.results_.end(); iter++) {
259 | [result addObject:(id)*iter];
260 | }
261 | return result;
262 | }
263 |
264 | NSString* choose(const char* classname){
265 | NSMutableString* result = [NSMutableString new];
266 | NSArray* results = choose_inner(classname);
267 | [result appendFormat:@"Find %lu instance objects in memory!\n" , (unsigned long)results.count];
268 | for (id item in results) {
269 | [result appendFormat:@"<%s: 0x%llx>\n", object_getClassName(item), (long long)item];
270 | }
271 | return result;
272 | }
273 |
274 | NSString* methods(const char * classname){
275 | return [objc_getClass(classname) performSelector:@selector(_shortMethodDescription)];
276 | }
277 |
278 | NSString* ivars(vm_address_t address){
279 | id target = (__bridge id)(void*)address;
280 | return [target performSelector:@selector(_ivarDescription)];
281 | }
282 |
283 | char * protection_bits_to_rwx (vm_prot_t p){
284 | static char returned[4];
285 |
286 | returned[0] = (p & VM_PROT_READ ? 'r' : '-');
287 | returned[1] = (p & VM_PROT_WRITE ? 'w' : '-');
288 | returned[2] = (p & VM_PROT_EXECUTE ? 'x' : '-');
289 | returned[3] = '\0';
290 |
291 | // memory leak here. No biggy
292 | return (strdup(returned));
293 | }
294 |
295 | const char * unparse_inheritance (vm_inherit_t i){
296 | switch (i){
297 | case VM_INHERIT_SHARE:
298 | return "share";
299 | case VM_INHERIT_COPY:
300 | return "copy";
301 | case VM_INHERIT_NONE:
302 | return "none";
303 | default:
304 | return "???";
305 | }
306 | }
307 |
308 | char * behavior_to_text (vm_behavior_t b){
309 | switch (b){
310 | case VM_BEHAVIOR_DEFAULT: return((char*)"default");
311 | case VM_BEHAVIOR_RANDOM: return((char*)"random");
312 | case VM_BEHAVIOR_SEQUENTIAL: return((char*)"fwd-seq");
313 | case VM_BEHAVIOR_RSEQNTL: return((char*)"rev-seq");
314 | case VM_BEHAVIOR_WILLNEED: return((char*)"will-need");
315 | case VM_BEHAVIOR_DONTNEED: return((char*)"will-need");
316 | case VM_BEHAVIOR_FREE: return((char*)"free-nowb");
317 | case VM_BEHAVIOR_ZERO_WIRED_PAGES: return((char*)"zero-wire");
318 | case VM_BEHAVIOR_REUSABLE: return((char*)"reusable");
319 | case VM_BEHAVIOR_REUSE: return((char*)"reuse");
320 | case VM_BEHAVIOR_CAN_REUSE: return((char*)"canreuse");
321 | default: return ((char*)"?");
322 | }
323 | }
324 |
325 | __BEGIN_DECLS
326 |
327 | extern kern_return_t mach_vm_region
328 | (
329 | vm_map_t target_task,
330 | mach_vm_address_t *address,
331 | mach_vm_size_t *size,
332 | vm_region_flavor_t flavor,
333 | vm_region_info_t info,
334 | mach_msg_type_number_t *infoCnt,
335 | mach_port_t *object_name
336 | );
337 |
338 | __END_DECLS
339 |
340 | NSString* vmmap(){
341 | vm_region_basic_info_data_t info, prev_info;
342 | mach_vm_address_t address = 1, prev_address;
343 | mach_vm_size_t size, prev_size;
344 | mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
345 | mach_port_t object_name;
346 |
347 | int nsubregions = 0;
348 | kern_return_t kr = mach_vm_region(mach_task_self(), &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object_name);
349 |
350 | NSMutableString* result = [[NSMutableString alloc] init];
351 |
352 | if(kr != KERN_SUCCESS){
353 | [result appendFormat:@"mach_vm_region: Error %d - %s", kr, mach_error_string(kr)];
354 | return [result copy];
355 | }
356 |
357 | //保存之前查到的info
358 | memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t));
359 | prev_address = address;
360 | prev_size = size;
361 | nsubregions = 1;
362 |
363 | while (true) {
364 | int print = 0, done = 0;
365 |
366 | address = prev_address + prev_size;
367 |
368 | if (address == 0){
369 | print = done = 1;
370 | }
371 |
372 | if (!done){
373 | kr = mach_vm_region (mach_task_self(), &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object_name);
374 |
375 | if (kr != KERN_SUCCESS){
376 | [result appendFormat:@"mach_vm_region failed for address %llu - Error: %x\n",address, (kr)];
377 | print = done = 1;
378 | }
379 | }
380 |
381 | //等于才是连续的内存,不等于才打印
382 | if (address != prev_address + prev_size)
383 | print = 1;
384 |
385 | //或者权限信息改变了也打印
386 | if ((info.protection != prev_info.protection)
387 | || (info.max_protection != prev_info.max_protection)
388 | || (info.inheritance != prev_info.inheritance)
389 | || (info.shared != prev_info.reserved)
390 | || (info.reserved != prev_info.reserved))
391 | print = 1;
392 |
393 | if (print){
394 | char *print_size_unit = NULL;
395 |
396 | mach_vm_size_t print_size = prev_size;
397 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"K"; }
398 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"M"; }
399 | if (print_size > 1024) { print_size /= 1024; print_size_unit = (char*)"G"; }
400 |
401 | [result appendFormat:@" %p-%p [%llu%s](%s/%s; %s, %s, %s) %s",
402 | (void*)(prev_address),
403 | (void*)(prev_address + prev_size),
404 | print_size,
405 | print_size_unit,
406 | protection_bits_to_rwx (prev_info.protection),
407 | protection_bits_to_rwx (prev_info.max_protection),
408 | unparse_inheritance (prev_info.inheritance),
409 | prev_info.shared ? "shared" : "private",
410 | prev_info.reserved ? "reserved" : "not-reserved",
411 | behavior_to_text (prev_info.behavior)];
412 |
413 | if (nsubregions > 1)
414 | [result appendFormat:@" (%d sub-regions)", nsubregions];
415 |
416 | [result appendFormat:@"\n"];
417 | prev_address = address;
418 | prev_size = size;
419 | memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_t));
420 | nsubregions = 1;
421 | }else{
422 | prev_size += size;
423 | nsubregions++;
424 | }
425 |
426 | if (done)
427 | break;
428 | }
429 | return [result copy];
430 | }
431 |
432 |
433 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/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 |
--------------------------------------------------------------------------------
/ELWeChat/ELWeChatDylib/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 |
--------------------------------------------------------------------------------
/ELWeChat/LatestBuild:
--------------------------------------------------------------------------------
1 | /Users/cuishengyu/Library/Developer/Xcode/DerivedData/ELWeChat-beoeidmupgcmtvctpgnydiaxgohg/Build/Products/Debug-iphoneos
--------------------------------------------------------------------------------
/ELWeChat/MUHook/MUHRuntime.h:
--------------------------------------------------------------------------------
1 | //
2 | // MUHRuntime.h
3 | // MUHookDemo
4 | //
5 | // Created by Shuang Wu on 2017/3/30.
6 | // Copyright © 2017年 unique. All rights reserved.
7 | //
8 |
9 | #ifndef MUHRuntime_h
10 | #define MUHRuntime_h
11 |
12 | #define MUHDefinedSend(var, returnType, argsTypes...) returnType (* var )(id, SEL, ##argsTypes) = (returnType (*)(id,SEL, ##argsTypes))objc_msgSend
13 | #define MUHMakeMsgSend(returnType, argsTypes...) ((returnType (*)(id,SEL, ##argsTypes))objc_msgSend)
14 | #define MUHCallMsgSend(msgsend, obj, sel, args...) ( msgsend (obj, @selector(sel), ##args))
15 |
16 | #endif /* MUHRuntime_h */
17 |
--------------------------------------------------------------------------------
/ELWeChat/MUHook/MUHook.h:
--------------------------------------------------------------------------------
1 | //
2 | // MUHook.h
3 | //
4 | // Created by Shuang Wu on 2017/2/9.
5 | //
6 | // Copyright Shuang Wu 2017
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "MUHRuntime.h"
13 | #import "NSObject+MUHook.h"
14 |
15 | #pragma mark - Main
16 |
17 | #define MUHMain static __attribute__((constructor)) initialize
18 |
19 | #pragma mark - Quick Statement
20 |
21 | #define MUHClass(c) ((Class)(((c *)0x0), objc_getClass(#c)))
22 |
23 | #define MUHSendClassMsg(c, factory) [MUHClass(c) factory]
24 |
25 | #define MUHAlloc(c) ((c *)[MUHClass(c) alloc])
26 |
27 | #define MUHAllocInitWith(c, init) [MUHAlloc(c) init]
28 |
29 | #define MUHGetObjectAsct(obj, name) MUGetAsctValue(obj, #name)
30 | #define MUHSetObjectAsct(obj, name, value, mm) MUSetAsctValue(obj, #name, value, MUHAssosiationType_##mm)
31 |
32 | #define MUHGetSelfAsct(name) MUGetAsctValue(self, #name)
33 | #define MUHSetSelfAsct(name, value, mm) MUSetAsctValue(self, #name, value, MUHAssosiationType_##mm)
34 |
35 | #define MUHGetObjectIvar(obj, ivar) MUGetInstanceIvar(obj, #ivar)
36 | #define MUHSetObjectIvar(obj, ivar, value) MUSetInstanceIvar(obj, #ivar, value)
37 |
38 | #define MUHGetSelfIvar(ivar) MUGetInstanceIvar(self, #ivar)
39 | #define MUHSetSelfIvar(ivar, value) MUSetInstanceIvar(self, #ivar, value)
40 |
41 | #define MUHInitClass(c) init_##c ()
42 |
43 | #pragma mark - Implementation
44 |
45 | #define MUHInstanceImplementation(c, name, returnType, args...) \
46 | static returnType (*_unique_objc_ori$##c##$##name) ( c * self, SEL _cmd, ##args );\
47 | static returnType _unique_objc_new$##c##$##name ( c * self, SEL _cmd, ##args )
48 |
49 | #define MUHClassImplementation(c, name, returnType, args...) \
50 | static returnType (*_unique_objc_ori$##c##$##name) ( __strong const Class self, SEL _cmd, ##args );\
51 | static returnType _unique_objc_new$##c##$##name ( __strong const Class self, SEL _cmd, ##args )
52 |
53 | #define MUHSymbolImplementation(symbol, returnType, args...) \
54 | static returnType (*_unique_symbol_ori$##symbol)(args);\
55 | static returnType _unique_symbol_new$##symbol (args)
56 |
57 | #pragma mark - Execute Orig or Super
58 |
59 | #define MUHOrig(c, name, args...) (((c *)0x0),(!_unique_objc_ori$##c##$##name?0:_unique_objc_ori$##c##$##name (self, _cmd, ##args)))
60 | #define MUHSuper(c, name, args...) (((c *)0x0),(!_unique_objc_ori$##c##$##name?0:_unique_objc_ori$##c##$##name (self, _cmd, ##args)))
61 |
62 | #define MUHSymbolOrig(symbol, args...) _unique_symbol_ori$##symbol(args)
63 |
64 | #pragma mark - Hook
65 |
66 | #define MUHHookInstanceMessage(c, name, sel) \
67 | {(c *)0x0;}MUHookInstanceMessageEx(objc_getClass( #c ), @selector(sel), (IMP)&_unique_objc_new$##c##$##name, (IMP*)&_unique_objc_ori$##c##$##name);
68 |
69 | #define MUHHookClassMessage(c, name, sel) \
70 | {(c *)0x0;}MUHookClassMessageEx(objc_getClass( #c ), @selector(sel), (IMP)&_unique_objc_new$##c##$##name, (IMP*)&_unique_objc_ori$##c##$##name);
71 |
72 | #define MUHHookSymbolFunction(symbol) \
73 | MURebindSymbol(#symbol, _unique_symbol_new$##symbol, (void *)&_unique_symbol_ori$##symbol)
74 |
75 | #pragma mark - Create
76 |
77 | #define MUHCreateClass(c, sc) {(c *)0x0;(sc *)0x0;}MUCreateClass(#c, #sc)
78 |
79 | #define MUHAddInstanceMethod(c, name, sel, encode) \
80 | {(c *)0x0;}MUAddInstanceMessageEx(objc_getClass( #c ), @selector(sel), (IMP)&_unique_objc_new$##c##$##name, #encode , (IMP*)&_unique_objc_ori$##c##$##name)
81 |
82 | #define MUHAddClassMethod(c, name, sel, encode) \
83 | {(c *)0x0;}MUAddClassMessageEx(objc_getMetaClass( #c ), @selector(sel), (IMP)&_unique_objc_new$##c##$##name, #encode , (IMP*)&_unique_objc_ori$##c##$##name)
84 |
85 | #pragma mark - Function
86 |
87 | Class MUCreateClass(const char *className, const char *superClass);
88 |
89 | void MUHookInstanceMessageEx(Class _class, SEL sel, IMP imp, IMP *result);
90 |
91 | void MUHookClassMessageEx(Class _class, SEL sel, IMP imp, IMP *result);
92 |
93 | void MUAddInstanceMessageEx(Class _class, SEL sel, IMP imp, const char *typeEncoding, IMP *result);
94 |
95 | void MUAddClassMessageEx(Class _class, SEL sel, IMP imp, const char *typeEncoding, IMP *result);
96 |
97 | id MUGetAsctValue(id obj, const char *name);
98 | void MUSetAsctValue(id obj, const char *name, id value, MUHAssosiationType memory);
99 |
100 | id MUGetInstanceIvar(id obj, const char *ivar);
101 | void MUSetInstanceIvar(id obj, const char *ivar, id value);
102 |
103 | Class MUAllocateClassPair(Class superClass, const char *className, size_t extraBytes);
104 |
105 | void MURegisterClassPair(Class _class);
106 |
107 | int MURebindSymbol(const char *symbol, void *imp, void **result);
108 |
--------------------------------------------------------------------------------
/ELWeChat/MUHook/MUHook.m:
--------------------------------------------------------------------------------
1 | //
2 | // MUHook.m
3 | //
4 | // Created by Shuang Wu on 2017/2/9.
5 | //
6 | // Copyright Shuang Wu 2017
7 | //
8 |
9 | #import "MUHook.h"
10 | #import "fishhook.h"
11 |
12 | Class MUCreateClass(const char *className, const char *superClass) {
13 | Class _superClass = superClass ? objc_getClass(superClass) : objc_getClass("NSObject");
14 | Class _class = objc_allocateClassPair(_superClass, className, 0);
15 | objc_registerClassPair(_class);
16 | return _class;
17 | }
18 |
19 | void MUHookInstanceMessageEx(Class _class, SEL sel, IMP imp, IMP *result) {
20 | Method ori_method = class_getInstanceMethod(_class, sel);
21 | const char *typeEncoding = method_getTypeEncoding(ori_method);
22 | if(!class_addMethod(_class, sel, imp, typeEncoding)) {
23 | // Replace implementation and return old implementation
24 | *result = method_getImplementation(ori_method);
25 | method_setImplementation(ori_method, imp);
26 | } else {
27 | // Add implementation and return super implementation
28 | Class superClass = class_getSuperclass(_class);
29 | ori_method = class_getInstanceMethod(superClass, sel);
30 | *result = method_getImplementation(ori_method);
31 | }
32 | }
33 |
34 | void MUHookClassMessageEx(Class _class, SEL sel, IMP imp, IMP *result) {
35 | MUHookInstanceMessageEx(object_getClass(_class), sel, imp, result);
36 | }
37 |
38 | id MUGetAsctValue(id obj, const char*name) {
39 | return [obj muh_getAssosiationForKey:[NSString stringWithUTF8String:name]];
40 | }
41 |
42 | void MUSetAsctValue(id obj, const char *name, id value, MUHAssosiationType memory) {
43 | [obj muh_setAssosiationObject:value forKey:[NSString stringWithUTF8String:name] type:memory];
44 | }
45 |
46 | void MUAddInstanceMessageEx(Class _class, SEL sel, IMP imp, const char *typeEncoding, IMP *result) {
47 | if (class_addMethod(_class, sel, imp, typeEncoding)) {
48 | Class superClass = class_getSuperclass(_class);
49 | Method ori_method = class_getInstanceMethod(superClass, sel);
50 | *result = ori_method ? method_getImplementation(ori_method) : NULL;
51 | } else {
52 | Method ori_method = class_getInstanceMethod(_class, sel);
53 | *result = method_getImplementation(ori_method);
54 | method_setImplementation(ori_method, imp);
55 | }
56 | }
57 |
58 | void MUAddClassMessageEx(Class _class, SEL sel, IMP imp, const char *typeEncoding, IMP *result) {
59 | MUAddInstanceMessageEx(object_getClass(_class), sel, imp, typeEncoding, result);
60 | }
61 |
62 | Class MUAllocateClassPair(Class superClass, const char *className, size_t extraBytes) {
63 | superClass = superClass ? superClass : objc_getClass("NSObject");
64 | return objc_allocateClassPair(superClass, className, extraBytes);
65 | }
66 |
67 | void MURegisterClassPair(Class _class) {
68 | objc_registerClassPair(_class);
69 | }
70 |
71 | void MUSetInstanceIvar(id obj, const char *ivar, id value) {
72 | object_setIvar(obj, class_getInstanceVariable([obj class], ivar), value);
73 | }
74 |
75 | id MUGetInstanceIvar(id obj, const char *ivar) {
76 | return object_getIvar(obj, class_getInstanceVariable([obj class], ivar));
77 | }
78 |
79 | int MURebindSymbol(const char *symbol, void *imp, void **result) {
80 | return rebind_symbols((struct rebinding[1]){{symbol, imp, (void *)result}}, 1);
81 | }
82 |
--------------------------------------------------------------------------------
/ELWeChat/MUHook/NSObject+MUHook.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MUHook.h
3 | // MUHookDemo
4 | //
5 | // Created by 吴双 on 2018/4/16.
6 | // Copyright © 2018年 unique. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSUInteger, MUHAssosiationType) {
12 | MUHAssosiationType_strong,
13 | MUHAssosiationType_assign,
14 | MUHAssosiationType_copy,
15 | MUHAssosiationType_weak,
16 | };
17 |
18 | @interface NSObject (MUHook)
19 |
20 | - (void)muh_setAssosiationObject:(id)object forKey:(NSString *)key type:(MUHAssosiationType)type;
21 |
22 | - (id)muh_getAssosiationForKey:(NSString *)key;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ELWeChat/MUHook/NSObject+MUHook.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MUHook.m
3 | // MUHookDemo
4 | //
5 | // Created by 吴双 on 2018/4/16.
6 | // Copyright © 2018年 unique. All rights reserved.
7 | //
8 |
9 | #import "NSObject+MUHook.h"
10 | #import
11 |
12 | typedef id(^PackageBlock)(void);
13 |
14 | @implementation NSObject (MUHook)
15 |
16 | - (void)muh_setAssosiationObject:(id)object forKey:(NSString *)key type:(MUHAssosiationType)type {
17 | PackageBlock block;
18 | switch (type) {
19 | case MUHAssosiationType_strong: {
20 | block = ^id() {
21 | return object;
22 | };
23 | break;
24 | }
25 | case MUHAssosiationType_copy: {
26 | object = [object copy];
27 | block = ^id() {
28 | return object;
29 | };
30 | break;
31 | }
32 | case MUHAssosiationType_assign: {
33 | __unsafe_unretained id blockObj = object;
34 | block = ^id() {
35 | return blockObj;
36 | };
37 | break;
38 | }
39 | case MUHAssosiationType_weak: {
40 | __weak id blockObj = object;
41 | block = ^id() {
42 | return blockObj;
43 | };
44 | break;
45 | }
46 | default:
47 | break;
48 | }
49 | objc_setAssociatedObject(self, (const void *)key.hash, block, OBJC_ASSOCIATION_RETAIN);
50 | }
51 |
52 | - (id)muh_getAssosiationForKey:(NSString *)key {
53 | PackageBlock block = objc_getAssociatedObject(self, (const void *)key.hash);
54 | return block();
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/ELWeChat/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 |
3 | source 'https://gitee.com/cuiyu8580/CYPodspec.git'
4 |
5 |
6 |
7 | platform :ios, '9.0'
8 |
9 | use_frameworks!
10 | target 'ELWeChatDylib' do
11 |
12 | pod 'YYModel'
13 |
14 | pod 'CYMHUD'
15 |
16 |
17 | end
18 |
--------------------------------------------------------------------------------
/ELWeChat/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CYMHUD (0.1.0):
3 | - MBProgressHUD (= 1.1.0)
4 | - MBProgressHUD (1.1.0)
5 | - YYModel (1.0.4)
6 |
7 | DEPENDENCIES:
8 | - CYMHUD
9 | - YYModel
10 |
11 | SPEC REPOS:
12 | https://gitee.com/cuiyu8580/CYPodspec.git:
13 | - CYMHUD
14 | https://github.com/cocoapods/specs.git:
15 | - MBProgressHUD
16 | - YYModel
17 |
18 | SPEC CHECKSUMS:
19 | CYMHUD: c6c0a363e4c5834716c1750c34109773efd3a950
20 | MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
21 | YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
22 |
23 | PODFILE CHECKSUM: a655ea8011c81b70a8b43404d5879d7858a99400
24 |
25 | COCOAPODS: 1.6.0.beta.1
26 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/CYMHUD/CYMHUD/Classes/HUD/HUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // HUD.h
3 | // geliwuliu
4 | //
5 | // Created by Eli on 2017/5/5.
6 | // Copyright © 2017年 Eli. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MBProgressHUD.h"
11 |
12 |
13 | #define HUDAfterDelayTime 2.0
14 |
15 | typedef NS_ENUM(NSInteger,HudProgressMode){
16 | HudProgressModeOnlyText, //文字
17 | HudProgressModeLoading, //加载菊花
18 | HudProgressModeCircle, //加载环形
19 | HudProgressModeCustomAnimation, //自定义加载动画(序列帧实现)
20 | HudProgressModeSuccess, //成功
21 | HudProgressModeCustomerImage //自定义图片
22 |
23 | };
24 |
25 | @interface HUD : NSObject
26 |
27 | /*=============================== 属性 ================================================*/
28 |
29 | @property (nonatomic,strong) MBProgressHUD *hud;
30 |
31 |
32 | /*============================= 本类自己调用 方法 =====================================*/
33 |
34 | + (instancetype)shareInstance;
35 |
36 | //显示
37 | + (void)show:(NSString *)msg inView:(UIView *)view mode:(HudProgressMode)myMode;
38 |
39 |
40 | /*========================= 自己可调用 方法 ================================*/
41 |
42 | //显示提示
43 | + (void)showMessage:(NSString *)msg inView:(UIView *)view;
44 |
45 | //显示提示(N秒后消失)
46 | + (void)showMessage:(NSString *)msg inView:(UIView *)view afterDelayTime:(NSInteger)delay;
47 |
48 | //在最上层显示 - 不需要指定showview
49 | + (void)showMsgWithoutView:(NSString *)msg;
50 |
51 |
52 | //显示进度(菊花)
53 | + (void)showProgress:(NSString *)msg inView:(UIView *)view;
54 |
55 | //显示自定义环形转圈圈 需要修改下MB
56 | + (void)showProgressCircleNoValue:(NSString *)msg inView:(UIView *)view ;
57 |
58 | //显示成功提示
59 | + (void)showSuccess:(NSString *)msg inview:(UIView *)view;
60 |
61 | //显示提示、带静态图片,比如失败,用失败图片即可,警告用警告图片等
62 | + (void)showMsgWithImage:(NSString *)msg imageName:(NSString *)imageName inview:(UIView *)view;
63 |
64 | //显示自定义动画(自定义动画序列帧 找UI做就可以了)
65 | + (void)showCustomAnimation:(NSString *)msg withImgArry:(NSArray *)imgArry inview:(UIView *)view;
66 |
67 | //显示进度(转圈-要处理数据加载进度)
68 | + (MBProgressHUD *)showProgressCircle:(NSString *)msg inView:(UIView *)view;
69 |
70 | //隐藏
71 | + (void)hide;
72 |
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/CYMHUD/CYMHUD/Classes/HUD/HUD.m:
--------------------------------------------------------------------------------
1 | //
2 | // HUD.m
3 | // geliwuliu
4 | //
5 | // Created by Eli on 2017/5/5.
6 | // Copyright © 2017年 Eli. All rights reserved.
7 | //
8 |
9 | #import "HUD.h"
10 |
11 | #define UIColorFromHex(s) [UIColor colorWithRed:(((s & 0xFF0000) >> 16))/255.0 green:(((s &0xFF00) >>8))/255.0 blue:((s &0xFF))/255.0 alpha:1.0]
12 |
13 | @implementation HUD
14 |
15 | + (instancetype)shareInstance{
16 |
17 | static HUD *instance = nil;
18 | static dispatch_once_t onceToken;
19 | dispatch_once(&onceToken, ^{
20 | instance = [[HUD alloc] init];
21 | });
22 |
23 | return instance;
24 | }
25 |
26 | + (void)show:(NSString *)msg inView:(UIView *)view mode:(HudProgressMode)myMode{
27 |
28 | [self show:msg inView:view mode:myMode customImgView:nil];
29 | }
30 |
31 | + (void)show:(NSString *)msg inView:(UIView *)view mode:(HudProgressMode)myMode customImgView:(UIImageView *)customImgView{
32 | //如果已有弹框,先消失
33 | if ([HUD shareInstance].hud != nil) {
34 | [[HUD shareInstance].hud hideAnimated:YES];
35 | [HUD shareInstance].hud = nil;
36 | }
37 |
38 |
39 | [HUD shareInstance].hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
40 |
41 | [HUD shareInstance].hud.label.text = msg;
42 |
43 |
44 | [HUD shareInstance].hud.bezelView.backgroundColor = UIColorFromHex(0xBEBEBE);
45 |
46 |
47 | switch ((NSInteger)myMode) {
48 | case HudProgressModeOnlyText: //仅文字
49 | [HUD shareInstance].hud.mode = MBProgressHUDModeText;
50 | break;
51 |
52 | case HudProgressModeLoading: //系统菊花
53 | [HUD shareInstance].hud.mode = MBProgressHUDModeIndeterminate;
54 | break;
55 |
56 | case HudProgressModeCircle:{ //环形
57 |
58 |
59 |
60 | break;
61 | }
62 | case HudProgressModeCustomerImage://自定义图片
63 | [HUD shareInstance].hud.mode = MBProgressHUDModeCustomView;
64 | [HUD shareInstance].hud.customView = customImgView;
65 | break;
66 |
67 | case HudProgressModeCustomAnimation://自定义加载动画(序列帧实现)
68 | //这里设置动画的背景色
69 | [HUD shareInstance].hud.bezelView.color = [UIColor yellowColor];
70 |
71 |
72 | [HUD shareInstance].hud.mode = MBProgressHUDModeCustomView;
73 | [HUD shareInstance].hud.customView = customImgView;
74 |
75 | break;
76 |
77 | case HudProgressModeSuccess://成功
78 | [HUD shareInstance].hud.mode = MBProgressHUDModeCustomView;
79 | [HUD shareInstance].hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"success"]];
80 | break;
81 |
82 | default:
83 | break;
84 | }
85 |
86 |
87 |
88 | }
89 |
90 |
91 | + (void)hide{
92 | if ([HUD shareInstance].hud != nil) {
93 | [[HUD shareInstance].hud hideAnimated:YES];
94 | }
95 | }
96 |
97 |
98 | + (void)showMessage:(NSString *)msg inView:(UIView *)view{
99 | [self show:msg inView:view mode:HudProgressModeOnlyText];
100 | [[HUD shareInstance].hud hideAnimated:YES afterDelay:HUDAfterDelayTime];
101 | }
102 |
103 |
104 |
105 | + (void)showMessage:(NSString *)msg inView:(UIView *)view afterDelayTime:(NSInteger)delay{
106 | [self show:msg inView:view mode:HudProgressModeOnlyText];
107 | [[HUD shareInstance].hud hideAnimated:YES afterDelay:delay];
108 | }
109 |
110 | + (void)showSuccess:(NSString *)msg inview:(UIView *)view{
111 | [self show:msg inView:view mode:HudProgressModeSuccess];
112 | [[HUD shareInstance].hud hideAnimated:YES afterDelay:HUDAfterDelayTime];
113 |
114 | }
115 |
116 | + (void)showMsgWithImage:(NSString *)msg imageName:(NSString *)imageName inview:(UIView *)view{
117 | UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
118 | [self show:msg inView:view mode:HudProgressModeCustomerImage customImgView:img];
119 | [[HUD shareInstance].hud hideAnimated:YES afterDelay:HUDAfterDelayTime];
120 | }
121 |
122 |
123 | + (void)showProgress:(NSString *)msg inView:(UIView *)view{
124 | [self show:msg inView:view mode:HudProgressModeLoading];
125 | }
126 |
127 | + (MBProgressHUD *)showProgressCircle:(NSString *)msg inView:(UIView *)view{
128 | if (view == nil) view = (UIView*)[UIApplication sharedApplication].delegate.window;
129 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
130 | hud.mode = MBProgressHUDModeAnnularDeterminate;
131 | hud.detailsLabel.text = msg;
132 | return hud;
133 |
134 |
135 | }
136 |
137 | + (void)showProgressCircleNoValue:(NSString *)msg inView:(UIView *)view{
138 | [self show:msg inView:view mode:HudProgressModeCircle];
139 |
140 | }
141 |
142 |
143 | +(void)showMsgWithoutView:(NSString *)msg{
144 | UIWindow *view = [[UIApplication sharedApplication].windows lastObject];
145 | [self show:msg inView:view mode:HudProgressModeOnlyText];
146 | [[HUD shareInstance].hud hideAnimated:YES afterDelay:HUDAfterDelayTime];
147 |
148 | }
149 |
150 | + (void)showCustomAnimation:(NSString *)msg withImgArry:(NSArray *)imgArry inview:(UIView *)view{
151 |
152 | UIImageView *showImageView = [[UIImageView alloc] init];
153 | showImageView.animationImages = imgArry;
154 | [showImageView setAnimationRepeatCount:0];
155 | [showImageView setAnimationDuration:(imgArry.count + 1) * 0.075];
156 | [showImageView startAnimating];
157 |
158 | [self show:msg inView:view mode:HudProgressModeCustomAnimation customImgView:showImageView];
159 | }
160 |
161 |
162 |
163 |
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/CYMHUD/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 cuiyu8580@126.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/CYMHUD/README.md:
--------------------------------------------------------------------------------
1 | # CYMHUD
2 |
3 | [](https://travis-ci.org/cuiyu8580@126.com/CYMHUD)
4 | [](http://cocoapods.org/pods/CYMHUD)
5 | [](http://cocoapods.org/pods/CYMHUD)
6 | [](http://cocoapods.org/pods/CYMHUD)
7 |
8 | ## Example
9 |
10 | To run the example project, clone the repo, and run `pod install` from the Example directory first.
11 |
12 | ## Requirements
13 |
14 | ## Installation
15 |
16 | CYMHUD is available through [CocoaPods](http://cocoapods.org). To install
17 | it, simply add the following line to your Podfile:
18 |
19 | ```ruby
20 | pod 'CYMHUD'
21 | ```
22 |
23 | ## Author
24 |
25 | cuiyu8580@126.com, cuiyu8580@126.com
26 |
27 | ## License
28 |
29 | CYMHUD is available under the MIT license. See the LICENSE file for more info.
30 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/MBProgressHUD/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2009-2016 Matej Bukovinski
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/ELWeChat/Pods/MBProgressHUD/README.mdown:
--------------------------------------------------------------------------------
1 | # MBProgressHUD
2 |
3 | [](https://travis-ci.org/matej/MBProgressHUD) [](https://codecov.io/github/matej/MBProgressHUD?branch=master)
4 | [](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) [](https://cocoapods.org/pods/MBProgressHUD) [](http://opensource.org/licenses/MIT)
5 |
6 | `MBProgressHUD` is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private `UIKit` `UIProgressHUD` with some additional features.
7 |
8 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/1.png)
9 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/2.png)
10 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/3.png)
11 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/4.png)
12 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/5.png)
13 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/6.png)
14 | [](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/7.png)
15 |
16 | **NOTE:** The class has recently undergone a major rewrite. The old version is available in the [legacy](https://github.com/jdg/MBProgressHUD/tree/legacy) branch, should you need it.
17 |
18 | ## Requirements
19 |
20 | `MBProgressHUD` works on iOS 6+ and requires ARC to build. It depends on the following Apple frameworks, which should already be included with most Xcode templates:
21 |
22 | * Foundation.framework
23 | * UIKit.framework
24 | * CoreGraphics.framework
25 |
26 | You will need the latest developer tools in order to build `MBProgressHUD`. Old Xcode versions might work, but compatibility will not be explicitly maintained.
27 |
28 | ## Adding MBProgressHUD to your project
29 |
30 | ### CocoaPods
31 |
32 | [CocoaPods](http://cocoapods.org) is the recommended way to add MBProgressHUD to your project.
33 |
34 | 1. Add a pod entry for MBProgressHUD to your Podfile `pod 'MBProgressHUD', '~> 1.1.0'`
35 | 2. Install the pod(s) by running `pod install`.
36 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`.
37 |
38 | ### Carthage
39 |
40 | 1. Add MBProgressHUD to your Cartfile. e.g., `github "jdg/MBProgressHUD" ~> 1.1.0`
41 | 2. Run `carthage update`
42 | 3. Follow the rest of the [standard Carthage installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add MBProgressHUD to your project.
43 |
44 | ### Source files
45 |
46 | Alternatively you can directly add the `MBProgressHUD.h` and `MBProgressHUD.m` source files to your project.
47 |
48 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/archive/master.zip) or add the repository as a git submodule to your git-tracked project.
49 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project.
50 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`.
51 |
52 | ### Static library
53 |
54 | You can also add MBProgressHUD as a static library to your project or workspace.
55 |
56 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/downloads) or add the repository as a git submodule to your git-tracked project.
57 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.xcodeproj` onto your project or workspace (use the "Product Navigator view").
58 | 3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add `libMBProgressHUD.a`. You might also need to add `MBProgressHUD` to the Target Dependencies list.
59 | 4. Include MBProgressHUD wherever you need it with `#import `.
60 |
61 | ## Usage
62 |
63 | The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread.
64 |
65 | ```objective-c
66 | [MBProgressHUD showHUDAddedTo:self.view animated:YES];
67 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
68 | // Do something...
69 | dispatch_async(dispatch_get_main_queue(), ^{
70 | [MBProgressHUD hideHUDForView:self.view animated:YES];
71 | });
72 | });
73 | ```
74 |
75 | You can add the HUD on any view or window. It is however a good idea to avoid adding the HUD to certain `UIKit` views with complex view hierarchies - like `UITableView` or `UICollectionView`. Those can mutate their subviews in unexpected ways and thereby break HUD display.
76 |
77 | If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns.
78 |
79 | ```objective-c
80 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
81 | hud.mode = MBProgressHUDModeAnnularDeterminate;
82 | hud.label.text = @"Loading";
83 | [self doSomethingInBackgroundWithProgressCallback:^(float progress) {
84 | hud.progress = progress;
85 | } completionCallback:^{
86 | [hud hideAnimated:YES];
87 | }];
88 | ```
89 |
90 | You can also use a `NSProgress` object and MBProgressHUD will update itself when there is progress reported through that object.
91 |
92 | ```objective-c
93 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
94 | hud.mode = MBProgressHUDModeAnnularDeterminate;
95 | hud.label.text = @"Loading";
96 | NSProgress *progress = [self doSomethingInBackgroundCompletion:^{
97 | [hud hideAnimated:YES];
98 | }];
99 | hud.progressObject = progress;
100 | ```
101 |
102 | Keep in mind that UI updates, inclining calls to MBProgressHUD should always be done on the main thread.
103 |
104 | If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task.
105 |
106 | ```objective-c
107 | [MBProgressHUD showHUDAddedTo:self.view animated:YES];
108 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC);
109 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
110 | // Do something...
111 | [MBProgressHUD hideHUDForView:self.view animated:YES];
112 | });
113 | ```
114 |
115 | You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes.
116 |
117 | For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h).
118 |
119 |
120 | ## License
121 |
122 | This code is distributed under the terms and conditions of the [MIT license](LICENSE).
123 |
124 | ## Change-log
125 |
126 | A brief summary of each MBProgressHUD release can be found in the [CHANGELOG](CHANGELOG.mdown).
127 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CYMHUD (0.1.0):
3 | - MBProgressHUD (= 1.1.0)
4 | - MBProgressHUD (1.1.0)
5 | - YYModel (1.0.4)
6 |
7 | DEPENDENCIES:
8 | - CYMHUD
9 | - YYModel
10 |
11 | SPEC REPOS:
12 | https://gitee.com/cuiyu8580/CYPodspec.git:
13 | - CYMHUD
14 | https://github.com/cocoapods/specs.git:
15 | - MBProgressHUD
16 | - YYModel
17 |
18 | SPEC CHECKSUMS:
19 | CYMHUD: c6c0a363e4c5834716c1750c34109773efd3a950
20 | MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9
21 | YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
22 |
23 | PODFILE CHECKSUM: a655ea8011c81b70a8b43404d5879d7858a99400
24 |
25 | COCOAPODS: 1.6.0.beta.1
26 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Pods.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/CYMHUD.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Pods.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/MBProgressHUD.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Pods.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/Pods-ELWeChatDylib.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 |
66 |
67 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Pods.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/YYModel.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
46 |
52 |
53 |
55 |
56 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Pods.xcodeproj/xcuserdata/cuishengyu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CYMHUD.xcscheme
8 |
9 | isShown
10 |
11 | orderHint
12 | 1
13 |
14 | MBProgressHUD.xcscheme
15 |
16 | isShown
17 |
18 | orderHint
19 | 2
20 |
21 | Pods-ELWeChatDylib.xcscheme
22 |
23 | isShown
24 |
25 | orderHint
26 | 3
27 |
28 | YYModel.xcscheme
29 |
30 | isShown
31 |
32 | orderHint
33 | 4
34 |
35 |
36 | SuppressBuildableAutocreation
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD-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 | FMWK
17 | CFBundleShortVersionString
18 | 0.1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_CYMHUD : NSObject
3 | @end
4 | @implementation PodsDummy_CYMHUD
5 | @end
6 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "HUD.h"
14 |
15 | FOUNDATION_EXPORT double CYMHUDVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char CYMHUDVersionString[];
17 |
18 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD.modulemap:
--------------------------------------------------------------------------------
1 | framework module CYMHUD {
2 | umbrella header "CYMHUD-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/CYMHUD/CYMHUD.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CYMHUD
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "MBProgressHUD" -framework "QuartzCore"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/CYMHUD
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-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 | FMWK
17 | CFBundleShortVersionString
18 | 1.1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_MBProgressHUD : NSObject
3 | @end
4 | @implementation PodsDummy_MBProgressHUD
5 | @end
6 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "MBProgressHUD.h"
14 |
15 | FOUNDATION_EXPORT double MBProgressHUDVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char MBProgressHUDVersionString[];
17 |
18 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap:
--------------------------------------------------------------------------------
1 | framework module MBProgressHUD {
2 | umbrella header "MBProgressHUD-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/MBProgressHUD
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## CYMHUD
5 |
6 | Copyright (c) 2018 cuiyu8580@126.com
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 |
27 | ## MBProgressHUD
28 |
29 | Copyright © 2009-2016 Matej Bukovinski
30 |
31 | Permission is hereby granted, free of charge, to any person obtaining a copy
32 | of this software and associated documentation files (the "Software"), to deal
33 | in the Software without restriction, including without limitation the rights
34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 | copies of the Software, and to permit persons to whom the Software is
36 | furnished to do so, subject to the following conditions:
37 |
38 | The above copyright notice and this permission notice shall be included in
39 | all copies or substantial portions of the Software.
40 |
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47 | THE SOFTWARE.
48 |
49 | ## YYModel
50 |
51 | The MIT License (MIT)
52 |
53 | Copyright (c) 2015 ibireme
54 |
55 | Permission is hereby granted, free of charge, to any person obtaining a copy
56 | of this software and associated documentation files (the "Software"), to deal
57 | in the Software without restriction, including without limitation the rights
58 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59 | copies of the Software, and to permit persons to whom the Software is
60 | furnished to do so, subject to the following conditions:
61 |
62 | The above copyright notice and this permission notice shall be included in all
63 | copies or substantial portions of the Software.
64 |
65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
71 | SOFTWARE.
72 |
73 |
74 | Generated by CocoaPods - https://cocoapods.org
75 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_ELWeChatDylib : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_ELWeChatDylib
5 | @end
6 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -u
4 | set -o pipefail
5 |
6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
8 | # frameworks to, so exit 0 (signalling the script phase was successful).
9 | exit 0
10 | fi
11 |
12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
14 |
15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
17 |
18 | # Used as a return value for each invocation of `strip_invalid_archs` function.
19 | STRIP_BINARY_RETVAL=0
20 |
21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
24 |
25 | # Copies and strips a vendored framework
26 | install_framework()
27 | {
28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
29 | local source="${BUILT_PRODUCTS_DIR}/$1"
30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
32 | elif [ -r "$1" ]; then
33 | local source="$1"
34 | fi
35 |
36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
37 |
38 | if [ -L "${source}" ]; then
39 | echo "Symlinked..."
40 | source="$(readlink "${source}")"
41 | fi
42 |
43 | # Use filter instead of exclude so missing patterns don't throw errors.
44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
46 |
47 | local basename
48 | basename="$(basename -s .framework "$1")"
49 | binary="${destination}/${basename}.framework/${basename}"
50 |
51 | if ! [ -r "$binary" ]; then
52 | binary="${destination}/${basename}"
53 | elif [ -L "${binary}" ]; then
54 | echo "Destination binary is symlinked..."
55 | dirname="$(dirname "${binary}")"
56 | binary="${dirname}/$(readlink "${binary}")"
57 | fi
58 |
59 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
60 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
61 | strip_invalid_archs "$binary"
62 | fi
63 |
64 | # Resign the code if required by the build settings to avoid unstable apps
65 | code_sign_if_enabled "${destination}/$(basename "$1")"
66 |
67 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
68 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
69 | local swift_runtime_libs
70 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
71 | for lib in $swift_runtime_libs; do
72 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
73 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
74 | code_sign_if_enabled "${destination}/${lib}"
75 | done
76 | fi
77 | }
78 |
79 | # Copies and strips a vendored dSYM
80 | install_dsym() {
81 | local source="$1"
82 | if [ -r "$source" ]; then
83 | # Copy the dSYM into a the targets temp dir.
84 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
85 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
86 |
87 | local basename
88 | basename="$(basename -s .framework.dSYM "$source")"
89 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
90 |
91 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
92 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
93 | strip_invalid_archs "$binary"
94 | fi
95 |
96 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
97 | # Move the stripped file into its final destination.
98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
100 | else
101 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
102 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
103 | fi
104 | fi
105 | }
106 |
107 | # Signs a framework with the provided identity
108 | code_sign_if_enabled() {
109 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
110 | # Use the current code_sign_identity
111 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
112 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
113 |
114 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
115 | code_sign_cmd="$code_sign_cmd &"
116 | fi
117 | echo "$code_sign_cmd"
118 | eval "$code_sign_cmd"
119 | fi
120 | }
121 |
122 | # Strip invalid architectures
123 | strip_invalid_archs() {
124 | binary="$1"
125 | # Get architectures for current target binary
126 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
127 | # Intersect them with the architectures we are building for
128 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
129 | # If there are no archs supported by this binary then warn the user
130 | if [[ -z "$intersected_archs" ]]; then
131 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
132 | STRIP_BINARY_RETVAL=0
133 | return
134 | fi
135 | stripped=""
136 | for arch in $binary_archs; do
137 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
138 | # Strip non-valid architectures in-place
139 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1
140 | stripped="$stripped $arch"
141 | fi
142 | done
143 | if [[ "$stripped" ]]; then
144 | echo "Stripped $binary of architectures:$stripped"
145 | fi
146 | STRIP_BINARY_RETVAL=1
147 | }
148 |
149 |
150 | if [[ "$CONFIGURATION" == "Debug" ]]; then
151 | install_framework "${BUILT_PRODUCTS_DIR}/CYMHUD/CYMHUD.framework"
152 | install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework"
153 | install_framework "${BUILT_PRODUCTS_DIR}/YYModel/YYModel.framework"
154 | fi
155 | if [[ "$CONFIGURATION" == "Release" ]]; then
156 | install_framework "${BUILT_PRODUCTS_DIR}/CYMHUD/CYMHUD.framework"
157 | install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework"
158 | install_framework "${BUILT_PRODUCTS_DIR}/YYModel/YYModel.framework"
159 | fi
160 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
161 | wait
162 | fi
163 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_ELWeChatDylibVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_ELWeChatDylibVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CYMHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CYMHUD/CYMHUD.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
5 | OTHER_LDFLAGS = $(inherited) -framework "CYMHUD" -framework "CoreFoundation" -framework "CoreGraphics" -framework "Foundation" -framework "MBProgressHUD" -framework "QuartzCore" -framework "YYModel"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_ELWeChatDylib {
2 | umbrella header "Pods-ELWeChatDylib-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/Pods-ELWeChatDylib/Pods-ELWeChatDylib.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CYMHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
4 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/CYMHUD/CYMHUD.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
5 | OTHER_LDFLAGS = $(inherited) -framework "CYMHUD" -framework "CoreFoundation" -framework "CoreGraphics" -framework "Foundation" -framework "MBProgressHUD" -framework "QuartzCore" -framework "YYModel"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel-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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.4
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_YYModel : NSObject
3 | @end
4 | @implementation PodsDummy_YYModel
5 | @end
6 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "NSObject+YYModel.h"
14 | #import "YYClassInfo.h"
15 | #import "YYModel.h"
16 |
17 | FOUNDATION_EXPORT double YYModelVersionNumber;
18 | FOUNDATION_EXPORT const unsigned char YYModelVersionString[];
19 |
20 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel.modulemap:
--------------------------------------------------------------------------------
1 | framework module YYModel {
2 | umbrella header "YYModel-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/Target Support Files/YYModel/YYModel.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YYModel
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "CoreFoundation" -framework "Foundation"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/YYModel
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/YYModel/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 ibireme
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/YYModel/YYModel/NSObject+YYModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+YYModel.h
3 | // YYModel
4 | //
5 | // Created by ibireme on 15/5/10.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | /**
17 | Provide some data-model method:
18 |
19 | * Convert json to any object, or convert any object to json.
20 | * Set object properties with a key-value dictionary (like KVC).
21 | * Implementations of `NSCoding`, `NSCopying`, `-hash` and `-isEqual:`.
22 |
23 | See `YYModel` protocol for custom methods.
24 |
25 |
26 | Sample Code:
27 |
28 | ********************** json convertor *********************
29 | @interface YYAuthor : NSObject
30 | @property (nonatomic, strong) NSString *name;
31 | @property (nonatomic, assign) NSDate *birthday;
32 | @end
33 | @implementation YYAuthor
34 | @end
35 |
36 | @interface YYBook : NSObject
37 | @property (nonatomic, copy) NSString *name;
38 | @property (nonatomic, assign) NSUInteger pages;
39 | @property (nonatomic, strong) YYAuthor *author;
40 | @end
41 | @implementation YYBook
42 | @end
43 |
44 | int main() {
45 | // create model from json
46 | YYBook *book = [YYBook yy_modelWithJSON:@"{\"name\": \"Harry Potter\", \"pages\": 256, \"author\": {\"name\": \"J.K.Rowling\", \"birthday\": \"1965-07-31\" }}"];
47 |
48 | // convert model to json
49 | NSString *json = [book yy_modelToJSONString];
50 | // {"author":{"name":"J.K.Rowling","birthday":"1965-07-31T00:00:00+0000"},"name":"Harry Potter","pages":256}
51 | }
52 |
53 | ********************** Coding/Copying/hash/equal *********************
54 | @interface YYShadow :NSObject
55 | @property (nonatomic, copy) NSString *name;
56 | @property (nonatomic, assign) CGSize size;
57 | @end
58 |
59 | @implementation YYShadow
60 | - (void)encodeWithCoder:(NSCoder *)aCoder { [self yy_modelEncodeWithCoder:aCoder]; }
61 | - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; return [self yy_modelInitWithCoder:aDecoder]; }
62 | - (id)copyWithZone:(NSZone *)zone { return [self yy_modelCopy]; }
63 | - (NSUInteger)hash { return [self yy_modelHash]; }
64 | - (BOOL)isEqual:(id)object { return [self yy_modelIsEqual:object]; }
65 | @end
66 |
67 | */
68 | @interface NSObject (YYModel)
69 |
70 | /**
71 | Creates and returns a new instance of the receiver from a json.
72 | This method is thread-safe.
73 |
74 | @param json A json object in `NSDictionary`, `NSString` or `NSData`.
75 |
76 | @return A new instance created from the json, or nil if an error occurs.
77 | */
78 | + (nullable instancetype)yy_modelWithJSON:(id)json;
79 |
80 | /**
81 | Creates and returns a new instance of the receiver from a key-value dictionary.
82 | This method is thread-safe.
83 |
84 | @param dictionary A key-value dictionary mapped to the instance's properties.
85 | Any invalid key-value pair in dictionary will be ignored.
86 |
87 | @return A new instance created from the dictionary, or nil if an error occurs.
88 |
89 | @discussion The key in `dictionary` will mapped to the reciever's property name,
90 | and the value will set to the property. If the value's type does not match the
91 | property, this method will try to convert the value based on these rules:
92 |
93 | `NSString` or `NSNumber` -> c number, such as BOOL, int, long, float, NSUInteger...
94 | `NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd".
95 | `NSString` -> NSURL.
96 | `NSValue` -> struct or union, such as CGRect, CGSize, ...
97 | `NSString` -> SEL, Class.
98 | */
99 | + (nullable instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary;
100 |
101 | /**
102 | Set the receiver's properties with a json object.
103 |
104 | @discussion Any invalid data in json will be ignored.
105 |
106 | @param json A json object of `NSDictionary`, `NSString` or `NSData`, mapped to the
107 | receiver's properties.
108 |
109 | @return Whether succeed.
110 | */
111 | - (BOOL)yy_modelSetWithJSON:(id)json;
112 |
113 | /**
114 | Set the receiver's properties with a key-value dictionary.
115 |
116 | @param dic A key-value dictionary mapped to the receiver's properties.
117 | Any invalid key-value pair in dictionary will be ignored.
118 |
119 | @discussion The key in `dictionary` will mapped to the reciever's property name,
120 | and the value will set to the property. If the value's type doesn't match the
121 | property, this method will try to convert the value based on these rules:
122 |
123 | `NSString`, `NSNumber` -> c number, such as BOOL, int, long, float, NSUInteger...
124 | `NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd".
125 | `NSString` -> NSURL.
126 | `NSValue` -> struct or union, such as CGRect, CGSize, ...
127 | `NSString` -> SEL, Class.
128 |
129 | @return Whether succeed.
130 | */
131 | - (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic;
132 |
133 | /**
134 | Generate a json object from the receiver's properties.
135 |
136 | @return A json object in `NSDictionary` or `NSArray`, or nil if an error occurs.
137 | See [NSJSONSerialization isValidJSONObject] for more information.
138 |
139 | @discussion Any of the invalid property is ignored.
140 | If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it just convert
141 | the inner object to json object.
142 | */
143 | - (nullable id)yy_modelToJSONObject;
144 |
145 | /**
146 | Generate a json string's data from the receiver's properties.
147 |
148 | @return A json string's data, or nil if an error occurs.
149 |
150 | @discussion Any of the invalid property is ignored.
151 | If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it will also convert the
152 | inner object to json string.
153 | */
154 | - (nullable NSData *)yy_modelToJSONData;
155 |
156 | /**
157 | Generate a json string from the receiver's properties.
158 |
159 | @return A json string, or nil if an error occurs.
160 |
161 | @discussion Any of the invalid property is ignored.
162 | If the reciver is `NSArray`, `NSDictionary` or `NSSet`, it will also convert the
163 | inner object to json string.
164 | */
165 | - (nullable NSString *)yy_modelToJSONString;
166 |
167 | /**
168 | Copy a instance with the receiver's properties.
169 |
170 | @return A copied instance, or nil if an error occurs.
171 | */
172 | - (nullable id)yy_modelCopy;
173 |
174 | /**
175 | Encode the receiver's properties to a coder.
176 |
177 | @param aCoder An archiver object.
178 | */
179 | - (void)yy_modelEncodeWithCoder:(NSCoder *)aCoder;
180 |
181 | /**
182 | Decode the receiver's properties from a decoder.
183 |
184 | @param aDecoder An archiver object.
185 |
186 | @return self
187 | */
188 | - (id)yy_modelInitWithCoder:(NSCoder *)aDecoder;
189 |
190 | /**
191 | Get a hash code with the receiver's properties.
192 |
193 | @return Hash code.
194 | */
195 | - (NSUInteger)yy_modelHash;
196 |
197 | /**
198 | Compares the receiver with another object for equality, based on properties.
199 |
200 | @param model Another object.
201 |
202 | @return `YES` if the reciever is equal to the object, otherwise `NO`.
203 | */
204 | - (BOOL)yy_modelIsEqual:(id)model;
205 |
206 | /**
207 | Description method for debugging purposes based on properties.
208 |
209 | @return A string that describes the contents of the receiver.
210 | */
211 | - (NSString *)yy_modelDescription;
212 |
213 | @end
214 |
215 |
216 |
217 | /**
218 | Provide some data-model method for NSArray.
219 | */
220 | @interface NSArray (YYModel)
221 |
222 | /**
223 | Creates and returns an array from a json-array.
224 | This method is thread-safe.
225 |
226 | @param cls The instance's class in array.
227 | @param json A json array of `NSArray`, `NSString` or `NSData`.
228 | Example: [{"name","Mary"},{name:"Joe"}]
229 |
230 | @return A array, or nil if an error occurs.
231 | */
232 | + (nullable NSArray *)yy_modelArrayWithClass:(Class)cls json:(id)json;
233 |
234 | @end
235 |
236 |
237 |
238 | /**
239 | Provide some data-model method for NSDictionary.
240 | */
241 | @interface NSDictionary (YYModel)
242 |
243 | /**
244 | Creates and returns a dictionary from a json.
245 | This method is thread-safe.
246 |
247 | @param cls The value instance's class in dictionary.
248 | @param json A json dictionary of `NSDictionary`, `NSString` or `NSData`.
249 | Example: {"user1":{"name","Mary"}, "user2": {name:"Joe"}}
250 |
251 | @return A dictionary, or nil if an error occurs.
252 | */
253 | + (nullable NSDictionary *)yy_modelDictionaryWithClass:(Class)cls json:(id)json;
254 | @end
255 |
256 |
257 |
258 | /**
259 | If the default model transform does not fit to your model class, implement one or
260 | more method in this protocol to change the default key-value transform process.
261 | There's no need to add '' to your class header.
262 | */
263 | @protocol YYModel
264 | @optional
265 |
266 | /**
267 | Custom property mapper.
268 |
269 | @discussion If the key in JSON/Dictionary does not match to the model's property name,
270 | implements this method and returns the additional mapper.
271 |
272 | Example:
273 |
274 | json:
275 | {
276 | "n":"Harry Pottery",
277 | "p": 256,
278 | "ext" : {
279 | "desc" : "A book written by J.K.Rowling."
280 | },
281 | "ID" : 100010
282 | }
283 |
284 | model:
285 | @interface YYBook : NSObject
286 | @property NSString *name;
287 | @property NSInteger page;
288 | @property NSString *desc;
289 | @property NSString *bookID;
290 | @end
291 |
292 | @implementation YYBook
293 | + (NSDictionary *)modelCustomPropertyMapper {
294 | return @{@"name" : @"n",
295 | @"page" : @"p",
296 | @"desc" : @"ext.desc",
297 | @"bookID": @[@"id", @"ID", @"book_id"]};
298 | }
299 | @end
300 |
301 | @return A custom mapper for properties.
302 | */
303 | + (nullable NSDictionary *)modelCustomPropertyMapper;
304 |
305 | /**
306 | The generic class mapper for container properties.
307 |
308 | @discussion If the property is a container object, such as NSArray/NSSet/NSDictionary,
309 | implements this method and returns a property->class mapper, tells which kind of
310 | object will be add to the array/set/dictionary.
311 |
312 | Example:
313 | @class YYShadow, YYBorder, YYAttachment;
314 |
315 | @interface YYAttributes
316 | @property NSString *name;
317 | @property NSArray *shadows;
318 | @property NSSet *borders;
319 | @property NSDictionary *attachments;
320 | @end
321 |
322 | @implementation YYAttributes
323 | + (NSDictionary *)modelContainerPropertyGenericClass {
324 | return @{@"shadows" : [YYShadow class],
325 | @"borders" : YYBorder.class,
326 | @"attachments" : @"YYAttachment" };
327 | }
328 | @end
329 |
330 | @return A class mapper.
331 | */
332 | + (nullable NSDictionary *)modelContainerPropertyGenericClass;
333 |
334 | /**
335 | If you need to create instances of different classes during json->object transform,
336 | use the method to choose custom class based on dictionary data.
337 |
338 | @discussion If the model implements this method, it will be called to determine resulting class
339 | during `+modelWithJSON:`, `+modelWithDictionary:`, conveting object of properties of parent objects
340 | (both singular and containers via `+modelContainerPropertyGenericClass`).
341 |
342 | Example:
343 | @class YYCircle, YYRectangle, YYLine;
344 |
345 | @implementation YYShape
346 |
347 | + (Class)modelCustomClassForDictionary:(NSDictionary*)dictionary {
348 | if (dictionary[@"radius"] != nil) {
349 | return [YYCircle class];
350 | } else if (dictionary[@"width"] != nil) {
351 | return [YYRectangle class];
352 | } else if (dictionary[@"y2"] != nil) {
353 | return [YYLine class];
354 | } else {
355 | return [self class];
356 | }
357 | }
358 |
359 | @end
360 |
361 | @param dictionary The json/kv dictionary.
362 |
363 | @return Class to create from this dictionary, `nil` to use current class.
364 |
365 | */
366 | + (nullable Class)modelCustomClassForDictionary:(NSDictionary *)dictionary;
367 |
368 | /**
369 | All the properties in blacklist will be ignored in model transform process.
370 | Returns nil to ignore this feature.
371 |
372 | @return An array of property's name.
373 | */
374 | + (nullable NSArray *)modelPropertyBlacklist;
375 |
376 | /**
377 | If a property is not in the whitelist, it will be ignored in model transform process.
378 | Returns nil to ignore this feature.
379 |
380 | @return An array of property's name.
381 | */
382 | + (nullable NSArray *)modelPropertyWhitelist;
383 |
384 | /**
385 | This method's behavior is similar to `- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;`,
386 | but be called before the model transform.
387 |
388 | @discussion If the model implements this method, it will be called before
389 | `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`.
390 | If this method returns nil, the transform process will ignore this model.
391 |
392 | @param dic The json/kv dictionary.
393 |
394 | @return Returns the modified dictionary, or nil to ignore this model.
395 | */
396 | - (NSDictionary *)modelCustomWillTransformFromDictionary:(NSDictionary *)dic;
397 |
398 | /**
399 | If the default json-to-model transform does not fit to your model object, implement
400 | this method to do additional process. You can also use this method to validate the
401 | model's properties.
402 |
403 | @discussion If the model implements this method, it will be called at the end of
404 | `+modelWithJSON:`, `+modelWithDictionary:`, `-modelSetWithJSON:` and `-modelSetWithDictionary:`.
405 | If this method returns NO, the transform process will ignore this model.
406 |
407 | @param dic The json/kv dictionary.
408 |
409 | @return Returns YES if the model is valid, or NO to ignore this model.
410 | */
411 | - (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
412 |
413 | /**
414 | If the default model-to-json transform does not fit to your model class, implement
415 | this method to do additional process. You can also use this method to validate the
416 | json dictionary.
417 |
418 | @discussion If the model implements this method, it will be called at the end of
419 | `-modelToJSONObject` and `-modelToJSONString`.
420 | If this method returns NO, the transform process will ignore this json dictionary.
421 |
422 | @param dic The json dictionary.
423 |
424 | @return Returns YES if the model is valid, or NO to ignore this model.
425 | */
426 | - (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic;
427 |
428 | @end
429 |
430 | NS_ASSUME_NONNULL_END
431 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/YYModel/YYModel/YYClassInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYClassInfo.h
3 | // YYModel
4 | //
5 | // Created by ibireme on 15/5/9.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 | #import
14 |
15 | NS_ASSUME_NONNULL_BEGIN
16 |
17 | /**
18 | Type encoding's type.
19 | */
20 | typedef NS_OPTIONS(NSUInteger, YYEncodingType) {
21 | YYEncodingTypeMask = 0xFF, ///< mask of type value
22 | YYEncodingTypeUnknown = 0, ///< unknown
23 | YYEncodingTypeVoid = 1, ///< void
24 | YYEncodingTypeBool = 2, ///< bool
25 | YYEncodingTypeInt8 = 3, ///< char / BOOL
26 | YYEncodingTypeUInt8 = 4, ///< unsigned char
27 | YYEncodingTypeInt16 = 5, ///< short
28 | YYEncodingTypeUInt16 = 6, ///< unsigned short
29 | YYEncodingTypeInt32 = 7, ///< int
30 | YYEncodingTypeUInt32 = 8, ///< unsigned int
31 | YYEncodingTypeInt64 = 9, ///< long long
32 | YYEncodingTypeUInt64 = 10, ///< unsigned long long
33 | YYEncodingTypeFloat = 11, ///< float
34 | YYEncodingTypeDouble = 12, ///< double
35 | YYEncodingTypeLongDouble = 13, ///< long double
36 | YYEncodingTypeObject = 14, ///< id
37 | YYEncodingTypeClass = 15, ///< Class
38 | YYEncodingTypeSEL = 16, ///< SEL
39 | YYEncodingTypeBlock = 17, ///< block
40 | YYEncodingTypePointer = 18, ///< void*
41 | YYEncodingTypeStruct = 19, ///< struct
42 | YYEncodingTypeUnion = 20, ///< union
43 | YYEncodingTypeCString = 21, ///< char*
44 | YYEncodingTypeCArray = 22, ///< char[10] (for example)
45 |
46 | YYEncodingTypeQualifierMask = 0xFF00, ///< mask of qualifier
47 | YYEncodingTypeQualifierConst = 1 << 8, ///< const
48 | YYEncodingTypeQualifierIn = 1 << 9, ///< in
49 | YYEncodingTypeQualifierInout = 1 << 10, ///< inout
50 | YYEncodingTypeQualifierOut = 1 << 11, ///< out
51 | YYEncodingTypeQualifierBycopy = 1 << 12, ///< bycopy
52 | YYEncodingTypeQualifierByref = 1 << 13, ///< byref
53 | YYEncodingTypeQualifierOneway = 1 << 14, ///< oneway
54 |
55 | YYEncodingTypePropertyMask = 0xFF0000, ///< mask of property
56 | YYEncodingTypePropertyReadonly = 1 << 16, ///< readonly
57 | YYEncodingTypePropertyCopy = 1 << 17, ///< copy
58 | YYEncodingTypePropertyRetain = 1 << 18, ///< retain
59 | YYEncodingTypePropertyNonatomic = 1 << 19, ///< nonatomic
60 | YYEncodingTypePropertyWeak = 1 << 20, ///< weak
61 | YYEncodingTypePropertyCustomGetter = 1 << 21, ///< getter=
62 | YYEncodingTypePropertyCustomSetter = 1 << 22, ///< setter=
63 | YYEncodingTypePropertyDynamic = 1 << 23, ///< @dynamic
64 | };
65 |
66 | /**
67 | Get the type from a Type-Encoding string.
68 |
69 | @discussion See also:
70 | https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
71 | https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
72 |
73 | @param typeEncoding A Type-Encoding string.
74 | @return The encoding type.
75 | */
76 | YYEncodingType YYEncodingGetType(const char *typeEncoding);
77 |
78 |
79 | /**
80 | Instance variable information.
81 | */
82 | @interface YYClassIvarInfo : NSObject
83 | @property (nonatomic, assign, readonly) Ivar ivar; ///< ivar opaque struct
84 | @property (nonatomic, strong, readonly) NSString *name; ///< Ivar's name
85 | @property (nonatomic, assign, readonly) ptrdiff_t offset; ///< Ivar's offset
86 | @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< Ivar's type encoding
87 | @property (nonatomic, assign, readonly) YYEncodingType type; ///< Ivar's type
88 |
89 | /**
90 | Creates and returns an ivar info object.
91 |
92 | @param ivar ivar opaque struct
93 | @return A new object, or nil if an error occurs.
94 | */
95 | - (instancetype)initWithIvar:(Ivar)ivar;
96 | @end
97 |
98 |
99 | /**
100 | Method information.
101 | */
102 | @interface YYClassMethodInfo : NSObject
103 | @property (nonatomic, assign, readonly) Method method; ///< method opaque struct
104 | @property (nonatomic, strong, readonly) NSString *name; ///< method name
105 | @property (nonatomic, assign, readonly) SEL sel; ///< method's selector
106 | @property (nonatomic, assign, readonly) IMP imp; ///< method's implementation
107 | @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< method's parameter and return types
108 | @property (nonatomic, strong, readonly) NSString *returnTypeEncoding; ///< return value's type
109 | @property (nullable, nonatomic, strong, readonly) NSArray *argumentTypeEncodings; ///< array of arguments' type
110 |
111 | /**
112 | Creates and returns a method info object.
113 |
114 | @param method method opaque struct
115 | @return A new object, or nil if an error occurs.
116 | */
117 | - (instancetype)initWithMethod:(Method)method;
118 | @end
119 |
120 |
121 | /**
122 | Property information.
123 | */
124 | @interface YYClassPropertyInfo : NSObject
125 | @property (nonatomic, assign, readonly) objc_property_t property; ///< property's opaque struct
126 | @property (nonatomic, strong, readonly) NSString *name; ///< property's name
127 | @property (nonatomic, assign, readonly) YYEncodingType type; ///< property's type
128 | @property (nonatomic, strong, readonly) NSString *typeEncoding; ///< property's encoding value
129 | @property (nonatomic, strong, readonly) NSString *ivarName; ///< property's ivar name
130 | @property (nullable, nonatomic, assign, readonly) Class cls; ///< may be nil
131 | @property (nullable, nonatomic, strong, readonly) NSArray *protocols; ///< may nil
132 | @property (nonatomic, assign, readonly) SEL getter; ///< getter (nonnull)
133 | @property (nonatomic, assign, readonly) SEL setter; ///< setter (nonnull)
134 |
135 | /**
136 | Creates and returns a property info object.
137 |
138 | @param property property opaque struct
139 | @return A new object, or nil if an error occurs.
140 | */
141 | - (instancetype)initWithProperty:(objc_property_t)property;
142 | @end
143 |
144 |
145 | /**
146 | Class information for a class.
147 | */
148 | @interface YYClassInfo : NSObject
149 | @property (nonatomic, assign, readonly) Class cls; ///< class object
150 | @property (nullable, nonatomic, assign, readonly) Class superCls; ///< super class object
151 | @property (nullable, nonatomic, assign, readonly) Class metaCls; ///< class's meta class object
152 | @property (nonatomic, readonly) BOOL isMeta; ///< whether this class is meta class
153 | @property (nonatomic, strong, readonly) NSString *name; ///< class name
154 | @property (nullable, nonatomic, strong, readonly) YYClassInfo *superClassInfo; ///< super class's class info
155 | @property (nullable, nonatomic, strong, readonly) NSDictionary *ivarInfos; ///< ivars
156 | @property (nullable, nonatomic, strong, readonly) NSDictionary *methodInfos; ///< methods
157 | @property (nullable, nonatomic, strong, readonly) NSDictionary *propertyInfos; ///< properties
158 |
159 | /**
160 | If the class is changed (for example: you add a method to this class with
161 | 'class_addMethod()'), you should call this method to refresh the class info cache.
162 |
163 | After called this method, `needUpdate` will returns `YES`, and you should call
164 | 'classInfoWithClass' or 'classInfoWithClassName' to get the updated class info.
165 | */
166 | - (void)setNeedUpdate;
167 |
168 | /**
169 | If this method returns `YES`, you should stop using this instance and call
170 | `classInfoWithClass` or `classInfoWithClassName` to get the updated class info.
171 |
172 | @return Whether this class info need update.
173 | */
174 | - (BOOL)needUpdate;
175 |
176 | /**
177 | Get the class info of a specified Class.
178 |
179 | @discussion This method will cache the class info and super-class info
180 | at the first access to the Class. This method is thread-safe.
181 |
182 | @param cls A class.
183 | @return A class info, or nil if an error occurs.
184 | */
185 | + (nullable instancetype)classInfoWithClass:(Class)cls;
186 |
187 | /**
188 | Get the class info of a specified Class.
189 |
190 | @discussion This method will cache the class info and super-class info
191 | at the first access to the Class. This method is thread-safe.
192 |
193 | @param className A class name.
194 | @return A class info, or nil if an error occurs.
195 | */
196 | + (nullable instancetype)classInfoWithClassName:(NSString *)className;
197 |
198 | @end
199 |
200 | NS_ASSUME_NONNULL_END
201 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/YYModel/YYModel/YYClassInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // YYClassInfo.m
3 | // YYModel
4 | //
5 | // Created by ibireme on 15/5/9.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import "YYClassInfo.h"
13 | #import
14 |
15 | YYEncodingType YYEncodingGetType(const char *typeEncoding) {
16 | char *type = (char *)typeEncoding;
17 | if (!type) return YYEncodingTypeUnknown;
18 | size_t len = strlen(type);
19 | if (len == 0) return YYEncodingTypeUnknown;
20 |
21 | YYEncodingType qualifier = 0;
22 | bool prefix = true;
23 | while (prefix) {
24 | switch (*type) {
25 | case 'r': {
26 | qualifier |= YYEncodingTypeQualifierConst;
27 | type++;
28 | } break;
29 | case 'n': {
30 | qualifier |= YYEncodingTypeQualifierIn;
31 | type++;
32 | } break;
33 | case 'N': {
34 | qualifier |= YYEncodingTypeQualifierInout;
35 | type++;
36 | } break;
37 | case 'o': {
38 | qualifier |= YYEncodingTypeQualifierOut;
39 | type++;
40 | } break;
41 | case 'O': {
42 | qualifier |= YYEncodingTypeQualifierBycopy;
43 | type++;
44 | } break;
45 | case 'R': {
46 | qualifier |= YYEncodingTypeQualifierByref;
47 | type++;
48 | } break;
49 | case 'V': {
50 | qualifier |= YYEncodingTypeQualifierOneway;
51 | type++;
52 | } break;
53 | default: { prefix = false; } break;
54 | }
55 | }
56 |
57 | len = strlen(type);
58 | if (len == 0) return YYEncodingTypeUnknown | qualifier;
59 |
60 | switch (*type) {
61 | case 'v': return YYEncodingTypeVoid | qualifier;
62 | case 'B': return YYEncodingTypeBool | qualifier;
63 | case 'c': return YYEncodingTypeInt8 | qualifier;
64 | case 'C': return YYEncodingTypeUInt8 | qualifier;
65 | case 's': return YYEncodingTypeInt16 | qualifier;
66 | case 'S': return YYEncodingTypeUInt16 | qualifier;
67 | case 'i': return YYEncodingTypeInt32 | qualifier;
68 | case 'I': return YYEncodingTypeUInt32 | qualifier;
69 | case 'l': return YYEncodingTypeInt32 | qualifier;
70 | case 'L': return YYEncodingTypeUInt32 | qualifier;
71 | case 'q': return YYEncodingTypeInt64 | qualifier;
72 | case 'Q': return YYEncodingTypeUInt64 | qualifier;
73 | case 'f': return YYEncodingTypeFloat | qualifier;
74 | case 'd': return YYEncodingTypeDouble | qualifier;
75 | case 'D': return YYEncodingTypeLongDouble | qualifier;
76 | case '#': return YYEncodingTypeClass | qualifier;
77 | case ':': return YYEncodingTypeSEL | qualifier;
78 | case '*': return YYEncodingTypeCString | qualifier;
79 | case '^': return YYEncodingTypePointer | qualifier;
80 | case '[': return YYEncodingTypeCArray | qualifier;
81 | case '(': return YYEncodingTypeUnion | qualifier;
82 | case '{': return YYEncodingTypeStruct | qualifier;
83 | case '@': {
84 | if (len == 2 && *(type + 1) == '?')
85 | return YYEncodingTypeBlock | qualifier;
86 | else
87 | return YYEncodingTypeObject | qualifier;
88 | }
89 | default: return YYEncodingTypeUnknown | qualifier;
90 | }
91 | }
92 |
93 | @implementation YYClassIvarInfo
94 |
95 | - (instancetype)initWithIvar:(Ivar)ivar {
96 | if (!ivar) return nil;
97 | self = [super init];
98 | _ivar = ivar;
99 | const char *name = ivar_getName(ivar);
100 | if (name) {
101 | _name = [NSString stringWithUTF8String:name];
102 | }
103 | _offset = ivar_getOffset(ivar);
104 | const char *typeEncoding = ivar_getTypeEncoding(ivar);
105 | if (typeEncoding) {
106 | _typeEncoding = [NSString stringWithUTF8String:typeEncoding];
107 | _type = YYEncodingGetType(typeEncoding);
108 | }
109 | return self;
110 | }
111 |
112 | @end
113 |
114 | @implementation YYClassMethodInfo
115 |
116 | - (instancetype)initWithMethod:(Method)method {
117 | if (!method) return nil;
118 | self = [super init];
119 | _method = method;
120 | _sel = method_getName(method);
121 | _imp = method_getImplementation(method);
122 | const char *name = sel_getName(_sel);
123 | if (name) {
124 | _name = [NSString stringWithUTF8String:name];
125 | }
126 | const char *typeEncoding = method_getTypeEncoding(method);
127 | if (typeEncoding) {
128 | _typeEncoding = [NSString stringWithUTF8String:typeEncoding];
129 | }
130 | char *returnType = method_copyReturnType(method);
131 | if (returnType) {
132 | _returnTypeEncoding = [NSString stringWithUTF8String:returnType];
133 | free(returnType);
134 | }
135 | unsigned int argumentCount = method_getNumberOfArguments(method);
136 | if (argumentCount > 0) {
137 | NSMutableArray *argumentTypes = [NSMutableArray new];
138 | for (unsigned int i = 0; i < argumentCount; i++) {
139 | char *argumentType = method_copyArgumentType(method, i);
140 | NSString *type = argumentType ? [NSString stringWithUTF8String:argumentType] : nil;
141 | [argumentTypes addObject:type ? type : @""];
142 | if (argumentType) free(argumentType);
143 | }
144 | _argumentTypeEncodings = argumentTypes;
145 | }
146 | return self;
147 | }
148 |
149 | @end
150 |
151 | @implementation YYClassPropertyInfo
152 |
153 | - (instancetype)initWithProperty:(objc_property_t)property {
154 | if (!property) return nil;
155 | self = [super init];
156 | _property = property;
157 | const char *name = property_getName(property);
158 | if (name) {
159 | _name = [NSString stringWithUTF8String:name];
160 | }
161 |
162 | YYEncodingType type = 0;
163 | unsigned int attrCount;
164 | objc_property_attribute_t *attrs = property_copyAttributeList(property, &attrCount);
165 | for (unsigned int i = 0; i < attrCount; i++) {
166 | switch (attrs[i].name[0]) {
167 | case 'T': { // Type encoding
168 | if (attrs[i].value) {
169 | _typeEncoding = [NSString stringWithUTF8String:attrs[i].value];
170 | type = YYEncodingGetType(attrs[i].value);
171 |
172 | if ((type & YYEncodingTypeMask) == YYEncodingTypeObject && _typeEncoding.length) {
173 | NSScanner *scanner = [NSScanner scannerWithString:_typeEncoding];
174 | if (![scanner scanString:@"@\"" intoString:NULL]) continue;
175 |
176 | NSString *clsName = nil;
177 | if ([scanner scanUpToCharactersFromSet: [NSCharacterSet characterSetWithCharactersInString:@"\"<"] intoString:&clsName]) {
178 | if (clsName.length) _cls = objc_getClass(clsName.UTF8String);
179 | }
180 |
181 | NSMutableArray *protocols = nil;
182 | while ([scanner scanString:@"<" intoString:NULL]) {
183 | NSString* protocol = nil;
184 | if ([scanner scanUpToString:@">" intoString: &protocol]) {
185 | if (protocol.length) {
186 | if (!protocols) protocols = [NSMutableArray new];
187 | [protocols addObject:protocol];
188 | }
189 | }
190 | [scanner scanString:@">" intoString:NULL];
191 | }
192 | _protocols = protocols;
193 | }
194 | }
195 | } break;
196 | case 'V': { // Instance variable
197 | if (attrs[i].value) {
198 | _ivarName = [NSString stringWithUTF8String:attrs[i].value];
199 | }
200 | } break;
201 | case 'R': {
202 | type |= YYEncodingTypePropertyReadonly;
203 | } break;
204 | case 'C': {
205 | type |= YYEncodingTypePropertyCopy;
206 | } break;
207 | case '&': {
208 | type |= YYEncodingTypePropertyRetain;
209 | } break;
210 | case 'N': {
211 | type |= YYEncodingTypePropertyNonatomic;
212 | } break;
213 | case 'D': {
214 | type |= YYEncodingTypePropertyDynamic;
215 | } break;
216 | case 'W': {
217 | type |= YYEncodingTypePropertyWeak;
218 | } break;
219 | case 'G': {
220 | type |= YYEncodingTypePropertyCustomGetter;
221 | if (attrs[i].value) {
222 | _getter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]);
223 | }
224 | } break;
225 | case 'S': {
226 | type |= YYEncodingTypePropertyCustomSetter;
227 | if (attrs[i].value) {
228 | _setter = NSSelectorFromString([NSString stringWithUTF8String:attrs[i].value]);
229 | }
230 | } // break; commented for code coverage in next line
231 | default: break;
232 | }
233 | }
234 | if (attrs) {
235 | free(attrs);
236 | attrs = NULL;
237 | }
238 |
239 | _type = type;
240 | if (_name.length) {
241 | if (!_getter) {
242 | _getter = NSSelectorFromString(_name);
243 | }
244 | if (!_setter) {
245 | _setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:", [_name substringToIndex:1].uppercaseString, [_name substringFromIndex:1]]);
246 | }
247 | }
248 | return self;
249 | }
250 |
251 | @end
252 |
253 | @implementation YYClassInfo {
254 | BOOL _needUpdate;
255 | }
256 |
257 | - (instancetype)initWithClass:(Class)cls {
258 | if (!cls) return nil;
259 | self = [super init];
260 | _cls = cls;
261 | _superCls = class_getSuperclass(cls);
262 | _isMeta = class_isMetaClass(cls);
263 | if (!_isMeta) {
264 | _metaCls = objc_getMetaClass(class_getName(cls));
265 | }
266 | _name = NSStringFromClass(cls);
267 | [self _update];
268 |
269 | _superClassInfo = [self.class classInfoWithClass:_superCls];
270 | return self;
271 | }
272 |
273 | - (void)_update {
274 | _ivarInfos = nil;
275 | _methodInfos = nil;
276 | _propertyInfos = nil;
277 |
278 | Class cls = self.cls;
279 | unsigned int methodCount = 0;
280 | Method *methods = class_copyMethodList(cls, &methodCount);
281 | if (methods) {
282 | NSMutableDictionary *methodInfos = [NSMutableDictionary new];
283 | _methodInfos = methodInfos;
284 | for (unsigned int i = 0; i < methodCount; i++) {
285 | YYClassMethodInfo *info = [[YYClassMethodInfo alloc] initWithMethod:methods[i]];
286 | if (info.name) methodInfos[info.name] = info;
287 | }
288 | free(methods);
289 | }
290 | unsigned int propertyCount = 0;
291 | objc_property_t *properties = class_copyPropertyList(cls, &propertyCount);
292 | if (properties) {
293 | NSMutableDictionary *propertyInfos = [NSMutableDictionary new];
294 | _propertyInfos = propertyInfos;
295 | for (unsigned int i = 0; i < propertyCount; i++) {
296 | YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:properties[i]];
297 | if (info.name) propertyInfos[info.name] = info;
298 | }
299 | free(properties);
300 | }
301 |
302 | unsigned int ivarCount = 0;
303 | Ivar *ivars = class_copyIvarList(cls, &ivarCount);
304 | if (ivars) {
305 | NSMutableDictionary *ivarInfos = [NSMutableDictionary new];
306 | _ivarInfos = ivarInfos;
307 | for (unsigned int i = 0; i < ivarCount; i++) {
308 | YYClassIvarInfo *info = [[YYClassIvarInfo alloc] initWithIvar:ivars[i]];
309 | if (info.name) ivarInfos[info.name] = info;
310 | }
311 | free(ivars);
312 | }
313 |
314 | if (!_ivarInfos) _ivarInfos = @{};
315 | if (!_methodInfos) _methodInfos = @{};
316 | if (!_propertyInfos) _propertyInfos = @{};
317 |
318 | _needUpdate = NO;
319 | }
320 |
321 | - (void)setNeedUpdate {
322 | _needUpdate = YES;
323 | }
324 |
325 | - (BOOL)needUpdate {
326 | return _needUpdate;
327 | }
328 |
329 | + (instancetype)classInfoWithClass:(Class)cls {
330 | if (!cls) return nil;
331 | static CFMutableDictionaryRef classCache;
332 | static CFMutableDictionaryRef metaCache;
333 | static dispatch_once_t onceToken;
334 | static dispatch_semaphore_t lock;
335 | dispatch_once(&onceToken, ^{
336 | classCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
337 | metaCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
338 | lock = dispatch_semaphore_create(1);
339 | });
340 | dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
341 | YYClassInfo *info = CFDictionaryGetValue(class_isMetaClass(cls) ? metaCache : classCache, (__bridge const void *)(cls));
342 | if (info && info->_needUpdate) {
343 | [info _update];
344 | }
345 | dispatch_semaphore_signal(lock);
346 | if (!info) {
347 | info = [[YYClassInfo alloc] initWithClass:cls];
348 | if (info) {
349 | dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
350 | CFDictionarySetValue(info.isMeta ? metaCache : classCache, (__bridge const void *)(cls), (__bridge const void *)(info));
351 | dispatch_semaphore_signal(lock);
352 | }
353 | }
354 | return info;
355 | }
356 |
357 | + (instancetype)classInfoWithClassName:(NSString *)className {
358 | Class cls = NSClassFromString(className);
359 | return [self classInfoWithClass:cls];
360 | }
361 |
362 | @end
363 |
--------------------------------------------------------------------------------
/ELWeChat/Pods/YYModel/YYModel/YYModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // YYModel.h
3 | // YYModel
4 | //
5 | // Created by ibireme on 15/5/10.
6 | // Copyright (c) 2015 ibireme.
7 | //
8 | // This source code is licensed under the MIT-style license found in the
9 | // LICENSE file in the root directory of this source tree.
10 | //
11 |
12 | #import
13 |
14 | #if __has_include()
15 | FOUNDATION_EXPORT double YYModelVersionNumber;
16 | FOUNDATION_EXPORT const unsigned char YYModelVersionString[];
17 | #import
18 | #import
19 | #else
20 | #import "NSObject+YYModel.h"
21 | #import "YYClassInfo.h"
22 | #endif
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 cuiyu8580
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## ELWeChat
2 | ### 简介
3 | 最新版微信抢红包,无需设备越狱,群红包和个人红包都可以。
4 | 支持修改微信步数(建议在2W左右设置即可),使用场景可以自己探索,近期会持续进行更新...
5 | QQ交流群:930556714(有问题请加)
6 |
友情提示:临近年底,微信加大监测力度,登录可能会收到警告,请不要拿来挂微信,有需要抢红包的同学,仅仅在抢的时候用一下就好了,多开的用户请绕道
7 |
8 |
9 | ---
10 |
11 | ### 百度云盘
12 | 链接: https://pan.baidu.com/s/11LlvsFjERRrBN0l9s2Qqew 提取码: epcg
13 |
14 | ---
15 |
16 | ### 关于安装
17 | 云盘提供.ipa文件
云盘提供的.ipa文件需要重新签名才可以安装,推荐使用[ios-app-signer](https://github.com/DanTheMan827/ios-app-signer)(非常重要,使用说明放在下面的链接里面)
18 |
19 | 下面提供几种方法可以使用:[提供几种常见的ipa文件安装方式](https://www.jianshu.com/p/2bf09385741a)
20 |
21 | ---
22 |
23 | ### 使用
24 | 在路径下开启【我】->【设置】->【XX助手】
25 |
26 | ---
27 |
28 | ### 功能说明
29 |
30 | #### 群管理(暂时去掉)
31 | 1、@所有人---使用格式#所有人+内容
32 | 群主以群公告形式@所有人,非群主以@A @B @C。。。的形式@所有人
33 |
34 | 2、踢群成员---使用格式#踢+@被踢人员
35 |
拥有管理权限或者群主才能操作
36 |
37 | ---
38 |
39 | ### 更新记录
40 | 2018.12.29
41 | 更新微信到7.0.1
42 | 2018.12.10
43 | 更新到微信最新版本
44 | 2018.10.24
45 | 新增红包黑名单,可以设置不想自动抢的群聊
46 | 2018.10.19
47 | 新增修改微信步数
48 | 2018.10.15
49 | 新增消息防撤回
50 |
51 | ---
52 |
53 | ### 免责声明
54 | 本项目仅用于学习,禁止用于商业及非法用途,如产生法律纠纷与本人无关。
55 |
--------------------------------------------------------------------------------