这部分需要对MethodSwizzle有一定了解会用,这里不对MethodSwizzle讨论
对某信静态分析加动态调试以获取登录账号和密码

重签后我们就可以调试别的人引用了,运行起来的时候可以查看他们的页面按钮的Target和Action,这样就可以hook到点击方法了
接下来就来hook一下登录的时候的账号密码(单纯的只是用来学习一下技术,并没有啥别的想法)。
首先我们可以用class-dump工具解析一下MachO文件提取出.h文件
class-dump -H WeChat -o ./headers/
会解析WeChat二进制文件并在当前文件夹的/headers文件夹下导出.h文件

把headers文件夹拖到sublime里查看在View Debug中我们已经得到了Targert的类名和方法名 接下来在sublime中command + shit + f 全局搜索类名

双击搜索出来的行就可以跳转到对应.h文件 然后我们到.h里就能找到方法的声明

这个方法里没有入参,(有点可惜,如果直接把账号密码传过来,我们就可以通过hook直接拿到了),现在我们hook onNext方法只能获取到两个隐式参数(self,cmd),那我们只能通过self去找账号和密码的输入框,必须要找去self和输入框的关系,在onNext方法中self就是WCAccountMainLoginViewController类,
然后View Debug动态调试,看看textField是哪个类

可以看到输入框的类是WCUITextField,到代码里静态分析一波,这个输入框怎么获取

WCAccountMainLoginViewController类里有两个属性_textFieldUserNameItem 和 _textFieldUserPwdItem看名称的话应该是用户名和密码但是这两个属性是WCAccountTextFieldItem 类型的,类型对不上,在看WCAccountTextFieldItem这个类的定义

里面并没有一个WCUITextField类型的属性,这个类也不是继承WCUITextField类的,这有点尬住了~~~
但是当我们查看他的父类WCBaseTextFieldItem时发现父类有一个WCUITextField类型的属性WCUITextField *m_textField;

按照上面的分析得出这样一个关系
WCAccountMainLoginViewController(self) -> _textFieldUserPwdItem -> m_textField在View Debug里验证一下确实是这样。

关系理清楚就可以写代码实现了
Hook 登录方法获取账号密码
有三种hook的方法
一、添加新方法
//指针 --》 8字节。
IMP (*old_onNext)(id self,SEL _cmd);
//方法实现IMP
void new_onNext(id self,SEL _cmd){
//拿出用户的密码
UITextField * pwd = [[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"];
NSLog(@"获取到用户的密码是%@",pwd.text);
//登录
// [self new_onNext];
// [self performSelector:@selector(new_onNext)];
old_onNext(self,_cmd);
}
因为要交换IMP实现hook,IMP的本质是函数指针所以我们定义一个函数new_onNext 其中(id self,SEL _cmd)是必传的隐式参数,再定义一个old_onNext指向原来的onNext的方法的IMP
//添加新方法
/**
- 1、给哪个类添加方法
- 2、方法的SEL
- 3、方法实现(地址)
- 4、types 方法编号:
- 方法编号要表明函数的返回值、参数如new_onNext返回值是void 第一个参数是对象类型(id)第二个参数是SEL类型就标识为"v@:" 各种类型对照表
*/
BOOL didAddMethod = class_addMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(new_onNext), new_onNext, "v@:");
//交换
method_exchangeImplementations(onNext, class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(new_onNext)));
二、通过替换!
//通过替换!
//原始某信的登录方法(IMP)
old_onNext = method_getImplementation(class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext)));
class_replaceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext), new_onNext, "v@:");
三、getIMP 和 setIMP
old_onNext = method_getImplementation(class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext)));
method_setImplementation(class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), @selector(onNext)), new_onNext);
网友评论