Kotani bald collection

Today is another day close to reverse

  • Today we are going to take a case: in the setting interface of a letter, inject UI (for the future automatic grab red envelope to prelude ~)

  • First let’s take a look at the renderings

1. Preparation

For both forward and reverse development, before we write code, we need to have a general idea: our goal is to add UI to the Settings interface

1.1. Location setting interface

In the last blog post we talked about Monkey and Logos.

  • We use 8.0.2 wechat package. (Of course you can use the latest 8.0.5, we should be the same)

    1. We re-signedWeChatRun,Monkey
    1. We can useviewDebugThe name of the location controller is:NewSettingViewController

    1. And we can also observe that the interface is aWCTableViewWe need to find himData sources (dataSource)So let’s take a look

Datasource =

    1. class-dumpTo obtainWeChattheH file.sublimeOpen it and look for itWCTableViewManager

    1. foundWCTableViewManagerThere is aA section ofandtableViewProxy method of

    1. Let’s see how many are managed using WCTableViewManager

    1. We can confirm that one of them is the Settings interface: we can go throughIn response to the chain, go to the Settings screen

2. The UI injection

We’ve found the setup screen and can view his methods through the class-dump. header file

  • I directly write the code ~ (there is a comment, this is relatively simple, brothers look at the opportunity to try, but there is a risk of being blocked ~ 😆, so I am at the risk of being blocked to explore ~)
#import <UIKit/UIKit.h>

#define XGDefaults [NSUserDefaults standardUserDefaults]
#define XGSWITCHKEY @"XGSWITCHKEY"
#define XGTEXTKEY @"XGTEXTKEY"

@interface WCTableViewManager : NSObject
// Method in class-dump. I'm going to call, so copy comes in ~
@property(retain.nonatomic) NSMutableArray *sections;
- (long long)numberOfSectionsInTableView:(UITableView *)tableView;
@end

// Since we use self, we need to know where self is positioned
@interface MMUIViewController : UIViewController
@end
@interface NewSettingViewController : MMUIViewController
@end

%hook WCTableViewManager

// To hook the method ~ slide, keyboard recycling
- (void)scrollViewWillBeginDragging:(id)arg1{
    %orig;
    // Make sure you are in the Settings screen
    if([MSHookIvar <UITableView* > (self."_tableView").nextResponder.nextResponder isKindOfClass:%c(NewSettingViewController)]){
            [MSHookIvar <UITableView* > (self."_tableView") endEditing:YES]; }}// Customize the textField method
%new
-(void)xg_textFieldDidChangeValue:(NSNotification *)notification{
    UITextField *textField = (UITextField *)[notification object];
    [XGDefaults setValue:textField.text forKey:XGTEXTKEY];
    [XGDefaults synchronize];
    [MSHookIvar <UITableView* > (self."_tableView") reloadData];
}

// Custom switch switch method
%new
-(void)xg_switchChang:(UISwitch *)switchView{
    [XGDefaults setBool:switchView.isOn forKey:XGSWITCHKEY];
    [XGDefaults synchronize];
    [MSHookIvar <UITableView* > (self."_tableView") reloadData];
}

/ / cell Settings
- (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// NSLog(@"indexPath:%ld,section:%ld",indexPath,[indexPath section]);
    // If in the Settings screen and is the last group. Set the cell
    if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && ([indexPath section] == [self numberOfSectionsInTableView:tableView]- 1)) {UITableViewCell * cell = nil;
        // UI SWICH switch
        if([indexPath row] == 0) {static NSString * swCell = @"SWCELL";
             cell = [tableView dequeueReusableCellWithIdentifier:swCell];
             if(! cell){ cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
             }
             cell.textLabel.text = @" Reverse start!!";
             
             UISwitch * switchView = [[UISwitch alloc] init];
             switchView.on = [XGDefaults boolForKey:XGSWITCHKEY];
             [switchView addTarget:self action:@selector(xg_switchChang:) forControlEvents:(UIControlEventValueChanged)];
             cell.accessoryView = switchView;
             cell.imageView.image = [UIImage imageNamed:([XGDefaults boolForKey:XGSWITCHKEY] == 1)?@"unlocked" : @"locked"];
         }else if([indexPath row] == 1) {static NSString * waitCell = @"UICELL";
             cell = [tableView dequeueReusableCellWithIdentifier:waitCell];
             if(! cell){ cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:nil];
             }
             cell.textLabel.text = "Add a small UI!";
             // First set the size of an input box
             UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0.0.80.30)];
             [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(xg_textFieldDidChangeValue:) name:UITextFieldTextDidChangeNotification object:textField];
             textField.text = [XGDefaults valueForKey:XGTEXTKEY];
             // the cell has a - (void)setAccessoryView:(id)arg1; methods
             [cell setAccessoryView:textField];
             
             cell.imageView.image = [UIImage imageNamed:@"1003_filled"];
             
         }
         cell.backgroundColor = [UIColor whiteColor];
         return cell;
 
 
    }else{
        return%orig; }}// How many rows are there in each group
- (long long)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    // If in the Settings screen and is the last group. Add 2 lines
    if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && (section == [self numberOfSectionsInTableView:tableView]- 1)) {return 2;
    }else{
        return%orig; }}// How many groups. NextResponder. NextResponder
- (long long)numberOfSectionsInTableView:(UITableView *)tableView {
    // The interface is set
    if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)]){
        return %orig + 1;
    }else{
        return%orig; }}/ / line height
- (double)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    // If in the Settings screen and is the last group. Set the line height to ~
    if([tableView.nextResponder .nextResponder isKindOfClass:%c(NewSettingViewController)] && ([indexPath section] == [self numberOfSectionsInTableView:tableView]- 1)) {return 44;
    }else{
        return %orig;
    }
}
%end

// Since we added a textField control, imagine that the keyboard would block the view, so we can deal with it.

// 2 things to do, 1, keyboard talk, tableView, move up! 2, slide tableView, keyboard recycling

%hook NewSettingViewController

/ / the pop-up
%new
- (void)xg_keyboardWillShow:(NSNotification *)notification{
    UIView * view = self.view;
    CGRect keyBoardRect=[notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    view.frame = CGRectMake(0, -keyBoardRect.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height );
}

/ / disappear
%new
- (void)xg_keyboardWillHide:(NSNotification *)notification{
    UIView * view = self.view;
    view.frame = CGRectMake(0.0[UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}

// hook method, add notification ~
- (void)viewDidLoad{
    %orig;
    // Listen for the keyboard to pop up and disappear
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xg_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(xg_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

%end
Copy the code
  • The physical picture took a wave

3. Summary

  • A letter has risks, be careful to contact ~ 😆

  • This blog is mainly for automatic red envelope to do a preparation, otherwise the code too much brother research is not good preview ~

  • If you guys try it, use the tuba. It can be unsealed at that time (due to the risk of being sealed)

  • We’re just gonna study his technique, learn a little bit, so there’s no problem, okay

  • There’s nothing written into the UI this time, so it’s a little simpler. Finally, guys, I went to work overtime ~ (the company always comes before the end of the day!! 😿)