├── FuckDingTalk
├── TargetApp
│ └── put ipa or app here
├── MethodTraceConfig.plist
└── Info.plist
├── LatestBuild
├── FuckDingTalk.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── README.md
├── FuckDingTalkDylib
├── FuckDingTalkDylib-Prefix.pch
├── FuckDingTalkDylib.h
├── WrappedHUDHelper.h
├── DingtalkPluginConfig.h
├── MethodTrace
│ ├── MethodTrace.h
│ ├── ANYMethodLog.h
│ ├── MethodTrace.m
│ └── ANYMethodLog.m
├── FuckDingTalkDylib.xm
├── DingtalkPluginConfig.m
├── FuckDingTalkDylib.m
├── fishhook
│ ├── fishhook.h
│ └── fishhook.c
├── AntiAntiDebug
│ └── AntiAntiDebug.m
└── FuckDingTalkDylib.mm
└── .gitignore
/FuckDingTalk/TargetApp/put ipa or app here:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LatestBuild:
--------------------------------------------------------------------------------
1 | /Users/mac/Library/Developer/Xcode/DerivedData/FuckDingTalk-cirihzprbkdsboflmejauddxigux/Build/Products/Debug-iphoneos
--------------------------------------------------------------------------------
/FuckDingTalk.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FuckDingTalk
2 |
3 | 根据大佬的[DingtalkPod](https://github.com/deskOfDafa/DingtalkPod)进行修改的
4 |
5 | 开启方式:我的->设置->关于->版权信息
6 |
7 | 修改定位:在`DingtalkPluginConfig.m`中修改经纬度
8 |
9 | 经纬度获取:钉钉使用的是高德地图,可以在这里获取[经纬度](https://lbs.amap.com/console/show/picker)
10 |
11 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/FuckDingTalkDylib-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'FuckDingTalkDylib' target in the 'FuckDingTalkDylib' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import "/opt/theos/Prefix.pch" //path/to/theos/Prefix.pch
8 | #endif
9 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/FuckDingTalkDylib.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // FuckDingTalkDylib.h
5 | // FuckDingTalkDylib
6 | //
7 | // Created by 马旭 on 2017/11/1.
8 | // Copyright (c) 2017年 马旭. All rights reserved.
9 | //
10 |
11 | #import
12 |
13 |
14 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/WrappedHUDHelper.h:
--------------------------------------------------------------------------------
1 | //
2 | // WrappedHUDHelper.h
3 | // DingTalkFuckDylib
4 | //
5 | // Created by 马旭 on 2017/11/1.
6 | // Copyright © 2017年 马旭. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface WrappedHUDHelper : NSObject
12 | + (id)sharedHelper;
13 | - (void)showHUDOnFrontWithSuccessTitle:(id)arg1 duration:(unsigned long long)arg2 blockUI:(_Bool)arg3;
14 | - (void)showHUDOnFrontWithTitle:(id)arg1 duration:(unsigned long long)arg2;
15 | @end
16 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/DingtalkPluginConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // DingtalkPluginConfig.h
3 | // DingTalkFuckDylib
4 | //
5 | // Created by 马旭 on 2017/10/31.
6 | // Copyright © 2017年 马旭. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface DingtalkPluginConfig : NSObject
13 |
14 | +(DingtalkPluginConfig*)sharedInstance;
15 | /**
16 | 经纬度
17 | */
18 | @property(nonatomic, assign) CLLocationCoordinate2D location;
19 | @property(nonatomic, assign) BOOL open;
20 | @end
21 |
--------------------------------------------------------------------------------
/FuckDingTalk/MethodTraceConfig.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ENABLE_METHODTRACE
6 |
7 | TARGET_CLASS_LIST
8 |
9 | BaseMsgContentViewController
10 |
11 | CMessageMgr
12 |
13 | AsyncOnAddMsg:MsgWrap:
14 | onRevokeMsg:
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/MethodTrace/MethodTrace.h:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // Created by AloneMonkey on 2017/9/7.
5 | // Copyright © 2017年 AloneMonkey. All rights reserved.
6 | //
7 |
8 | #ifndef MethodTrace_h
9 | #define MethodTrace_h
10 |
11 | #import
12 |
13 | @interface MethodTrace : NSObject
14 |
15 | + (void)addClassTrace:(NSString*) className;
16 |
17 | + (void)addClassTrace:(NSString *)className methodName:(NSString*) methodName;
18 |
19 | + (void)addClassTrace:(NSString *)className methodList:(NSArray*) methodList;
20 |
21 | @end
22 |
23 | #endif /* MethodTrace_h */
24 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/FuckDingTalkDylib.xm:
--------------------------------------------------------------------------------
1 | // See http://iphonedevwiki.net/index.php/Logos
2 |
3 | #import
4 |
5 | %hook ClassName
6 |
7 | + (id)sharedInstance
8 | {
9 | %log;
10 |
11 | return %orig;
12 | }
13 |
14 | - (void)messageWithNoReturnAndOneArgument:(id)originalArgument
15 | {
16 | %log;
17 |
18 | %orig(originalArgument);
19 |
20 | // or, for exmaple, you could use a custom value instead of the original argument: %orig(customValue);
21 | }
22 |
23 | - (id)messageWithReturnAndNoArguments
24 | {
25 | %log;
26 |
27 | id originalReturnOfMessage = %orig;
28 |
29 | // for example, you could modify the original return value before returning it: [SomeOtherClass doSomethingToThisObject:originalReturnOfMessage];
30 |
31 | return originalReturnOfMessage;
32 | }
33 |
34 | %end
35 |
--------------------------------------------------------------------------------
/FuckDingTalk/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/DingtalkPluginConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // DingtalkPluginConfig.m
3 | // DingTalkFuckDylib
4 | //
5 | // Created by 马旭 on 2017/10/31.
6 | // Copyright © 2017年 马旭. All rights reserved.
7 | //
8 |
9 | #import "DingtalkPluginConfig.h"
10 | #import
11 |
12 | @implementation DingtalkPluginConfig
13 | + (instancetype)sharedInstance {
14 | static dispatch_once_t onceToken;
15 | static DingtalkPluginConfig *instance = nil;
16 | dispatch_once(&onceToken,^{
17 | instance = [[super allocWithZone:NULL] init];
18 | });
19 | return instance;
20 | }
21 |
22 | - (instancetype)init
23 | {
24 | self = [super init];
25 | if (self) {
26 | _location = CLLocationCoordinate2DMake(39.950506, 116.33732);
27 | _open = NO;
28 | }
29 | return self;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/MethodTrace/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 |
--------------------------------------------------------------------------------
/.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 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## MonkeyDev
21 | *.app
22 |
23 | ## Other
24 | *.moved-aside
25 | *.xccheckout
26 | *.xcscmblueprint
27 |
28 | ## Obj-C/Swift specific
29 | *.hmap
30 | *.ipa
31 | *.dSYM.zip
32 | *.dSYM
33 |
34 | # CocoaPods
35 | #
36 | # We recommend against adding the Pods directory to your .gitignore. However
37 | # you should judge for yourself, the pros and cons are mentioned at:
38 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
39 | #
40 | # Pods/
41 |
42 | # Carthage
43 | #
44 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
45 | # Carthage/Checkouts
46 |
47 | Carthage/Build
48 |
49 | # fastlane
50 | #
51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
52 | # screenshots whenever they are needed.
53 | # For more information about the recommended setup visit:
54 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
55 |
56 | fastlane/report.xml
57 | fastlane/Preview.html
58 | fastlane/screenshots
59 | fastlane/test_output
60 |
61 | # Code Injection
62 | #
63 | # After new code Injection tools there's a generated folder /iOSInjectionProject
64 | # https://github.com/johnno1962/injectionforxcode
65 |
66 | iOSInjectionProject/
67 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/FuckDingTalkDylib.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // FuckDingTalkDylib.m
5 | // FuckDingTalkDylib
6 | //
7 | // Created by 马旭 on 2017/11/1.
8 | // Copyright (c) 2017年 马旭. All rights reserved.
9 | //
10 |
11 | #import "FuckDingTalkDylib.h"
12 | #import
13 | #import
14 | #import
15 | #import "DingtalkPluginConfig.h"
16 | #import "DingtalkPluginConfig.h"
17 | #import "WrappedHUDHelper.h"
18 |
19 |
20 | CHDeclareClass(CLLocation);
21 |
22 | CHOptimizedMethod0(self, CLLocationCoordinate2D, CLLocation, coordinate){
23 | CLLocationCoordinate2D coordinate = CHSuper(0, CLLocation, coordinate);
24 | if([DingtalkPluginConfig sharedInstance].open){
25 | CLLocationDegrees latitude = [DingtalkPluginConfig sharedInstance].location.latitude - (arc4random()%150) / 1000000.0;
26 | CLLocationDegrees longitude = [DingtalkPluginConfig sharedInstance].location.longitude - (arc4random()%150) / 1000000.0;
27 | coordinate = CLLocationCoordinate2DMake(latitude, longitude);
28 | }
29 | return coordinate;
30 | }
31 | CHConstructor{
32 | CHLoadLateClass(CLLocation);
33 | CHClassHook(0, CLLocation, coordinate);
34 | }
35 |
36 | CHDeclareClass(DTAboutDingController);
37 | CHOptimizedMethod0(self, void, DTAboutDingController, copyright) {
38 | [DingtalkPluginConfig sharedInstance].open = ![DingtalkPluginConfig sharedInstance].open;
39 | NSString *str = [DingtalkPluginConfig sharedInstance].open ? @"FakeGPS" : @"Good Boy";
40 | [(WrappedHUDHelper *)[NSClassFromString(@"WrappedHUDHelper") sharedHelper] showHUDOnFrontWithTitle:str duration:1];
41 | }
42 | CHConstructor{
43 | CHLoadLateClass(DTAboutDingController);
44 | CHClassHook(0, DTAboutDingController,copyright);
45 | }
46 |
47 | CHDeclareClass(AMapGeoFenceManager);
48 | CHMethod(0, BOOL,AMapGeoFenceManager,detectRiskOfFakeLocation){
49 |
50 | return NO;
51 | }
52 | CHMethod(0, BOOL,AMapGeoFenceManager,pausesLocationUpdatesAutomatically){
53 |
54 | return NO;
55 | }
56 | CHConstructor{
57 | CHLoadLateClass(AMapGeoFenceManager);
58 | CHClassHook(0, AMapGeoFenceManager,detectRiskOfFakeLocation);
59 | CHClassHook(0, AMapGeoFenceManager,pausesLocationUpdatesAutomatically);
60 | }
61 |
62 |
63 | CHDeclareClass(AMapLocationManager);
64 | CHMethod(0, BOOL,AMapLocationManager,detectRiskOfFakeLocation){
65 | return NO;
66 | }
67 | CHMethod(0, BOOL,AMapLocationManager,pausesLocationUpdatesAutomatically){
68 |
69 | return NO;
70 | }
71 | CHConstructor{
72 | CHLoadLateClass(AMapLocationManager);
73 | CHClassHook(0, AMapLocationManager,detectRiskOfFakeLocation);
74 | CHClassHook(0, AMapLocationManager,pausesLocationUpdatesAutomatically);
75 | }
76 |
77 |
78 | CHDeclareClass(DTALocationManager);
79 | CHMethod(0, BOOL,DTALocationManager,detectRiskOfFakeLocation){
80 | return NO;
81 | }
82 | CHMethod(0, BOOL,DTALocationManager,dt_pausesLocationUpdatesAutomatically){
83 | return NO;
84 | }
85 | CHConstructor{
86 | CHLoadLateClass(DTALocationManager);
87 | CHClassHook(0, DTALocationManager,detectRiskOfFakeLocation);
88 | CHClassHook(0, DTALocationManager,dt_pausesLocationUpdatesAutomatically);
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/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 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/MethodTrace/MethodTrace.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // Created by AloneMonkey on 2017/9/6.
5 | // Copyright © 2017年 AloneMonkey. All rights reserved.
6 | //
7 |
8 | #import "ANYMethodLog.h"
9 | #import "MethodTrace.h"
10 | #import
11 | #import
12 |
13 | @implementation MethodTrace : NSObject
14 |
15 | +(void)addClassTrace:(NSString *)className{
16 | [self addClassTrace:className methodList:nil];
17 | }
18 |
19 | +(void)addClassTrace:(NSString *)className methodName:(NSString *)methodName{
20 | [self addClassTrace:className methodList:@[methodName]];
21 | }
22 |
23 | +(void)addClassTrace:(NSString *)className methodList:(NSArray *)methodList{
24 | Class targetClass = objc_getClass([className UTF8String]);
25 | if(targetClass != nil){
26 | [ANYMethodLog logMethodWithClass:NSClassFromString(className) condition:^BOOL(SEL sel) {
27 | return (methodList == nil || methodList.count == 0) ? YES : [methodList containsObject:NSStringFromSelector(sel)];
28 | } before:^(id target, SEL sel, NSArray *args, int deep) {
29 | NSString *selector = NSStringFromSelector(sel);
30 | NSArray *selectorArrary = [selector componentsSeparatedByString:@":"];
31 | selectorArrary = [selectorArrary filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];
32 | NSMutableString *selectorString = [NSMutableString new];
33 | for (int i = 0; i < selectorArrary.count; i++) {
34 | [selectorString appendFormat:@"%@:%@ ", selectorArrary[i], args[i]];
35 | }
36 | NSMutableString *deepString = [NSMutableString new];
37 | for (int i = 0; i < deep; i++) {
38 | [deepString appendString:@"-"];
39 | }
40 | NSLog(@"%@[%@ %@]", deepString , target, selectorString);
41 | } after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval,int deep, id retValue) {
42 | NSMutableString *deepString = [NSMutableString new];
43 | for (int i = 0; i < deep; i++) {
44 | [deepString appendString:@"-"];
45 | }
46 | NSLog(@"%@ret:%@", deepString, retValue);
47 | }];
48 | }else{
49 | NSLog(@"canot find class %@", className);
50 | }
51 | }
52 |
53 | @end
54 |
55 | static __attribute__((constructor)) void entry(){
56 | NSString* configFilePath = [[NSBundle mainBundle] pathForResource:@"MethodTraceConfig" ofType:@"plist"];
57 | if(configFilePath == nil){
58 | NSLog(@"MethodTraceConfig.plist file is not exits!!!");
59 | return;
60 | }
61 | NSMutableDictionary *configItem = [NSMutableDictionary dictionaryWithContentsOfFile:configFilePath];
62 | BOOL isEnable = [[configItem valueForKey:@"ENABLE_METHODTRACE"] boolValue];
63 | if(isEnable){
64 | NSDictionary* classListDictionary = [configItem valueForKey:@"TARGET_CLASS_LIST"];
65 | for (NSString* className in classListDictionary.allKeys) {
66 | Class targetClass = objc_getClass([className UTF8String]);
67 | if(targetClass != nil){
68 | id methodList = [classListDictionary valueForKey:className];
69 | if([methodList isKindOfClass:[NSArray class]]){
70 | [MethodTrace addClassTrace:className methodList:methodList];
71 | }else{
72 | [MethodTrace addClassTrace:className];
73 | }
74 | }else{
75 | NSLog(@"canot find class %@", className);
76 | }
77 | }
78 | }else{
79 | NSLog(@"Method Trace is disable");
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/AntiAntiDebug/AntiAntiDebug.m:
--------------------------------------------------------------------------------
1 | // weibo: http://weibo.com/xiaoqing28
2 | // blog: http://www.alonemonkey.com
3 | //
4 | // Created by AloneMonkey on 2016/12/10.
5 | // Copyright © 2017年 Coder. All rights reserved.
6 | //
7 |
8 | #import "fishhook.h"
9 | #import
10 | #import
11 |
12 | typedef int (*ptrace_ptr_t)(int _request,pid_t _pid, caddr_t _addr,int _data);
13 | typedef void* (*dlsym_ptr_t)(void * __handle, const char* __symbol);
14 | typedef int (*syscall_ptr_t)(int, ...);
15 | typedef int (*sysctl_ptr_t)(int *,u_int, void*, size_t*,void*, size_t);
16 |
17 |
18 | static ptrace_ptr_t orig_ptrace = NULL;
19 | static dlsym_ptr_t orig_dlsym = NULL;
20 | static sysctl_ptr_t orig_sysctl = NULL;
21 | static syscall_ptr_t orig_syscall = NULL;
22 |
23 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
24 | void* my_dlsym(void* __handle, const char* __symbol);
25 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize);
26 | int my_syscall(int code, va_list args);
27 |
28 | int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){
29 | if(_request != 31){
30 | return orig_ptrace(_request,_pid,_addr,_data);
31 | }
32 |
33 | NSLog(@"[AntiAntiDebug] - ptrace request is PT_DENY_ATTACH");
34 |
35 | return 0;
36 | }
37 |
38 | void* my_dlsym(void* __handle, const char* __symbol){
39 | if(strcmp(__symbol, "ptrace") != 0){
40 | return orig_dlsym(__handle, __symbol);
41 | }
42 |
43 | NSLog(@"[AntiAntiDebug] - dlsym get ptrace symbol");
44 |
45 | return my_ptrace;
46 | }
47 |
48 | typedef struct kinfo_proc _kinfo_proc;
49 |
50 | int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){
51 | int ret = orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize);
52 | if(namelen == 4 && name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID && info && infosize && (*infosize == sizeof(_kinfo_proc))){
53 | struct kinfo_proc *info_ptr = (struct kinfo_proc *)info;
54 | if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){
55 | NSLog(@"[AntiAntiDebug] - sysctl query trace status.");
56 | info_ptr->kp_proc.p_flag ^= P_TRACED;
57 | if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){
58 | NSLog(@"trace status reomve success!");
59 | }
60 | }
61 | }
62 | return ret;
63 | }
64 |
65 | int my_syscall(int code, va_list args){
66 | int request;
67 | va_list newArgs;
68 | va_copy(newArgs, args);
69 | if(code == 26){
70 | #ifdef __LP64__
71 | __asm__(
72 | "ldr %w[result], [fp, #0x10]\n"
73 | : [result] "=r" (request)
74 | :
75 | :
76 | );
77 | #else
78 | request = va_arg(args, int);
79 | #endif
80 | if(request == 31){
81 | NSLog(@"[AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH");
82 | return 0;
83 | }
84 | }
85 | return orig_syscall(code, newArgs);
86 | }
87 |
88 | __attribute__((constructor)) static void entry(){
89 | NSLog(@"[AntiAntiDebug Init]");
90 |
91 | rebind_symbols((struct rebinding[1]){{"ptrace", my_ptrace, (void*)&orig_ptrace}},1);
92 |
93 | rebind_symbols((struct rebinding[1]){{"dlsym", my_dlsym, (void*)&orig_dlsym}},1);
94 |
95 | //some app will crash with _dyld_debugger_notification
96 | //rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1);
97 |
98 | rebind_symbols((struct rebinding[1]){{"syscall", my_syscall, (void*)&orig_syscall}},1);
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/FuckDingTalkDylib.mm:
--------------------------------------------------------------------------------
1 | #line 1 "/Users/mac/code/jailbreak/FuckDingTalk/FuckDingTalkDylib/FuckDingTalkDylib.xm"
2 |
3 |
4 | #import
5 |
6 |
7 | #include
8 | #if defined(__clang__)
9 | #if __has_feature(objc_arc)
10 | #define _LOGOS_SELF_TYPE_NORMAL __unsafe_unretained
11 | #define _LOGOS_SELF_TYPE_INIT __attribute__((ns_consumed))
12 | #define _LOGOS_SELF_CONST const
13 | #define _LOGOS_RETURN_RETAINED __attribute__((ns_returns_retained))
14 | #else
15 | #define _LOGOS_SELF_TYPE_NORMAL
16 | #define _LOGOS_SELF_TYPE_INIT
17 | #define _LOGOS_SELF_CONST
18 | #define _LOGOS_RETURN_RETAINED
19 | #endif
20 | #else
21 | #define _LOGOS_SELF_TYPE_NORMAL
22 | #define _LOGOS_SELF_TYPE_INIT
23 | #define _LOGOS_SELF_CONST
24 | #define _LOGOS_RETURN_RETAINED
25 | #endif
26 |
27 | @class ClassName;
28 | static id (*_logos_meta_orig$_ungrouped$ClassName$sharedInstance)(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST, SEL); static id _logos_meta_method$_ungrouped$ClassName$sharedInstance(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST, SEL); static void (*_logos_orig$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$)(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST, SEL, id); static void _logos_method$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST, SEL, id); static id (*_logos_orig$_ungrouped$ClassName$messageWithReturnAndNoArguments)(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST, SEL); static id _logos_method$_ungrouped$ClassName$messageWithReturnAndNoArguments(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST, SEL);
29 |
30 | #line 5 "/Users/mac/code/jailbreak/FuckDingTalk/FuckDingTalkDylib/FuckDingTalkDylib.xm"
31 |
32 |
33 |
34 | static id _logos_meta_method$_ungrouped$ClassName$sharedInstance(_LOGOS_SELF_TYPE_NORMAL Class _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
35 | HBLogDebug(@"+[ sharedInstance]", self);
36 |
37 | return _logos_meta_orig$_ungrouped$ClassName$sharedInstance(self, _cmd);
38 | }
39 |
40 |
41 | static void _logos_method$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, id originalArgument) {
42 | HBLogDebug(@"-[ messageWithNoReturnAndOneArgument:%@]", self, originalArgument);
43 |
44 | _logos_orig$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$(self, _cmd, originalArgument);
45 |
46 |
47 | }
48 |
49 |
50 | static id _logos_method$_ungrouped$ClassName$messageWithReturnAndNoArguments(_LOGOS_SELF_TYPE_NORMAL ClassName* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
51 | HBLogDebug(@"-[ messageWithReturnAndNoArguments]", self);
52 |
53 | id originalReturnOfMessage = _logos_orig$_ungrouped$ClassName$messageWithReturnAndNoArguments(self, _cmd);
54 |
55 |
56 |
57 | return originalReturnOfMessage;
58 | }
59 |
60 |
61 | static __attribute__((constructor)) void _logosLocalInit() {
62 | {Class _logos_class$_ungrouped$ClassName = objc_getClass("ClassName"); Class _logos_metaclass$_ungrouped$ClassName = object_getClass(_logos_class$_ungrouped$ClassName); MSHookMessageEx(_logos_metaclass$_ungrouped$ClassName, @selector(sharedInstance), (IMP)&_logos_meta_method$_ungrouped$ClassName$sharedInstance, (IMP*)&_logos_meta_orig$_ungrouped$ClassName$sharedInstance);MSHookMessageEx(_logos_class$_ungrouped$ClassName, @selector(messageWithNoReturnAndOneArgument:), (IMP)&_logos_method$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$, (IMP*)&_logos_orig$_ungrouped$ClassName$messageWithNoReturnAndOneArgument$);MSHookMessageEx(_logos_class$_ungrouped$ClassName, @selector(messageWithReturnAndNoArguments), (IMP)&_logos_method$_ungrouped$ClassName$messageWithReturnAndNoArguments, (IMP*)&_logos_orig$_ungrouped$ClassName$messageWithReturnAndNoArguments);} }
63 | #line 35 "/Users/mac/code/jailbreak/FuckDingTalk/FuckDingTalkDylib/FuckDingTalkDylib.xm"
64 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/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 |
--------------------------------------------------------------------------------
/FuckDingTalkDylib/MethodTrace/ANYMethodLog.m:
--------------------------------------------------------------------------------
1 | //
2 | // ANYMethodLog.m
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 | /*经实践打印出不同类型占的长度,放此以方便调试查看
12 | +---------------------------+------------+------------+--------+
13 | | type | value(32) | value(64) | comp |
14 | |---------------------------|------------|------------|--------|
15 | | sizeof(char) | 1 | 1 | |
16 | |---------------------------|------------|------------|--------|
17 | | sizeof(int) | 4 | 4 | |
18 | |---------------------------|------------|------------|--------|
19 | | sizeof(short) | 2 | 2 | |
20 | |---------------------------|------------|------------|--------|
21 | | sizeof(long) | 4 | 8 | * |
22 | |---------------------------|------------|------------|--------|
23 | | sizeof(long long) | 8 | 8 | |
24 | |---------------------------|------------|------------|--------|
25 | | sizeof(unsigned char) | 1 | 1 | |
26 | |---------------------------|------------|------------|--------|
27 | | sizeof(unsigned int) | 4 | 4 | |
28 | |---------------------------|------------|------------|--------|
29 | | sizeof(unsigned short) | 2 | 2 | |
30 | |---------------------------|------------|------------|--------|
31 | | sizeof(unsigned long) | 4 | 8 | * |
32 | |---------------------------|------------|------------|--------|
33 | | sizeof(unsigned long long)| 8 | 8 | |
34 | |---------------------------|------------|------------|--------|
35 | | sizeof(float) | 4 | 4 | |
36 | |---------------------------|------------|------------|--------|
37 | | sizeof(double) | 8 | 8 | |
38 | |---------------------------|------------|------------|--------|
39 | | sizeof(BOOL) | 1 | 1 | |
40 | |---------------------------|------------|------------|--------|
41 | | sizeof(void) | 1 | 1 | |
42 | |---------------------------|------------|------------|--------|
43 | | sizeof(char*) | 4 | 8 | * |
44 | |---------------------------|------------|------------|--------|
45 | | sizeof(id) | 4 | 8 | * |
46 | |---------------------------|------------|------------|--------|
47 | | sizeof(Class) | 4 | 8 | * |
48 | |---------------------------|------------|------------|--------|
49 | | sizeof(SEL) | 4 | 8 | * |
50 | +---------------------------+------------+------------+--------+
51 | */
52 |
53 | #import "ANYMethodLog.h"
54 | #import
55 | #import
56 | #import
57 |
58 | #pragma mark - deep
59 |
60 | //调用层次
61 | static int deep = -1;
62 |
63 | #pragma mark - Func Define
64 |
65 | BOOL qhd_isInBlackList(NSString *methodName);
66 | NSDictionary *qhd_canHandleTypeDic(void);
67 | BOOL qhd_isCanHandle(NSString *typeEncode);
68 | SEL qhd_createNewSelector(SEL originalSelector);
69 | BOOL qhd_isStructType(const char *argumentType);
70 | NSString *qhd_structName(const char *argumentType);
71 | BOOL isCGRect (const char *type);
72 | BOOL isCGPoint (const char *type);
73 | BOOL isCGSize (const char *type);
74 | BOOL isCGVector (const char *type);
75 | BOOL isUIOffset (const char *type);
76 | BOOL isUIEdgeInsets (const char *type);
77 | BOOL isCGAffineTransform(const char *type);
78 | BOOL qhd_isCanHook(Method method, const char *returnType);
79 | id getReturnValue(NSInvocation *invocation);
80 | NSArray *qhd_method_arguments(NSInvocation *invocation);
81 | void qhd_forwardInvocation(id target, SEL selector, NSInvocation *invocation);
82 | BOOL qhd_replaceMethod(Class cls, SEL originSelector, char *returnType);
83 | void qhd_logMethod(Class aClass, BOOL(^condition)(SEL sel));
84 |
85 | #pragma mark - AMLBlock
86 |
87 | @interface AMLBlock : NSObject
88 |
89 | @property (strong, nonatomic) NSString *targetClassName;
90 | @property (copy, nonatomic) ConditionBlock condition;
91 | @property (copy, nonatomic) BeforeBlock before;
92 | @property (copy, nonatomic) AfterBlock after;
93 |
94 | @end
95 |
96 | @implementation AMLBlock
97 |
98 | - (BOOL)runCondition:(SEL)sel {
99 | if (self.condition) {
100 | return self.condition(sel);
101 | } else {
102 | return YES;
103 | }
104 | }
105 |
106 | - (void)rundBefore:(id)target sel:(SEL)sel args:(NSArray *)args deep:(int) deep {
107 | if (self.before) {
108 | self.before(target, sel, args, deep);
109 | }
110 | }
111 |
112 | - (void)rundAfter:(id)target sel:(SEL)sel args:(NSArray *)args interval:(NSTimeInterval)interval deep:(int)deep retValue:(id)retValue{
113 | if (self.after) {
114 | self.after(target, sel, args, interval, deep, retValue);
115 | }
116 | }
117 |
118 | @end
119 |
120 |
121 | #pragma mark - ANYMethodLog private interface
122 |
123 | @interface ANYMethodLog()
124 |
125 | @property (strong, nonatomic) NSMutableDictionary *blockCache;
126 |
127 | + (instancetype)sharedANYMethodLog;
128 |
129 | - (void)setAMLBlock:(AMLBlock *)block forKey:(NSString *)aKey;
130 |
131 | - (AMLBlock *)blockWithTarget:(id)target;
132 |
133 | @end
134 |
135 |
136 | #pragma mark - C function
137 |
138 | #define SHARED_ANYMETHODLOG [ANYMethodLog sharedANYMethodLog]
139 |
140 | //#define OPEN_TARGET_LOG
141 |
142 | #ifdef OPEN_TARGET_LOG
143 | #define TARGET_LOG(format, ...) NSLog(format, ## __VA_ARGS__)
144 | #else
145 | #define TARGET_LOG(format, ...)
146 | #endif
147 |
148 |
149 | //#define OPEN_DEV_LOG
150 |
151 | #ifdef OPEN_DEV_LOG
152 | #define DEV_LOG(format, ...) NSLog(format, ## __VA_ARGS__)
153 | #else
154 | #define DEV_LOG(format, ...)
155 | #endif
156 |
157 | //是否在默认的黑名单中
158 | BOOL qhd_isInBlackList(NSString *methodName) {
159 | static NSArray *defaultBlackList = nil;
160 | static dispatch_once_t onceToken;
161 | dispatch_once(&onceToken, ^{
162 | defaultBlackList = @[/*UIViewController的:*/@".cxx_destruct", @"dealloc", @"_isDeallocating", @"release", @"autorelease", @"retain", @"Retain", @"_tryRetain", @"copy", /*UIView的:*/ @"nsis_descriptionOfVariable:", /*NSObject的:*/@"respondsToSelector:", @"class", @"methodSignatureForSelector:", @"allowsWeakReference", @"retainWeakReference", @"init", @"forwardInvocation:"];
163 | });
164 | return ([defaultBlackList containsObject:methodName]);
165 | }
166 |
167 | /*reference: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100-SW1
168 | 经实践发现与文档有差别
169 | 1.在64位时@encode(long)跟@encode(long long)的值一样;
170 | 2.在64位时@encode(unsigned long)跟@encode(unsigned long long)的值一样;
171 | 3.在32位时@encode(BOOL)跟@encode(char)一样。
172 | +--------------------+-----------+-----------+
173 | | type |code(32bit)|code(64bit)|
174 | |--------------------|-----------|-----------|
175 | | BOOL | c | B |
176 | |--------------------|-----------|-----------|
177 | | char | c | c |
178 | |--------------------|-----------|-----------|
179 | | long | l | q |
180 | |--------------------|-----------|-----------|
181 | | long long | q | q |
182 | |--------------------|-----------|-----------|
183 | | unsigned long | L | Q |
184 | |--------------------|-----------|-----------|
185 | | unsigned long long | Q | Q |
186 | +--------------------+-----------+-----------+
187 | */
188 | NSDictionary *qhd_canHandleTypeDic() {
189 | static NSDictionary *dic = nil;
190 | static dispatch_once_t onceToken;
191 | dispatch_once(&onceToken, ^{
192 | dic = @{[NSString stringWithUTF8String:@encode(char)] : @"(char)",
193 | [NSString stringWithUTF8String:@encode(int)] : @"(int)",
194 | [NSString stringWithUTF8String:@encode(short)] : @"(short)",
195 | [NSString stringWithUTF8String:@encode(long)] : @"(long)",
196 | [NSString stringWithUTF8String:@encode(long long)] : @"(long long)",
197 | [NSString stringWithUTF8String:@encode(unsigned char)] : @"(unsigned char))",
198 | [NSString stringWithUTF8String:@encode(unsigned int)] : @"(unsigned int)",
199 | [NSString stringWithUTF8String:@encode(unsigned short)] : @"(unsigned short)",
200 | [NSString stringWithUTF8String:@encode(unsigned long)] : @"(unsigned long)",
201 | [NSString stringWithUTF8String:@encode(unsigned long long)] : @"(unsigned long long)",
202 | [NSString stringWithUTF8String:@encode(float)] : @"(float)",
203 | [NSString stringWithUTF8String:@encode(double)] : @"(double)",
204 | [NSString stringWithUTF8String:@encode(BOOL)] : @"(BOOL)",
205 | [NSString stringWithUTF8String:@encode(void)] : @"(void)",
206 | [NSString stringWithUTF8String:@encode(char *)] : @"(char *)",
207 | [NSString stringWithUTF8String:@encode(id)] : @"(id)",
208 | [NSString stringWithUTF8String:@encode(Class)] : @"(Class)",
209 | [NSString stringWithUTF8String:@encode(SEL)] : @"(SEL)",
210 | [NSString stringWithUTF8String:@encode(CGRect)] : @"(CGRect)",
211 | [NSString stringWithUTF8String:@encode(CGPoint)] : @"(CGPoint)",
212 | [NSString stringWithUTF8String:@encode(CGSize)] : @"(CGSize)",
213 | [NSString stringWithUTF8String:@encode(CGVector)] : @"(CGVector)",
214 | [NSString stringWithUTF8String:@encode(CGAffineTransform)] : @"(CGAffineTransform)",
215 | [NSString stringWithUTF8String:@encode(UIOffset)] : @"(UIOffset)",
216 | [NSString stringWithUTF8String:@encode(UIEdgeInsets)] : @"(UIEdgeInsets)",
217 | @"@?":@"(block)" // block类型
218 | };//TODO:添加其他类型
219 | });
220 | return dic;
221 | }
222 |
223 | //根据定义的类型的判断是否能处理
224 | BOOL qhd_isCanHandle(NSString *typeEncode) {
225 | return [qhd_canHandleTypeDic().allKeys containsObject:typeEncode];
226 | }
227 |
228 | //创建一个新的selector
229 | SEL qhd_createNewSelector(SEL originalSelector) {
230 | NSString *oldSelectorName = NSStringFromSelector(originalSelector);
231 | NSString *newSelectorName = [NSString stringWithFormat:@"qhd_%@", oldSelectorName];
232 | SEL newSelector = NSSelectorFromString(newSelectorName);
233 | return newSelector;
234 | }
235 |
236 | //是否struct类型
237 | BOOL qhd_isStructType(const char *argumentType) {
238 | NSString *typeString = [NSString stringWithUTF8String:argumentType];
239 | return ([typeString hasPrefix:@"{"] && [typeString hasSuffix:@"}"]);
240 | }
241 |
242 | //struct类型名
243 | NSString *qhd_structName(const char *argumentType) {
244 | NSString *typeString = [NSString stringWithUTF8String:argumentType];
245 | NSUInteger start = [typeString rangeOfString:@"{"].location;
246 | NSUInteger end = [typeString rangeOfString:@"="].location;
247 | if (end > start) {
248 | return [typeString substringWithRange:NSMakeRange(start + 1, end - start - 1)];
249 | } else {
250 | return nil;
251 | }
252 | }
253 |
254 | BOOL isCGRect (const char *type) {return [qhd_structName(type) isEqualToString:@"CGRect"];}
255 | BOOL isCGPoint (const char *type) {return [qhd_structName(type) isEqualToString:@"CGPoint"];}
256 | BOOL isCGSize (const char *type) {return [qhd_structName(type) isEqualToString:@"CGSize"];}
257 | BOOL isCGVector (const char *type) {return [qhd_structName(type) isEqualToString:@"CGVector"];}
258 | BOOL isUIOffset (const char *type) {return [qhd_structName(type) isEqualToString:@"UIOffset"];}
259 | BOOL isUIEdgeInsets (const char *type) {return [qhd_structName(type) isEqualToString:@"UIEdgeInsets"];}
260 | BOOL isCGAffineTransform(const char *type) {return [qhd_structName(type) isEqualToString:@"CGAffineTransform"];}
261 |
262 | //检查是否能处理
263 | BOOL qhd_isCanHook(Method method, const char *returnType) {
264 |
265 | //若在黑名单中则不处理
266 | NSString *selectorName = NSStringFromSelector(method_getName(method));
267 | if (qhd_isInBlackList(selectorName)) {
268 | return NO;
269 | }
270 |
271 | if ([selectorName rangeOfString:@"qhd_"].location != NSNotFound) {
272 | return NO;
273 | }
274 |
275 | NSString *returnTypeString = [NSString stringWithUTF8String:returnType];
276 |
277 | BOOL isCanHook = YES;
278 | if (!qhd_isCanHandle(returnTypeString)) {
279 | isCanHook = NO;
280 | }
281 | for(int k = 2 ; k < method_getNumberOfArguments(method); k ++) {
282 | char argument[250];
283 | memset(argument, 0, sizeof(argument));
284 | method_getArgumentType(method, k, argument, sizeof(argument));
285 | NSString *argumentString = [NSString stringWithUTF8String:argument];
286 | if (!qhd_isCanHandle(argumentString)) {
287 | isCanHook = NO;
288 | break;
289 | }
290 | }
291 | return isCanHook;
292 | }
293 |
294 | //获取方法返回值
295 | id getReturnValue(NSInvocation *invocation){
296 | const char *returnType = invocation.methodSignature.methodReturnType;
297 | if (returnType[0] == 'r') {
298 | returnType++;
299 | }
300 | #define WRAP_GET_VALUE(type) \
301 | do { \
302 | type val = 0; \
303 | [invocation getReturnValue:&val]; \
304 | return @(val); \
305 | } while (0)
306 | if (strcmp(returnType, @encode(id)) == 0 || strcmp(returnType, @encode(Class)) == 0 || strcmp(returnType, @encode(void (^)(void))) == 0) {
307 | __autoreleasing id returnObj;
308 | [invocation getReturnValue:&returnObj];
309 | return returnObj;
310 | } else if (strcmp(returnType, @encode(char)) == 0) {
311 | WRAP_GET_VALUE(char);
312 | } else if (strcmp(returnType, @encode(int)) == 0) {
313 | WRAP_GET_VALUE(int);
314 | } else if (strcmp(returnType, @encode(short)) == 0) {
315 | WRAP_GET_VALUE(short);
316 | } else if (strcmp(returnType, @encode(long)) == 0) {
317 | WRAP_GET_VALUE(long);
318 | } else if (strcmp(returnType, @encode(long long)) == 0) {
319 | WRAP_GET_VALUE(long long);
320 | } else if (strcmp(returnType, @encode(unsigned char)) == 0) {
321 | WRAP_GET_VALUE(unsigned char);
322 | } else if (strcmp(returnType, @encode(unsigned int)) == 0) {
323 | WRAP_GET_VALUE(unsigned int);
324 | } else if (strcmp(returnType, @encode(unsigned short)) == 0) {
325 | WRAP_GET_VALUE(unsigned short);
326 | } else if (strcmp(returnType, @encode(unsigned long)) == 0) {
327 | WRAP_GET_VALUE(unsigned long);
328 | } else if (strcmp(returnType, @encode(unsigned long long)) == 0) {
329 | WRAP_GET_VALUE(unsigned long long);
330 | } else if (strcmp(returnType, @encode(float)) == 0) {
331 | WRAP_GET_VALUE(float);
332 | } else if (strcmp(returnType, @encode(double)) == 0) {
333 | WRAP_GET_VALUE(double);
334 | } else if (strcmp(returnType, @encode(BOOL)) == 0) {
335 | WRAP_GET_VALUE(BOOL);
336 | } else if (strcmp(returnType, @encode(char *)) == 0) {
337 | WRAP_GET_VALUE(const char *);
338 | } else if (strcmp(returnType, @encode(void)) == 0) {
339 | return @"void";
340 | } else {
341 | NSUInteger valueSize = 0;
342 | NSGetSizeAndAlignment(returnType, &valueSize, NULL);
343 | unsigned char valueBytes[valueSize];
344 | [invocation getReturnValue:valueBytes];
345 |
346 | return [NSValue valueWithBytes:valueBytes objCType:returnType];
347 | }
348 | return nil;
349 | }
350 |
351 | //获取方法参数
352 | NSArray *qhd_method_arguments(NSInvocation *invocation) {
353 | NSMethodSignature *methodSignature = [invocation methodSignature];
354 | NSMutableArray *argList = (methodSignature.numberOfArguments > 2 ? [NSMutableArray array] : nil);
355 | for (NSUInteger i = 2; i < methodSignature.numberOfArguments; i++) {
356 | const char *argumentType = [methodSignature getArgumentTypeAtIndex:i];
357 | id arg = nil;
358 |
359 | if (qhd_isStructType(argumentType)) {
360 | #define GET_STRUCT_ARGUMENT(_type)\
361 | if (is##_type(argumentType)) {\
362 | _type arg_temp;\
363 | [invocation getArgument:&arg_temp atIndex:i];\
364 | arg = NSStringFrom##_type(arg_temp);\
365 | }
366 | GET_STRUCT_ARGUMENT(CGRect)
367 | else GET_STRUCT_ARGUMENT(CGPoint)
368 | else GET_STRUCT_ARGUMENT(CGSize)
369 | else GET_STRUCT_ARGUMENT(CGVector)
370 | else GET_STRUCT_ARGUMENT(UIOffset)
371 | else GET_STRUCT_ARGUMENT(UIEdgeInsets)
372 | else GET_STRUCT_ARGUMENT(CGAffineTransform)
373 |
374 | if (arg == nil) {
375 | arg = @"{unknown}";
376 | }
377 | }
378 | #define GET_ARGUMENT(_type)\
379 | if (0 == strcmp(argumentType, @encode(_type))) {\
380 | _type arg_temp;\
381 | [invocation getArgument:&arg_temp atIndex:i];\
382 | arg = @(arg_temp);\
383 | }
384 | else GET_ARGUMENT(char)
385 | else GET_ARGUMENT(int)
386 | else GET_ARGUMENT(short)
387 | else GET_ARGUMENT(long)
388 | else GET_ARGUMENT(long long)
389 | else GET_ARGUMENT(unsigned char)
390 | else GET_ARGUMENT(unsigned int)
391 | else GET_ARGUMENT(unsigned short)
392 | else GET_ARGUMENT(unsigned long)
393 | else GET_ARGUMENT(unsigned long long)
394 | else GET_ARGUMENT(float)
395 | else GET_ARGUMENT(double)
396 | else GET_ARGUMENT(BOOL)
397 | else if (0 == strcmp(argumentType, @encode(id))) {
398 | __unsafe_unretained id arg_temp;
399 | [invocation getArgument:&arg_temp atIndex:i];
400 | arg = arg_temp;
401 | }
402 | else if (0 == strcmp(argumentType, @encode(SEL))) {
403 | SEL arg_temp;
404 | [invocation getArgument:&arg_temp atIndex:i];
405 | arg = NSStringFromSelector(arg_temp);
406 | }
407 | else if (0 == strcmp(argumentType, @encode(char *))) {
408 | char *arg_temp;
409 | [invocation getArgument:&arg_temp atIndex:i];
410 | arg = [NSString stringWithUTF8String:arg_temp];
411 | }
412 | else if (0 == strcmp(argumentType, @encode(void *))) {
413 | void *arg_temp;
414 | [invocation getArgument:&arg_temp atIndex:i];
415 | arg = (__bridge id _Nonnull)arg_temp;
416 | }
417 | else if (0 == strcmp(argumentType, @encode(Class))) {
418 | Class arg_temp;
419 | [invocation getArgument:&arg_temp atIndex:i];
420 | arg = arg_temp;
421 | }
422 |
423 | if (!arg) {
424 | arg = @"unknown";
425 | }
426 | [argList addObject:arg];
427 | }
428 | return argList;
429 | }
430 |
431 | //forwardInvocation:方法的新IMP
432 | void qhd_forwardInvocation(id target, SEL selector, NSInvocation *invocation) {
433 | NSArray *argList = qhd_method_arguments(invocation);
434 |
435 | SEL originSelector = invocation.selector;
436 |
437 | NSString *originSelectorString = NSStringFromSelector(originSelector);
438 |
439 | //友盟的UMAOCTools会产生问题
440 | if ([originSelectorString rangeOfString:@"hook_"].location != NSNotFound) {
441 | return;
442 | }
443 |
444 | [invocation setSelector:qhd_createNewSelector(originSelector)];
445 | [invocation setTarget:target];
446 |
447 | deep++;
448 |
449 | AMLBlock *block = [SHARED_ANYMETHODLOG blockWithTarget:target];
450 | [block rundBefore:target sel:originSelector args:argList deep:deep];
451 |
452 | NSDate *start = [NSDate date];
453 |
454 | [invocation invoke];
455 |
456 | NSDate *end = [NSDate date];
457 | NSTimeInterval interval = [end timeIntervalSinceDate:start];
458 |
459 | [block rundAfter:target sel:originSelector args:argList interval:interval deep:deep retValue:getReturnValue(invocation)];
460 |
461 | deep--;
462 | }
463 |
464 | //替换方法
465 | BOOL qhd_replaceMethod(Class cls, SEL originSelector, char *returnType) {
466 | Method originMethod = class_getInstanceMethod(cls, originSelector);
467 | if (originMethod == nil) {
468 | return NO;
469 | }
470 | const char *originTypes = method_getTypeEncoding(originMethod);
471 | IMP msgForwardIMP = _objc_msgForward;
472 | #if !defined(__arm64__)
473 | if (qhd_isStructType(returnType)) {
474 | //Reference JSPatch:
475 | //In some cases that returns struct, we should use the '_stret' API:
476 | //http://sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html
477 | //NSMethodSignature knows the detail but has no API to return, we can only get the info from debugDescription.
478 | NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:originTypes];
479 | if ([methodSignature.debugDescription rangeOfString:@"is special struct return? YES"].location != NSNotFound) {
480 | msgForwardIMP = (IMP)_objc_msgForward_stret;
481 | }
482 | }
483 | #endif
484 |
485 | IMP originIMP = method_getImplementation(originMethod);
486 |
487 | if (originIMP == nil || originIMP == msgForwardIMP) {
488 | return NO;
489 | }
490 |
491 | //把原方法的IMP换成_objc_msgForward,使之触发forwardInvocation方法
492 | class_replaceMethod(cls, originSelector, msgForwardIMP, originTypes);
493 |
494 | //把方法forwardInvocation的IMP换成qhd_forwardInvocation
495 | class_replaceMethod(cls, @selector(forwardInvocation:), (IMP)qhd_forwardInvocation, "v@:@");
496 |
497 | //创建一个新方法,IMP就是原方法的原来的IMP,那么只要在qhd_forwardInvocation调用新方法即可
498 | SEL newSelecotr = qhd_createNewSelector(originSelector);
499 | BOOL isAdd = class_addMethod(cls, newSelecotr, originIMP, originTypes);
500 | if (!isAdd) {
501 | DEV_LOG(@"class_addMethod fail");
502 | }
503 |
504 | return YES;
505 | }
506 |
507 | void qhd_logMethod(Class aClass, BOOL(^condition)(SEL sel)) {
508 | unsigned int outCount;
509 | Method *methods = class_copyMethodList(aClass,&outCount);
510 |
511 | for (int i = 0; i < outCount; i ++) {
512 | Method tempMethod = *(methods + i);
513 | SEL selector = method_getName(tempMethod);
514 | char *returnType = method_copyReturnType(tempMethod);
515 |
516 | BOOL isCan = qhd_isCanHook(tempMethod, returnType);
517 |
518 | if (isCan && condition) {
519 | isCan = condition(selector);
520 | }
521 |
522 | if (isCan) {
523 | if (qhd_replaceMethod(aClass, selector, returnType)) {
524 | DEV_LOG(@"success hook method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types);
525 | } else {
526 | DEV_LOG(@"fail method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types);
527 | }
528 | } else {
529 | DEV_LOG(@"can not hook method:%@ types:%s", NSStringFromSelector(selector), method_getDescription(tempMethod)->types);
530 | }
531 | free(returnType);
532 | }
533 | free(methods);
534 | }
535 |
536 |
537 | #pragma mark - ANYMethodLog implementation
538 |
539 | @implementation ANYMethodLog
540 |
541 | + (void)logMethodWithClass:(Class)aClass
542 | condition:(ConditionBlock) condition
543 | before:(BeforeBlock) before
544 | after:(AfterBlock) after {
545 | #ifndef DEBUG
546 | return;
547 | #endif
548 |
549 | if (aClass) {
550 | AMLBlock *block = [[AMLBlock alloc] init];
551 | block.targetClassName = NSStringFromClass(aClass);
552 | block.condition = condition;
553 | block.before = before;
554 | block.after = after;
555 | [SHARED_ANYMETHODLOG setAMLBlock:block forKey:block.targetClassName];
556 | }
557 |
558 | qhd_logMethod(aClass, condition);
559 |
560 | //获取元类,处理类方法。(注意获取元类是用object_getClass,而不是class_getSuperclass)
561 | Class metaClass = object_getClass(aClass);
562 | qhd_logMethod(metaClass, condition);
563 | }
564 |
565 | + (instancetype)sharedANYMethodLog {
566 | static ANYMethodLog *_sharedANYMethodLog = nil;
567 | static dispatch_once_t onceToken;
568 | dispatch_once(&onceToken, ^{
569 | _sharedANYMethodLog = [[self alloc] init];
570 | _sharedANYMethodLog.blockCache = [NSMutableDictionary dictionary];
571 | });
572 | return _sharedANYMethodLog;
573 | }
574 |
575 | - (void)setAMLBlock:(AMLBlock *)block forKey:(NSString *)aKey {
576 | @synchronized (self) {
577 | [self.blockCache setObject:block forKey:aKey];
578 | }
579 | }
580 |
581 | - (AMLBlock *)blockWithTarget:(id)target {
582 | Class class = [target class];
583 | AMLBlock *block = [self.blockCache objectForKey:NSStringFromClass(class)];
584 | while (block == nil) {
585 | class = [class superclass];
586 | if (class == nil) {
587 | break;
588 | }
589 | block = [self.blockCache objectForKey:NSStringFromClass(class)];
590 | }
591 | return block;
592 | }
593 |
594 | @end
595 |
--------------------------------------------------------------------------------
/FuckDingTalk.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5A4E0BB61FA8DBE70042B6C6 /* MethodTraceConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5A4E0BB51FA8DBE70042B6C6 /* MethodTraceConfig.plist */; };
11 | 5A4E0BB91FA8DBE70042B6C6 /* put ipa or app here in Resources */ = {isa = PBXBuildFile; fileRef = 5A4E0BB81FA8DBE70042B6C6 /* put ipa or app here */; };
12 | 5A4E0BC11FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5A4E0BC01FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
13 | 5A4E0BC61FA8DBE70042B6C6 /* Cycript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A4E0BC51FA8DBE70042B6C6 /* Cycript.framework */; };
14 | 5A4E0BC81FA8DBE70042B6C6 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A4E0BC71FA8DBE70042B6C6 /* JavaScriptCore.framework */; };
15 | 5A4E0BCA1FA8DBE70042B6C6 /* RevealServer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A4E0BC91FA8DBE70042B6C6 /* RevealServer.framework */; };
16 | 5A4E0BCC1FA8DBE70042B6C6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A4E0BCB1FA8DBE70042B6C6 /* Foundation.framework */; };
17 | 5A4E0BCE1FA8DBE70042B6C6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A4E0BCD1FA8DBE70042B6C6 /* UIKit.framework */; };
18 | 5A4E0BD21FA8DBE70042B6C6 /* ANYMethodLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E0BD11FA8DBE70042B6C6 /* ANYMethodLog.h */; };
19 | 5A4E0BD41FA8DBE70042B6C6 /* ANYMethodLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BD31FA8DBE70042B6C6 /* ANYMethodLog.m */; };
20 | 5A4E0BD61FA8DBE70042B6C6 /* MethodTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E0BD51FA8DBE70042B6C6 /* MethodTrace.h */; };
21 | 5A4E0BD81FA8DBE70042B6C6 /* MethodTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BD71FA8DBE70042B6C6 /* MethodTrace.m */; };
22 | 5A4E0BDD1FA8DBE70042B6C6 /* AntiAntiDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BDC1FA8DBE70042B6C6 /* AntiAntiDebug.m */; };
23 | 5A4E0BE01FA8DBE70042B6C6 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BDF1FA8DBE70042B6C6 /* fishhook.c */; };
24 | 5A4E0BE21FA8DBE70042B6C6 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E0BE11FA8DBE70042B6C6 /* fishhook.h */; };
25 | 5A4E0BE51FA8DBE70042B6C6 /* FuckDingTalkDylib.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BE41FA8DBE70042B6C6 /* FuckDingTalkDylib.mm */; };
26 | 5A4E0BE71FA8DBE70042B6C6 /* FuckDingTalkDylib.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A4E0BE61FA8DBE70042B6C6 /* FuckDingTalkDylib.h */; };
27 | 5A4E0BE91FA8DBE70042B6C6 /* FuckDingTalkDylib.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BE81FA8DBE70042B6C6 /* FuckDingTalkDylib.m */; };
28 | 5A4E0BF51FA8DC050042B6C6 /* DingtalkPluginConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A4E0BF21FA8DC050042B6C6 /* DingtalkPluginConfig.m */; };
29 | /* End PBXBuildFile section */
30 |
31 | /* Begin PBXContainerItemProxy section */
32 | 5A4E0BC21FA8DBE70042B6C6 /* PBXContainerItemProxy */ = {
33 | isa = PBXContainerItemProxy;
34 | containerPortal = 5A4E0BA71FA8DBE70042B6C6 /* Project object */;
35 | proxyType = 1;
36 | remoteGlobalIDString = 5A4E0BBF1FA8DBE70042B6C6;
37 | remoteInfo = FuckDingTalkDylib;
38 | };
39 | /* End PBXContainerItemProxy section */
40 |
41 | /* Begin PBXCopyFilesBuildPhase section */
42 | 5A4E0BAF1FA8DBE70042B6C6 /* CopyFiles */ = {
43 | isa = PBXCopyFilesBuildPhase;
44 | buildActionMask = 2147483647;
45 | dstPath = "";
46 | dstSubfolderSpec = 10;
47 | files = (
48 | 5A4E0BC11FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib in CopyFiles */,
49 | );
50 | runOnlyForDeploymentPostprocessing = 0;
51 | };
52 | /* End PBXCopyFilesBuildPhase section */
53 |
54 | /* Begin PBXFileReference section */
55 | 5A4E0BB21FA8DBE70042B6C6 /* FuckDingTalk.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FuckDingTalk.app; sourceTree = BUILT_PRODUCTS_DIR; };
56 | 5A4E0BB51FA8DBE70042B6C6 /* MethodTraceConfig.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = MethodTraceConfig.plist; sourceTree = ""; };
57 | 5A4E0BB81FA8DBE70042B6C6 /* put ipa or app here */ = {isa = PBXFileReference; lastKnownFileType = text; name = "put ipa or app here"; path = "TargetApp/put ipa or app here"; sourceTree = ""; };
58 | 5A4E0BBA1FA8DBE70042B6C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
59 | 5A4E0BC01FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libFuckDingTalkDylib.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
60 | 5A4E0BC51FA8DBE70042B6C6 /* Cycript.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cycript.framework; path = Library/Frameworks/Cycript.framework; sourceTree = DEVELOPER_DIR; };
61 | 5A4E0BC71FA8DBE70042B6C6 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
62 | 5A4E0BC91FA8DBE70042B6C6 /* RevealServer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RevealServer.framework; path = Library/Frameworks/RevealServer.framework; sourceTree = DEVELOPER_DIR; };
63 | 5A4E0BCB1FA8DBE70042B6C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
64 | 5A4E0BCD1FA8DBE70042B6C6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
65 | 5A4E0BD11FA8DBE70042B6C6 /* ANYMethodLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ANYMethodLog.h; path = MethodTrace/ANYMethodLog.h; sourceTree = ""; };
66 | 5A4E0BD31FA8DBE70042B6C6 /* ANYMethodLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ANYMethodLog.m; path = MethodTrace/ANYMethodLog.m; sourceTree = ""; };
67 | 5A4E0BD51FA8DBE70042B6C6 /* MethodTrace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MethodTrace.h; path = MethodTrace/MethodTrace.h; sourceTree = ""; };
68 | 5A4E0BD71FA8DBE70042B6C6 /* MethodTrace.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MethodTrace.m; path = MethodTrace/MethodTrace.m; sourceTree = ""; };
69 | 5A4E0BDA1FA8DBE70042B6C6 /* FuckDingTalkDylib-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FuckDingTalkDylib-Prefix.pch"; sourceTree = ""; };
70 | 5A4E0BDC1FA8DBE70042B6C6 /* AntiAntiDebug.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AntiAntiDebug.m; path = AntiAntiDebug/AntiAntiDebug.m; sourceTree = ""; };
71 | 5A4E0BDF1FA8DBE70042B6C6 /* fishhook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = fishhook.c; path = fishhook/fishhook.c; sourceTree = ""; };
72 | 5A4E0BE11FA8DBE70042B6C6 /* fishhook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fishhook.h; path = fishhook/fishhook.h; sourceTree = ""; };
73 | 5A4E0BE31FA8DBE70042B6C6 /* FuckDingTalkDylib.xm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FuckDingTalkDylib.xm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
74 | 5A4E0BE41FA8DBE70042B6C6 /* FuckDingTalkDylib.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FuckDingTalkDylib.mm; sourceTree = ""; };
75 | 5A4E0BE61FA8DBE70042B6C6 /* FuckDingTalkDylib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FuckDingTalkDylib.h; sourceTree = ""; };
76 | 5A4E0BE81FA8DBE70042B6C6 /* FuckDingTalkDylib.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FuckDingTalkDylib.m; sourceTree = ""; };
77 | 5A4E0BF21FA8DC050042B6C6 /* DingtalkPluginConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DingtalkPluginConfig.m; sourceTree = ""; };
78 | 5A4E0BF31FA8DC050042B6C6 /* WrappedHUDHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WrappedHUDHelper.h; sourceTree = ""; };
79 | 5A4E0BF41FA8DC050042B6C6 /* DingtalkPluginConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DingtalkPluginConfig.h; sourceTree = ""; };
80 | /* End PBXFileReference section */
81 |
82 | /* Begin PBXFrameworksBuildPhase section */
83 | 5A4E0BAC1FA8DBE70042B6C6 /* Frameworks */ = {
84 | isa = PBXFrameworksBuildPhase;
85 | buildActionMask = 2147483647;
86 | files = (
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | 5A4E0BBD1FA8DBE70042B6C6 /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | 5A4E0BC81FA8DBE70042B6C6 /* JavaScriptCore.framework in Frameworks */,
95 | 5A4E0BCA1FA8DBE70042B6C6 /* RevealServer.framework in Frameworks */,
96 | 5A4E0BC61FA8DBE70042B6C6 /* Cycript.framework in Frameworks */,
97 | 5A4E0BCC1FA8DBE70042B6C6 /* Foundation.framework in Frameworks */,
98 | 5A4E0BCE1FA8DBE70042B6C6 /* UIKit.framework in Frameworks */,
99 | );
100 | runOnlyForDeploymentPostprocessing = 0;
101 | };
102 | /* End PBXFrameworksBuildPhase section */
103 |
104 | /* Begin PBXGroup section */
105 | 5A4E0BA61FA8DBE70042B6C6 = {
106 | isa = PBXGroup;
107 | children = (
108 | 5A4E0BB41FA8DBE70042B6C6 /* FuckDingTalk */,
109 | 5A4E0BCF1FA8DBE70042B6C6 /* FuckDingTalkDylib */,
110 | 5A4E0BC41FA8DBE70042B6C6 /* Frameworks */,
111 | 5A4E0BB31FA8DBE70042B6C6 /* Products */,
112 | );
113 | sourceTree = "";
114 | };
115 | 5A4E0BB31FA8DBE70042B6C6 /* Products */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 5A4E0BB21FA8DBE70042B6C6 /* FuckDingTalk.app */,
119 | 5A4E0BC01FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib */,
120 | );
121 | name = Products;
122 | sourceTree = "";
123 | };
124 | 5A4E0BB41FA8DBE70042B6C6 /* FuckDingTalk */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 5A4E0BB51FA8DBE70042B6C6 /* MethodTraceConfig.plist */,
128 | 5A4E0BBA1FA8DBE70042B6C6 /* Info.plist */,
129 | 5A4E0BB71FA8DBE70042B6C6 /* TargetApp */,
130 | );
131 | path = FuckDingTalk;
132 | sourceTree = "";
133 | };
134 | 5A4E0BB71FA8DBE70042B6C6 /* TargetApp */ = {
135 | isa = PBXGroup;
136 | children = (
137 | 5A4E0BB81FA8DBE70042B6C6 /* put ipa or app here */,
138 | );
139 | name = TargetApp;
140 | sourceTree = "";
141 | };
142 | 5A4E0BC41FA8DBE70042B6C6 /* Frameworks */ = {
143 | isa = PBXGroup;
144 | children = (
145 | 5A4E0BC51FA8DBE70042B6C6 /* Cycript.framework */,
146 | 5A4E0BC71FA8DBE70042B6C6 /* JavaScriptCore.framework */,
147 | 5A4E0BC91FA8DBE70042B6C6 /* RevealServer.framework */,
148 | 5A4E0BCB1FA8DBE70042B6C6 /* Foundation.framework */,
149 | 5A4E0BCD1FA8DBE70042B6C6 /* UIKit.framework */,
150 | );
151 | name = Frameworks;
152 | sourceTree = "";
153 | };
154 | 5A4E0BCF1FA8DBE70042B6C6 /* FuckDingTalkDylib */ = {
155 | isa = PBXGroup;
156 | children = (
157 | 5A4E0BE31FA8DBE70042B6C6 /* FuckDingTalkDylib.xm */,
158 | 5A4E0BE41FA8DBE70042B6C6 /* FuckDingTalkDylib.mm */,
159 | 5A4E0BE61FA8DBE70042B6C6 /* FuckDingTalkDylib.h */,
160 | 5A4E0BE81FA8DBE70042B6C6 /* FuckDingTalkDylib.m */,
161 | 5A4E0BF41FA8DC050042B6C6 /* DingtalkPluginConfig.h */,
162 | 5A4E0BF21FA8DC050042B6C6 /* DingtalkPluginConfig.m */,
163 | 5A4E0BF31FA8DC050042B6C6 /* WrappedHUDHelper.h */,
164 | 5A4E0BD01FA8DBE70042B6C6 /* MethodTrace */,
165 | 5A4E0BDB1FA8DBE70042B6C6 /* AntiAntiDebug */,
166 | 5A4E0BDE1FA8DBE70042B6C6 /* fishhook */,
167 | 5A4E0BD91FA8DBE70042B6C6 /* Supporting Files */,
168 | );
169 | path = FuckDingTalkDylib;
170 | sourceTree = "";
171 | };
172 | 5A4E0BD01FA8DBE70042B6C6 /* MethodTrace */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 5A4E0BD11FA8DBE70042B6C6 /* ANYMethodLog.h */,
176 | 5A4E0BD31FA8DBE70042B6C6 /* ANYMethodLog.m */,
177 | 5A4E0BD51FA8DBE70042B6C6 /* MethodTrace.h */,
178 | 5A4E0BD71FA8DBE70042B6C6 /* MethodTrace.m */,
179 | );
180 | name = MethodTrace;
181 | sourceTree = "";
182 | };
183 | 5A4E0BD91FA8DBE70042B6C6 /* Supporting Files */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 5A4E0BDA1FA8DBE70042B6C6 /* FuckDingTalkDylib-Prefix.pch */,
187 | );
188 | name = "Supporting Files";
189 | sourceTree = "";
190 | };
191 | 5A4E0BDB1FA8DBE70042B6C6 /* AntiAntiDebug */ = {
192 | isa = PBXGroup;
193 | children = (
194 | 5A4E0BDC1FA8DBE70042B6C6 /* AntiAntiDebug.m */,
195 | );
196 | name = AntiAntiDebug;
197 | sourceTree = "";
198 | };
199 | 5A4E0BDE1FA8DBE70042B6C6 /* fishhook */ = {
200 | isa = PBXGroup;
201 | children = (
202 | 5A4E0BDF1FA8DBE70042B6C6 /* fishhook.c */,
203 | 5A4E0BE11FA8DBE70042B6C6 /* fishhook.h */,
204 | );
205 | name = fishhook;
206 | sourceTree = "";
207 | };
208 | /* End PBXGroup section */
209 |
210 | /* Begin PBXHeadersBuildPhase section */
211 | 5A4E0BBE1FA8DBE70042B6C6 /* Headers */ = {
212 | isa = PBXHeadersBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | 5A4E0BE71FA8DBE70042B6C6 /* FuckDingTalkDylib.h in Headers */,
216 | 5A4E0BD21FA8DBE70042B6C6 /* ANYMethodLog.h in Headers */,
217 | 5A4E0BD61FA8DBE70042B6C6 /* MethodTrace.h in Headers */,
218 | 5A4E0BE21FA8DBE70042B6C6 /* fishhook.h in Headers */,
219 | );
220 | runOnlyForDeploymentPostprocessing = 0;
221 | };
222 | /* End PBXHeadersBuildPhase section */
223 |
224 | /* Begin PBXNativeTarget section */
225 | 5A4E0BB11FA8DBE70042B6C6 /* FuckDingTalk */ = {
226 | isa = PBXNativeTarget;
227 | buildConfigurationList = 5A4E0BEF1FA8DBE70042B6C6 /* Build configuration list for PBXNativeTarget "FuckDingTalk" */;
228 | buildPhases = (
229 | 5A4E0BAB1FA8DBE70042B6C6 /* Sources */,
230 | 5A4E0BAC1FA8DBE70042B6C6 /* Frameworks */,
231 | 5A4E0BAD1FA8DBE70042B6C6 /* ShellScript */,
232 | 5A4E0BAE1FA8DBE70042B6C6 /* Resources */,
233 | 5A4E0BAF1FA8DBE70042B6C6 /* CopyFiles */,
234 | 5A4E0BB01FA8DBE70042B6C6 /* ShellScript */,
235 | );
236 | buildRules = (
237 | );
238 | dependencies = (
239 | 5A4E0BC31FA8DBE70042B6C6 /* PBXTargetDependency */,
240 | );
241 | name = FuckDingTalk;
242 | productName = FuckDingTalk;
243 | productReference = 5A4E0BB21FA8DBE70042B6C6 /* FuckDingTalk.app */;
244 | productType = "com.apple.product-type.application";
245 | };
246 | 5A4E0BBF1FA8DBE70042B6C6 /* FuckDingTalkDylib */ = {
247 | isa = PBXNativeTarget;
248 | buildConfigurationList = 5A4E0BEC1FA8DBE70042B6C6 /* Build configuration list for PBXNativeTarget "FuckDingTalkDylib" */;
249 | buildPhases = (
250 | 5A4E0BBB1FA8DBE70042B6C6 /* ShellScript */,
251 | 5A4E0BBC1FA8DBE70042B6C6 /* Sources */,
252 | 5A4E0BBD1FA8DBE70042B6C6 /* Frameworks */,
253 | 5A4E0BBE1FA8DBE70042B6C6 /* Headers */,
254 | );
255 | buildRules = (
256 | );
257 | dependencies = (
258 | );
259 | name = FuckDingTalkDylib;
260 | productName = FuckDingTalkDylib;
261 | productReference = 5A4E0BC01FA8DBE70042B6C6 /* libFuckDingTalkDylib.dylib */;
262 | productType = "com.apple.product-type.library.dynamic";
263 | };
264 | /* End PBXNativeTarget section */
265 |
266 | /* Begin PBXProject section */
267 | 5A4E0BA71FA8DBE70042B6C6 /* Project object */ = {
268 | isa = PBXProject;
269 | attributes = {
270 | LastUpgradeCheck = 0900;
271 | ORGANIZATIONNAME = "马旭";
272 | TargetAttributes = {
273 | 5A4E0BB11FA8DBE70042B6C6 = {
274 | CreatedOnToolsVersion = 9.0;
275 | ProvisioningStyle = Automatic;
276 | };
277 | 5A4E0BBF1FA8DBE70042B6C6 = {
278 | CreatedOnToolsVersion = 9.0;
279 | ProvisioningStyle = Automatic;
280 | };
281 | };
282 | };
283 | buildConfigurationList = 5A4E0BAA1FA8DBE70042B6C6 /* Build configuration list for PBXProject "FuckDingTalk" */;
284 | compatibilityVersion = "Xcode 8.0";
285 | developmentRegion = en;
286 | hasScannedForEncodings = 0;
287 | knownRegions = (
288 | en,
289 | );
290 | mainGroup = 5A4E0BA61FA8DBE70042B6C6;
291 | productRefGroup = 5A4E0BB31FA8DBE70042B6C6 /* Products */;
292 | projectDirPath = "";
293 | projectRoot = "";
294 | targets = (
295 | 5A4E0BB11FA8DBE70042B6C6 /* FuckDingTalk */,
296 | 5A4E0BBF1FA8DBE70042B6C6 /* FuckDingTalkDylib */,
297 | );
298 | };
299 | /* End PBXProject section */
300 |
301 | /* Begin PBXResourcesBuildPhase section */
302 | 5A4E0BAE1FA8DBE70042B6C6 /* Resources */ = {
303 | isa = PBXResourcesBuildPhase;
304 | buildActionMask = 2147483647;
305 | files = (
306 | 5A4E0BB91FA8DBE70042B6C6 /* put ipa or app here in Resources */,
307 | 5A4E0BB61FA8DBE70042B6C6 /* MethodTraceConfig.plist in Resources */,
308 | );
309 | runOnlyForDeploymentPostprocessing = 0;
310 | };
311 | /* End PBXResourcesBuildPhase section */
312 |
313 | /* Begin PBXShellScriptBuildPhase section */
314 | 5A4E0BAD1FA8DBE70042B6C6 /* ShellScript */ = {
315 | isa = PBXShellScriptBuildPhase;
316 | buildActionMask = 2147483647;
317 | files = (
318 | );
319 | inputPaths = (
320 | );
321 | outputPaths = (
322 | );
323 | runOnlyForDeploymentPostprocessing = 0;
324 | shellPath = /bin/sh;
325 | shellScript = /opt/MonkeyDev/Tools/pack.sh;
326 | };
327 | 5A4E0BB01FA8DBE70042B6C6 /* ShellScript */ = {
328 | isa = PBXShellScriptBuildPhase;
329 | buildActionMask = 2147483647;
330 | files = (
331 | );
332 | inputPaths = (
333 | );
334 | outputPaths = (
335 | );
336 | runOnlyForDeploymentPostprocessing = 0;
337 | shellPath = /bin/sh;
338 | shellScript = "/opt/MonkeyDev/Tools/pack.sh codesign";
339 | };
340 | 5A4E0BBB1FA8DBE70042B6C6 /* ShellScript */ = {
341 | isa = PBXShellScriptBuildPhase;
342 | buildActionMask = 2147483647;
343 | files = (
344 | );
345 | inputPaths = (
346 | );
347 | outputPaths = (
348 | );
349 | runOnlyForDeploymentPostprocessing = 0;
350 | shellPath = /bin/sh;
351 | shellScript = "/opt/MonkeyDev/bin/md --xcbp-logos";
352 | };
353 | /* End PBXShellScriptBuildPhase section */
354 |
355 | /* Begin PBXSourcesBuildPhase section */
356 | 5A4E0BAB1FA8DBE70042B6C6 /* Sources */ = {
357 | isa = PBXSourcesBuildPhase;
358 | buildActionMask = 2147483647;
359 | files = (
360 | );
361 | runOnlyForDeploymentPostprocessing = 0;
362 | };
363 | 5A4E0BBC1FA8DBE70042B6C6 /* Sources */ = {
364 | isa = PBXSourcesBuildPhase;
365 | buildActionMask = 2147483647;
366 | files = (
367 | 5A4E0BDD1FA8DBE70042B6C6 /* AntiAntiDebug.m in Sources */,
368 | 5A4E0BF51FA8DC050042B6C6 /* DingtalkPluginConfig.m in Sources */,
369 | 5A4E0BD81FA8DBE70042B6C6 /* MethodTrace.m in Sources */,
370 | 5A4E0BE01FA8DBE70042B6C6 /* fishhook.c in Sources */,
371 | 5A4E0BD41FA8DBE70042B6C6 /* ANYMethodLog.m in Sources */,
372 | 5A4E0BE51FA8DBE70042B6C6 /* FuckDingTalkDylib.mm in Sources */,
373 | 5A4E0BE91FA8DBE70042B6C6 /* FuckDingTalkDylib.m in Sources */,
374 | );
375 | runOnlyForDeploymentPostprocessing = 0;
376 | };
377 | /* End PBXSourcesBuildPhase section */
378 |
379 | /* Begin PBXTargetDependency section */
380 | 5A4E0BC31FA8DBE70042B6C6 /* PBXTargetDependency */ = {
381 | isa = PBXTargetDependency;
382 | target = 5A4E0BBF1FA8DBE70042B6C6 /* FuckDingTalkDylib */;
383 | targetProxy = 5A4E0BC21FA8DBE70042B6C6 /* PBXContainerItemProxy */;
384 | };
385 | /* End PBXTargetDependency section */
386 |
387 | /* Begin XCBuildConfiguration section */
388 | 5A4E0BEA1FA8DBE70042B6C6 /* Debug */ = {
389 | isa = XCBuildConfiguration;
390 | buildSettings = {
391 | ALWAYS_SEARCH_USER_PATHS = NO;
392 | CLANG_ANALYZER_NONNULL = YES;
393 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
394 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
395 | CLANG_CXX_LIBRARY = "libc++";
396 | CLANG_ENABLE_MODULES = YES;
397 | CLANG_ENABLE_OBJC_ARC = YES;
398 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
399 | CLANG_WARN_BOOL_CONVERSION = YES;
400 | CLANG_WARN_COMMA = YES;
401 | CLANG_WARN_CONSTANT_CONVERSION = YES;
402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
403 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
404 | CLANG_WARN_EMPTY_BODY = YES;
405 | CLANG_WARN_ENUM_CONVERSION = YES;
406 | CLANG_WARN_INFINITE_RECURSION = YES;
407 | CLANG_WARN_INT_CONVERSION = YES;
408 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
412 | CLANG_WARN_STRICT_PROTOTYPES = YES;
413 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
414 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
415 | CLANG_WARN_UNREACHABLE_CODE = YES;
416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
417 | CODE_SIGN_IDENTITY = "iPhone Developer";
418 | COPY_PHASE_STRIP = NO;
419 | DEBUG_INFORMATION_FORMAT = dwarf;
420 | ENABLE_STRICT_OBJC_MSGSEND = YES;
421 | ENABLE_TESTABILITY = YES;
422 | GCC_C_LANGUAGE_STANDARD = gnu11;
423 | GCC_DYNAMIC_NO_PIC = NO;
424 | GCC_NO_COMMON_BLOCKS = YES;
425 | GCC_OPTIMIZATION_LEVEL = 0;
426 | GCC_PREPROCESSOR_DEFINITIONS = (
427 | "DEBUG=1",
428 | "$(inherited)",
429 | );
430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
432 | GCC_WARN_UNDECLARED_SELECTOR = YES;
433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
434 | GCC_WARN_UNUSED_FUNCTION = YES;
435 | GCC_WARN_UNUSED_VARIABLE = YES;
436 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
437 | MTL_ENABLE_DEBUG_INFO = YES;
438 | ONLY_ACTIVE_ARCH = YES;
439 | SDKROOT = iphoneos;
440 | };
441 | name = Debug;
442 | };
443 | 5A4E0BEB1FA8DBE70042B6C6 /* Release */ = {
444 | isa = XCBuildConfiguration;
445 | buildSettings = {
446 | ALWAYS_SEARCH_USER_PATHS = NO;
447 | CLANG_ANALYZER_NONNULL = YES;
448 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
450 | CLANG_CXX_LIBRARY = "libc++";
451 | CLANG_ENABLE_MODULES = YES;
452 | CLANG_ENABLE_OBJC_ARC = YES;
453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
454 | CLANG_WARN_BOOL_CONVERSION = YES;
455 | CLANG_WARN_COMMA = YES;
456 | CLANG_WARN_CONSTANT_CONVERSION = YES;
457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
458 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
459 | CLANG_WARN_EMPTY_BODY = YES;
460 | CLANG_WARN_ENUM_CONVERSION = YES;
461 | CLANG_WARN_INFINITE_RECURSION = YES;
462 | CLANG_WARN_INT_CONVERSION = YES;
463 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
464 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
466 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
467 | CLANG_WARN_STRICT_PROTOTYPES = YES;
468 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
469 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
470 | CLANG_WARN_UNREACHABLE_CODE = YES;
471 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
472 | CODE_SIGN_IDENTITY = "iPhone Developer";
473 | COPY_PHASE_STRIP = NO;
474 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
475 | ENABLE_NS_ASSERTIONS = NO;
476 | ENABLE_STRICT_OBJC_MSGSEND = YES;
477 | GCC_C_LANGUAGE_STANDARD = gnu11;
478 | GCC_NO_COMMON_BLOCKS = YES;
479 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
480 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
481 | GCC_WARN_UNDECLARED_SELECTOR = YES;
482 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
483 | GCC_WARN_UNUSED_FUNCTION = YES;
484 | GCC_WARN_UNUSED_VARIABLE = YES;
485 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
486 | MTL_ENABLE_DEBUG_INFO = NO;
487 | SDKROOT = iphoneos;
488 | VALIDATE_PRODUCT = YES;
489 | };
490 | name = Release;
491 | };
492 | 5A4E0BED1FA8DBE70042B6C6 /* Debug */ = {
493 | isa = XCBuildConfiguration;
494 | buildSettings = {
495 | CODE_SIGN_STYLE = Automatic;
496 | DEVELOPMENT_TEAM = ZZ9329T9X9;
497 | DYLIB_COMPATIBILITY_VERSION = 1;
498 | DYLIB_CURRENT_VERSION = 1;
499 | ENABLE_BITCODE = NO;
500 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj";
501 | EXECUTABLE_PREFIX = lib;
502 | FRAMEWORK_SEARCH_PATHS = (
503 | "$(inherited)",
504 | "$(MonkeyDevPath)/Frameworks/**",
505 | "$(MonkeyDevPath)/Librarys/**",
506 | "$(MonkeyDevTheosPath)/vendor/lib",
507 | );
508 | GCC_C_LANGUAGE_STANDARD = gnu99;
509 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
510 | GCC_PREFIX_HEADER = "FuckDingTalkDylib/FuckDingTalkDylib-Prefix.pch";
511 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
512 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
513 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
514 | HEADER_SEARCH_PATHS = (
515 | "$(inherited)",
516 | "$(MonkeyDevPath)/include",
517 | "$(MonkeyDevTheosPath)/vendor/include/**",
518 | );
519 | INSTALL_PATH = "@executable_path/Frameworks/libFuckDingTalkDylib.dylib";
520 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
521 | LIBRARY_SEARCH_PATHS = (
522 | "$(inherited)",
523 | "$(MonkeyDevPath)/Frameworks",
524 | "$(MonkeyDevTheosPath)/vendor/lib/**",
525 | );
526 | MonkeyDevPath = /opt/MonkeyDev;
527 | MonkeyDevTheosPath = /opt/theos;
528 | OTHER_CFLAGS = (
529 | "$(inherited)",
530 | "-DTHEOS_INSTANCE_NAME=\"\\\"FuckDingTalkDylib\\\"\"",
531 | );
532 | OTHER_LDFLAGS = (
533 | "$(inherited)",
534 | "-weak_library",
535 | "/usr/lib/libc++.dylib",
536 | "-weak_library",
537 | "/usr/lib/libstdc++.dylib",
538 | "-lsubstrate",
539 | );
540 | PRODUCT_NAME = "$(TARGET_NAME)";
541 | TARGETED_DEVICE_FAMILY = "1,2";
542 | VALIDATE_PRODUCT = NO;
543 | };
544 | name = Debug;
545 | };
546 | 5A4E0BEE1FA8DBE70042B6C6 /* Release */ = {
547 | isa = XCBuildConfiguration;
548 | buildSettings = {
549 | CODE_SIGN_STYLE = Automatic;
550 | COPY_PHASE_STRIP = YES;
551 | DEVELOPMENT_TEAM = ZZ9329T9X9;
552 | DYLIB_COMPATIBILITY_VERSION = 1;
553 | DYLIB_CURRENT_VERSION = 1;
554 | ENABLE_BITCODE = NO;
555 | EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = "*.nib *.lproj *.gch (*) .DS_Store CVS .svn .git .hg *.xcodeproj *.xcode *.pbproj *.pbxproj";
556 | EXECUTABLE_PREFIX = lib;
557 | FRAMEWORK_SEARCH_PATHS = (
558 | "$(inherited)",
559 | "$(MonkeyDevPath)/Frameworks/**",
560 | "$(MonkeyDevPath)/Librarys/**",
561 | "$(MonkeyDevTheosPath)/vendor/lib",
562 | );
563 | GCC_C_LANGUAGE_STANDARD = gnu99;
564 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
565 | GCC_PREFIX_HEADER = "FuckDingTalkDylib/FuckDingTalkDylib-Prefix.pch";
566 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
567 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
568 | HEADER_SEARCH_PATHS = (
569 | "$(inherited)",
570 | "$(MonkeyDevPath)/include",
571 | "$(MonkeyDevTheosPath)/vendor/include/**",
572 | );
573 | INSTALL_PATH = "@executable_path/Frameworks/libFuckDingTalkDylib.dylib";
574 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
575 | LIBRARY_SEARCH_PATHS = (
576 | "$(inherited)",
577 | "$(MonkeyDevPath)/Frameworks",
578 | "$(MonkeyDevTheosPath)/vendor/lib/**",
579 | );
580 | MonkeyDevPath = /opt/MonkeyDev;
581 | MonkeyDevTheosPath = /opt/theos;
582 | OTHER_CFLAGS = (
583 | "$(inherited)",
584 | "-DTHEOS_INSTANCE_NAME=\"\\\"FuckDingTalkDylib\\\"\"",
585 | );
586 | OTHER_LDFLAGS = (
587 | "$(inherited)",
588 | "-weak_library",
589 | "/usr/lib/libc++.dylib",
590 | "-weak_library",
591 | "/usr/lib/libstdc++.dylib",
592 | "-lsubstrate",
593 | );
594 | PRODUCT_NAME = "$(TARGET_NAME)";
595 | TARGETED_DEVICE_FAMILY = "1,2";
596 | };
597 | name = Release;
598 | };
599 | 5A4E0BF01FA8DBE70042B6C6 /* Debug */ = {
600 | isa = XCBuildConfiguration;
601 | buildSettings = {
602 | CODE_SIGN_STYLE = Automatic;
603 | DEVELOPMENT_TEAM = ZZ9329T9X9;
604 | ENABLE_BITCODE = NO;
605 | INFOPLIST_FILE = FuckDingTalk/Info.plist;
606 | MONKEYDEV_CLASS_DUMP = NO;
607 | MONKEYDEV_RESTORE_SYMBOL = NO;
608 | PODS_ROOT = "${SRCROOT}/Pods";
609 | PRODUCT_BUNDLE_IDENTIFIER = com.laiwang.DingTalk;
610 | PRODUCT_NAME = "$(TARGET_NAME)";
611 | TARGETED_DEVICE_FAMILY = "1,2";
612 | };
613 | name = Debug;
614 | };
615 | 5A4E0BF11FA8DBE70042B6C6 /* Release */ = {
616 | isa = XCBuildConfiguration;
617 | buildSettings = {
618 | CODE_SIGN_STYLE = Automatic;
619 | DEVELOPMENT_TEAM = ZZ9329T9X9;
620 | ENABLE_BITCODE = NO;
621 | INFOPLIST_FILE = FuckDingTalk/Info.plist;
622 | MONKEYDEV_CLASS_DUMP = NO;
623 | MONKEYDEV_RESTORE_SYMBOL = NO;
624 | PODS_ROOT = "${SRCROOT}/Pods";
625 | PRODUCT_BUNDLE_IDENTIFIER = com.laiwang.DingTalk;
626 | PRODUCT_NAME = "$(TARGET_NAME)";
627 | TARGETED_DEVICE_FAMILY = "1,2";
628 | };
629 | name = Release;
630 | };
631 | /* End XCBuildConfiguration section */
632 |
633 | /* Begin XCConfigurationList section */
634 | 5A4E0BAA1FA8DBE70042B6C6 /* Build configuration list for PBXProject "FuckDingTalk" */ = {
635 | isa = XCConfigurationList;
636 | buildConfigurations = (
637 | 5A4E0BEA1FA8DBE70042B6C6 /* Debug */,
638 | 5A4E0BEB1FA8DBE70042B6C6 /* Release */,
639 | );
640 | defaultConfigurationIsVisible = 0;
641 | defaultConfigurationName = Release;
642 | };
643 | 5A4E0BEC1FA8DBE70042B6C6 /* Build configuration list for PBXNativeTarget "FuckDingTalkDylib" */ = {
644 | isa = XCConfigurationList;
645 | buildConfigurations = (
646 | 5A4E0BED1FA8DBE70042B6C6 /* Debug */,
647 | 5A4E0BEE1FA8DBE70042B6C6 /* Release */,
648 | );
649 | defaultConfigurationIsVisible = 0;
650 | defaultConfigurationName = Release;
651 | };
652 | 5A4E0BEF1FA8DBE70042B6C6 /* Build configuration list for PBXNativeTarget "FuckDingTalk" */ = {
653 | isa = XCConfigurationList;
654 | buildConfigurations = (
655 | 5A4E0BF01FA8DBE70042B6C6 /* Debug */,
656 | 5A4E0BF11FA8DBE70042B6C6 /* Release */,
657 | );
658 | defaultConfigurationIsVisible = 0;
659 | defaultConfigurationName = Release;
660 | };
661 | /* End XCConfigurationList section */
662 | };
663 | rootObject = 5A4E0BA71FA8DBE70042B6C6 /* Project object */;
664 | }
665 |
--------------------------------------------------------------------------------