├── .gitattributes ├── IMG ├── IMG_01.PNG ├── IMG_010.PNG ├── IMG_011.gif ├── IMG_02.PNG ├── IMG_03.PNG ├── IMG_04.PNG ├── IMG_05.PNG ├── IMG_06.PNG ├── IMG_07.PNG ├── IMG_08.PNG ├── IMG_09.PNG └── IMG_4292.MOV ├── LICENSE ├── README.md └── douyinDylib.m /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /IMG/IMG_01.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_01.PNG -------------------------------------------------------------------------------- /IMG/IMG_010.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_010.PNG -------------------------------------------------------------------------------- /IMG/IMG_011.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_011.gif -------------------------------------------------------------------------------- /IMG/IMG_02.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_02.PNG -------------------------------------------------------------------------------- /IMG/IMG_03.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_03.PNG -------------------------------------------------------------------------------- /IMG/IMG_04.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_04.PNG -------------------------------------------------------------------------------- /IMG/IMG_05.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_05.PNG -------------------------------------------------------------------------------- /IMG/IMG_06.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_06.PNG -------------------------------------------------------------------------------- /IMG/IMG_07.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_07.PNG -------------------------------------------------------------------------------- /IMG/IMG_08.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_08.PNG -------------------------------------------------------------------------------- /IMG/IMG_09.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_09.PNG -------------------------------------------------------------------------------- /IMG/IMG_4292.MOV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nododo/HookDouYin/77ac30460431398404c4947de7ea31f616962047/IMG/IMG_4292.MOV -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 hehehehehehe 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HookDouYin 2 | 3 | ## 文章参考地址:https://www.52pojie.cn/thread-865083-1-1.html 4 | -------------------------------------------------------------------------------- /douyinDylib.m: -------------------------------------------------------------------------------- 1 | // weibo: http://weibo.com/xiaoqing28 2 | // blog: http://www.alonemonkey.com 3 | // 4 | // douyinDylib.m 5 | // douyinDylib 6 | // 7 | // Created by nododo on 2018/12/18. 8 | // Copyright (c) 2018 nododo. All rights reserved. 9 | // 10 | 11 | #import "douyinDylib.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import "CTBlockDescription.h" 17 | #import "CTObjectiveCRuntimeAdditions.h" 18 | 19 | static NSString * const VideoPlayEndedNotiName = @"VideoPlayEndedNotiName"; 20 | static NSString * const OpenAutoPlay = @"OpenAutoPlay"; 21 | 22 | CHConstructor{ 23 | printf(INSERT_SUCCESS_WELCOME); 24 | 25 | [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) { 26 | 27 | #ifndef __OPTIMIZE__ 28 | CYListenServer(6666); 29 | 30 | MDCycriptManager* manager = [MDCycriptManager sharedInstance]; 31 | [manager loadCycript:NO]; 32 | 33 | NSError* error; 34 | NSString* result = [manager evaluateCycript:@"UIApp" error:&error]; 35 | NSLog(@"result: %@", result); 36 | if(error.code != 0){ 37 | NSLog(@"error: %@", error.localizedDescription); 38 | } 39 | #endif 40 | 41 | }]; 42 | } 43 | 44 | 45 | CHDeclareClass(CustomViewController) 46 | 47 | #pragma clang diagnostic push 48 | #pragma clang diagnostic ignored "-Wstrict-prototypes" 49 | 50 | //add new method 51 | CHDeclareMethod1(void, CustomViewController, newMethod, NSString*, output){ 52 | NSLog(@"This is a new method : %@", output); 53 | } 54 | 55 | #pragma clang diagnostic pop 56 | 57 | CHOptimizedClassMethod0(self, void, CustomViewController, classMethod){ 58 | NSLog(@"hook class method"); 59 | CHSuper0(CustomViewController, classMethod); 60 | } 61 | 62 | CHOptimizedMethod0(self, NSString*, CustomViewController, getMyName){ 63 | //get origin value 64 | NSString* originName = CHSuper(0, CustomViewController, getMyName); 65 | 66 | NSLog(@"origin name is:%@",originName); 67 | 68 | //get property 69 | NSString* password = CHIvar(self,_password,__strong NSString*); 70 | 71 | NSLog(@"password is %@",password); 72 | 73 | [self newMethod:@"output"]; 74 | 75 | //set new property 76 | self.newProperty = @"newProperty"; 77 | NSLog(@"newProperty : %@", self.newProperty); 78 | //change the value 79 | return @"nododo"; 80 | } 81 | 82 | #pragma mark - 关闭弹框 83 | 84 | CHDeclareClass(UIViewController) 85 | 86 | CHOptimizedMethod3(self, void, UIViewController, presentViewController, UIViewController *, viewControllerToPresent, animated, BOOL, flag, completion, id, completion) { 87 | if([viewControllerToPresent isKindOfClass:UIAlertController.class]) { 88 | return; 89 | } 90 | CHSuper3(UIViewController, presentViewController, viewControllerToPresent, animated, flag, completion, completion); 91 | } 92 | 93 | #pragma mark - 自动播放相关 94 | 95 | CHDeclareClass(AWEFeedTableViewController) 96 | 97 | CHOptimizedMethod(0, self, BOOL, AWEFeedTableViewController, pureMode) { 98 | return YES; 99 | } 100 | 101 | @interface AWEFeedTableViewController : UIViewController 102 | 103 | @property (nonatomic, assign) NSInteger currentPlayIndex; 104 | 105 | @end 106 | 107 | //- (void)_addNotifications; 108 | CHOptimizedMethod0(self, void, AWEFeedTableViewController, _addNotifications) { 109 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playNext) name:VideoPlayEndedNotiName object:nil]; 110 | CHSuper0(AWEFeedTableViewController, _addNotifications); 111 | } 112 | 113 | CHDeclareMethod0(void, AWEFeedTableViewController, playNext) { 114 | if ([[NSUserDefaults standardUserDefaults] boolForKey:OpenAutoPlay] == NO) { 115 | return; 116 | } 117 | UITableView *tableView = [self valueForKey:@"_tableView"]; 118 | NSIndexPath *path = [NSIndexPath indexPathForRow:self.currentPlayIndex +1 inSection:0]; 119 | [tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 120 | } 121 | 122 | 123 | CHDeclareClass(AWEVideoPlayerController) 124 | 125 | CHOptimizedMethod1(self, void, AWEVideoPlayerController, playerItemDidReachEnd, id, arg1) { 126 | NSLog(@"--------------------------------"); 127 | [[NSNotificationCenter defaultCenter] postNotificationName:VideoPlayEndedNotiName object:nil]; 128 | CHSuper1(AWEVideoPlayerController, playerItemDidReachEnd, arg1); 129 | } 130 | 131 | #pragma mark - 设置界面相关 132 | 133 | @interface AWEGeneralSettingViewModel : NSObject 134 | 135 | - (id)sectionDataArray; 136 | - (void)setSectionDataArray:(id)arg1; 137 | 138 | @end 139 | 140 | @interface AWESettingSectionModel : NSObject 141 | 142 | @property(retain, nonatomic) NSArray *itemArray; 143 | 144 | @end 145 | 146 | @interface AWESettingItemModel : NSObject 147 | 148 | @property(copy, nonatomic) NSString *title; 149 | @property(nonatomic) long long cellType; 150 | @property(nonatomic) _Bool isSwitchOn; 151 | @property(copy, nonatomic) id switchChangedBlock; 152 | 153 | @end 154 | 155 | CHDeclareClass(AWESettingsViewModel) 156 | 157 | @interface AWESettingsTableViewController : UIViewController 158 | 159 | @end 160 | 161 | CHDeclareClass(AWESettingsTableViewController) 162 | 163 | CHOptimizedMethod0(self, void, AWESettingsTableViewController, refreshView) { 164 | AWEGeneralSettingViewModel *model = [self valueForKey:@"_viewModel"]; 165 | NSMutableArray *sectionArr = [NSMutableArray arrayWithArray:model.sectionDataArray]; 166 | AWESettingSectionModel *secModel = sectionArr[1]; 167 | NSMutableArray *secArr = [NSMutableArray arrayWithArray:secModel.itemArray]; 168 | AWESettingItemModel *lastItem = secArr.lastObject; 169 | 170 | 171 | if(![lastItem.title isEqualToString:@"连续播放"]) { 172 | AWESettingItemModel *item = [[objc_getClass("AWESettingItemModel") alloc] init]; 173 | item.title = @"连续播放"; 174 | item.cellType = 4; 175 | item.isSwitchOn = [[NSUserDefaults standardUserDefaults] boolForKey:OpenAutoPlay]; 176 | item.switchChangedBlock = ^(BOOL ison) { 177 | [[NSUserDefaults standardUserDefaults] setBool:ison forKey:OpenAutoPlay]; 178 | }; 179 | 180 | [secArr addObject:item]; 181 | secModel.itemArray = secArr; 182 | [sectionArr replaceObjectAtIndex:1 withObject:secModel]; 183 | [model setSectionDataArray:sectionArr]; 184 | [self setValue:model forKey:@"_viewModel"]; 185 | } 186 | CHSuper0(AWESettingsTableViewController, refreshView); 187 | } 188 | 189 | 190 | #pragma mark - 获取block参数相关 191 | 192 | //CHDeclareClass(AWEGeneralSettingViewController) 193 | 194 | //@interface AWEGeneralSettingViewController : UIViewController 195 | ////AWEGeneralSettingViewController AWESettingsTableViewController 为并列子类 hook 了 父类的 refreshView 结果代码执行起来优先hook了 堆栈关系优先出现的AWESettingsTableViewController 196 | //@end 197 | // 198 | //CHDeclareMethod0(void, AWEGeneralSettingViewController, testXXX) { 199 | // AWEGeneralSettingViewModel *model = [self valueForKey:@"_viewModel"]; 200 | // AWESettingSectionModel *secModel = [(NSArray *)(model.sectionDataArray) firstObject]; 201 | // NSMutableArray *secArr = [NSMutableArray arrayWithArray:secModel.itemArray]; 202 | // 203 | // NSString *tempStr = @""; 204 | // if (YES) { 205 | // AWESettingItemModel *testItem = secArr[1]; 206 | // 207 | // id testBlock = testItem.switchChangedBlock; 208 | // CTBlockDescription *blockDescription = [[CTBlockDescription alloc] initWithBlock:testBlock]; 209 | // const char *expectedArguments[] = {@encode(typeof(testBlock)), @encode(BOOL), @encode(id)}; 210 | // for (int i = 0; i < blockDescription.blockSignature.numberOfArguments; i++) { 211 | // NSString *argu = [NSString stringWithFormat:@"第%d个参数为 %@", i, [NSString stringWithUTF8String: expectedArguments[i]]]; 212 | // tempStr = [[tempStr stringByAppendingString:argu] stringByAppendingString:@"\n"]; 213 | // } 214 | // [self performSelector:@selector(showLoadingViewWithTitle:) withObject:tempStr]; 215 | // } 216 | // 217 | //} 218 | // 219 | //CHOptimizedMethod0(self, void, AWEGeneralSettingViewController, viewDidLoad) { 220 | // [self performSelector:@selector(testXXX) withObject:nil afterDelay:0.5]; 221 | // CHSuper0(AWEGeneralSettingViewController, viewDidLoad); 222 | //} 223 | 224 | 225 | CHConstructor{ 226 | CHLoadLateClass(CustomViewController); 227 | CHClassHook0(CustomViewController, getMyName); 228 | CHClassHook0(CustomViewController, classMethod); 229 | 230 | CHLoadLateClass(UIViewController); 231 | CHHook3(UIViewController, presentViewController, animated, completion); 232 | 233 | CHLoadLateClass(AWEFeedTableViewController); 234 | CHHook0(AWEFeedTableViewController, pureMode); 235 | CHHook0(AWEFeedTableViewController, _addNotifications); 236 | 237 | 238 | CHLoadLateClass(AWEVideoPlayerController); 239 | CHHook1(AWEVideoPlayerController, playerItemDidReachEnd); 240 | 241 | CHLoadLateClass(AWESettingsTableViewController); 242 | CHHook0(AWESettingsTableViewController, refreshView); 243 | 244 | // CHLoadLateClass(AWEGeneralSettingViewController); 245 | // CHHook0(AWEGeneralSettingViewController, viewDidLoad); 246 | // CHHook0(AWEGeneralSettingViewController, testXXX); 247 | } 248 | 249 | --------------------------------------------------------------------------------