iOS逆向——Method Swizzle及WeChat注册、登录代码示例

872 阅读3分钟

Method Swizzle

利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关系,达到OC方法调用流程改变的目的。主要用于OC方法。

关于Runtime,如果大家不了解,可以看看Cooci老师的文章——iOS底层原理(二):Runtime研究(一),简单了解一下。


在OC中,SEL 和 IMP 之间的关系,就好像一本书的“目录”。

SEL 是方法编号,就像“标题”一样。

IMP是方法实现的真实地址,就像“页码”一样。

他们是一一对应的关系

SEL(标题)————————IMP(页码)

Runtime提供了交换两个SEL和IMP对应关系的函数。通过函数交换、改变两个SEL和IMP关系的技术,我们称之为Method Swizzle(方法欺骗)。

多种Hook方式

  • class_addMethod
        •   利用AddMethod方式,让原始方法可以被调用,不至于因为找不到SEL而崩溃
  • class_replaceMethod
         •   利用class_replaceMethod,直接给原始的方法替换IMP
  • method_setImplementation
         •   利用method_setImplementation,直接重新赋值原始的新的IMP

代码示例

一、注册

之前我们有讲过代码注入,本文不再过多赘述,需要的同学,点击iOS逆向——shell重签名及代码注入跳转。那么上手直接撸代码啦。

1、新建项目,生成新的证书和描述文件,在手机上跑一遍,保证描述文件可以正确安装到手机中。

2、运行Xcode,脚本重签APP

3、TARGETS创建Framework,并创建.h .m,这里我们命名Inject

4、运行app, lldb动态调试,分析代码逻辑。

5、如下图所示,因为Xcode版本不同,有的Target 和 Action 会直接显示类名,如果不直接显示类名的,可以用po命令+对象地址看到ClassName。p是执行指令,o是object的意思。


6、找到相关名称,就可以用class-dump这个工具把二进制文件所有的类的描述copy出来(相当于头文件,但是不仅仅是头文件)

class-dump -H 二进制文件 -o 目标文件夹

7、根据clas-dump导出的文件,考虑相关逻辑。关于查看class-dump导出的文件,建议使用轻量级的sublime,使用更快速。

8、那么接下来就是代码了。如下图所示:


9、运行Xcode,重签app,这里要注意一点,上一章我写的脚本,在最后一行'#代码注入'是注释状态。那么这次运行放开,才能注入成功。Framework的名字也要改成代码中对应的名字。

10、铛铛铛铛


二、登录

同理,登录的的业务逻辑我们要结合动态调试(lldb)以及静态分析(class-dump导出的文件)


  1. class-dump导出文件


2、根据文件分析业务逻辑,找出相关类。先判定控制器,是WCAccountBaseViewController,通过找WCAccountBaseViewController的属性,判断WCAccountTextFieldItem *_textFieldUserPwdItem与密码相关。


通过WCAccountTextFieldItem找其父类WCBaseTextFieldItem,


在WCBaseTextFieldItem下,查到WCUITextField *m_textField。以上仅是分析,但不能判断是否就是我们需要的UITextField,所以首先,我们要lldb调试。


3、lldb调试如下


4、所以最终我们需要拿到textField,最后textField.text拿到pwd.

(1)方法交换



这是在inject类中增加新的方法,再实现方法交换,但WCAccountMainLoginViewController并不存在Maxy_onNext调用方法,要想真正的根据业务需求实现方法交换,需要给WCAccountMainLoginViewController增加新的方法,在inject实现方法交换。


这样并不破坏wc的登录逻辑。关于参数type,请查看官方文档,有明确的说明。

(2)方法替换


(3)setIMP和getIMP(推荐)


三种不同的方法,都能实现。最后推荐使用setIMP、getIMP。如果我哪里写的不对、不清楚,还希望你能指正出来,我们共同探讨进步,如果你喜欢此文章,就动一动小手点个赞吧。