iOS逆向(4)-代码注入,非越狱窃取微信密码

利用LLDB对微信进行分析,而后利用分析的结果,再逐步讲解如何Hook微信的登陆过程,截获微信密码。ios

在上一篇文章(APP重签名)中,已经介绍了如何对APP重签名,而且利用XCode将微信跑起来,既然到了这一步,就万万不能错过强大的LLDB。这篇文章就讲为你们讲解到如何利用LLDB对微信进行分析,而后利用分析的结果,再逐步讲解如何Hook微信的登陆过程,截获微信密码。git

老规矩,片头先给福利:点击下载Demo:HookWeChat,此次有两份代码。因为越狱版微信体积太大,受到github限制,因此并无将它传到github,能够在下方连接单独下载github

文中所须要用到的工具和文件:
越狱版本微信7.0.2 提取码: 2w87
MachOView 提取码: n3hy
yololib 提取码:e8qs
class-dump 提取码:v5ku安全

接下来咱们会从一下几部,让微信脱下看似安全的外衣,裸露在你们面前。bash

  • Framework的做用
  • 初探MachO (原理分析)
  • 代码注入 (代码过程)
  • ViewDebug、LLDB、class-dump分析微信登陆页面(原理分析)
  • Hook登陆,自动获取密码 (代码过程)
  • 总结

一、Framework的做用(对Framework熟悉的同窗能够跳过这一步)

什么是Framework这里就很少加叙述,我参考这个网站,很是详细,看不懂你直接@我。点这里:Framework最强讲解微信

废话很少说,接下来直接演示如何建立一个Framework,而且介绍跟我们Hook微信有关的基础原理。架构

新建一个工程FrameworkDemo,新建一个Framework,取名FYHook app

建立Framework(1).png

建立Framework(2).png

在新建出来的FYHook文件夹中新建InjectCode(继承NSObject)对象,而且新建代码:工具

+ (void)load {
    NSLog(@"来了,老弟😁");
}
复制代码

新建InjectCode.png

直接运行,会发现来了,老弟😁被输出,证实用这种方法新建的Framework可以直接运行在咱们的项目中。 网站

NSLog字符串.png

二、初探MachO (若是不想看原理,能够直接跳到第三部 代码注入)

根据上篇文章APP重签名讲到的,咱们可使用XCode将微信跑起来,那么是否是将二者结合起来,就能够将咱们的代码注入进微信的APP呢?

Step 1 先思考一个问题。

根据APP重签名中的结论,利用脚本能够便捷重签APP(由于咱们用的WeChat举例,因此下面简称WeChat),那么咱们在重签脚本的工程中,直接建立一个Framework,能不能让咱们Framework中的代码在WeChat中运行?

很显然,这是不行的(有兴趣的能够试一下)!为何? 这个问题下面会回答,先把这个问题记在心中。

Step 2 MachO做用

在咱们用XCode新建HYHook的时候,其实XCode帮咱们作了一部操做:建立HYHook时候,同时将HYHook连接到咱们的项目中(这是后期的XCode新增功能,早年的XCode这一步是须要咱们直接作的)

XCode自动连接.png
common+ b Build一下,会发如今已经Build出来的文件中的Frameworks下已经有FYHook了,已经已经代表FYHook被Copy咱们的ipa文件了。(如何看Build出来的文件?查看: APP重签名中Step 8 App重签名)
自动加入Frameworks已经MachO文件.png
可是FYHook在ipa文件中,并不表明着FYHook就能够被咱们的可执行文件所执行,由于FYHook并无没导报入咱们的可执行文件,只有在这个可行执行文件的 某一个地方作好标记,告知可执行文件,在适当的时候须要加载外部的FYHook,才可以正常运行。

而这个地方所说的可执行文件就是MachO文件(具体什么是MachO,这不是本片文章的重点内容,能够持续关注笔者以后的文章,下一章详细介绍这相当重要的MachO),咱们能够利用工具MachOView来查看MachO中到底有什么内容。

Step 3 MachOView

MachOView.png
点击这里下载: MachOView 提取码: n3hy

用MachOView打开FrameworkDemo的MachO,能够看到以下图

查看MachO.png

能够看到其中的有个Load Commons组,这里面就包括全部须要被动态加载的库。也就是说,若是在Load Commons中没有对应的FYHook,就不会加载FYHook。

在上图中能够看到FYHook已经被加入了Load Commons,而且图右侧也标记了FYHook所属的目录(和MachO文件同级的Frameworks下FYHook.framework中 ,FYHook.framework实际上是个文件夹,里面的FYHook也是个MachO

因此这里就获得了「为何咱们直接将FYHook加入咱们的从重签脚本工程,不能直接运行FYHook」的答案。 由于在在咱们Build出来的MachO文件中的Load Commons中没有加入FYHook的路径。因此没法运行FYHook中的代码。

那么咱们直接将FYHook加入咱们Build出的MachO文件行吗? 显然也是不行的,由于咱们Build出的MachO文件始终会被原始包(WeChat)中的MachO给替换掉。咱们须要将FYHook加入原始包(WeChat)中的MachO中。

Step 4 将FYHook标记入MachO中

这里咱们就须要用到终端命令行工具:yololib 提取码:e8qs

将下载下来的yololib.zip解压后获得的yololib放在‎⁨目录/usr⁩/local⁩/bin⁩下,这样咱们在终端中就可使用yololib命令了

yololib.png

如下命令就是将FYHook注入WeChat的命令

// yololib 「MachO路径」 「FYHook相对MachO的路径」
yololib WeChat Frameworks/FYHook.framework/FYHook
复制代码

三、代码注入

Step 1 创建重签脚本工程

新建工程,取名InjectFrameWork,过程可参照上一篇文章(APP重签名) 最后获得以下工程:

重签工程.png

Step 2 建立Framework文件

新建一个Framework文件,取名FYHook,在FYHook中新建文件InjectCode,在InjectCode加入以前提到的一样的load代码, 等到以下工程:

建立Framework(3).png

Step 3 修改源文件的MachO文件

找到WeChat的MachO文件,打开终端,进入此目录下 执行命令

// yololib 「MachO路径」 「FYHook相对MachO的路径」
yololib WeChat Frameworks/FYHook.framework/FYHook
复制代码

yololib注入成功.png

Step 4 从新打包WeChat.ipa

zip -ry WeChat.ipa Payload
复制代码

从新打包WeChat.ipa.png

Step 5 加入新的WeChat.ipa,运行工程

将新获得的WeChat.ipa从新加入APP文件(这一步其实能够只加入文件,而不用加入工程),删除原来的Wechat7.0.2越狱.ipa。

新WeChat.ipa.png
新WeChat.ipa-2.png

common + R运行代码,会发现微信跑起来了,咱们的来了,老弟😁也被输出了!

Step 6 新的思考

以前分析了咱们建立了FYHook,可是没有对MachO注入,获得的答案是来了,老弟😁不能被输出,WeChat能跑起来。
那么若是咱们对MachO注入FYHook,却没有建立对应的FYHook.framework,会怎么样呢?
这就留给你们思考,再去验证了,有答案的同窗也能下方留言,并说出缘由哦。

四、 ViewDebug、LLDB、class-dump分析微信登陆页面

Step 1 ViewDebug

XCode跑起微信以后,跳转到登陆页面,利用ViewDebug查看具体的详细的UI

ViewDebug.png
能够看到,登陆按钮是一个FixTitleColorButton对象,他的Target的名字存在地址0x280afaa40中,他的Action名字存在地址0x280afac00中。 用一样的方法查看帐号密码的输入框,会发现他们都属于一个对象,叫作WCUITextField
帐号输入框WCUITextField.png

Step 2 LLDB

利用LLDB查看登陆按钮具体的Target和Action名称

LLDB查看Target和Action.png
得知: 登陆按钮处于WCAccountMainLoginViewController这个页面之中 登陆按钮的点击方法叫作onNext

Step 3 class-dump

class-dump,是能够把Objective-C运行时的声明的信息导出来的工具。其实就是能够导出.h文件。用class-dump能够把未经加密的app的头文件导出来。

点击这下载命令行工具:class-dump 提取码:v5ku 一样的,将class-dump拷贝到Mac的目录/usr⁩/local⁩/bin⁩下,这样咱们在终端中就可使用yololib命令了

class-dump目录.png

运行命令将WeChat全部的头文件导出来。

// class-dump -H 「app的MachO文件」 -o 「输入的目录」
class-dump -H WeChat -o /Users/dengbin/Code/GitHub/HookWeChat/InjectFrameWork/APP/WeChat-H
复制代码

class-dump.png
WeChat-H.png

Step 4 找到输入框里面的内容

利用文本工具,例如Sublime查看WeChat的头文件,找到前面发现的WCAccountMainLoginViewController

WCAccountMainLoginViewController.png

发现里面确实有方法- (void)onNext;,还有长得很像帐号输入框,密码输入框的对象_textFieldUserNameItem,_textFieldUserPwdItem

接下来就是找到密码输入框里面的字符串了,能够发现这两个都是WCAccountTextFieldItem对象,全部咱们继续在导出的文件里面找到WCAccountTextFieldItem

WCAccountTextFieldItem.png

在其中只发现一个tips对象m_labelTip,没有发现对应的textfiled,可是能够看到WCAccountTextFieldItem是继承于WCBaseTextFieldItem的,因此继续查找WCBaseTextFieldItem

WCBaseTextFieldItem.png

从这就能够看到一个m_textField对象,这是个WCUITextField对象,疑似咱们的目标textField,继续查看WCUITextField

WCUITextField.png

果真,这就是一个UITextField文件,那么咱们就能够经过text字段取出其string。

接下来在用LLDB试试看,验证下咱们的猜测:
随便在帐号栏输入:qwerty
而后在密码栏输入:123456

po [(WCAccountMainLoginViewController *)0x1128bbc00 valueForKey:@"_textFieldUserPwdItem"]
po [(WCAccountTextFieldItem *)0x28328e880 valueForKey:@"m_textField"]
po [(WCUITextField *)0x112163a00 text]
复制代码

其中第一个地址0x1128bbc00是在前两部利用ViewDubg找到的。

找到输入的密码.png

能够发现最后确实找到了咱们输入的密码123456,证实咱们的分析是正确的。

五、Hook登陆,自动获取密码

接下来又是代码Coding了。原理分析完,其实代码就很简单了,直接上代码:

+ (void)load {
    NSLog(@"来了,老弟😁");
    Method onNext = class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), sel_registerName("onNext"));
    //1.保存原始的IMP
    old_onNext = method_getImplementation(onNext);
    //2.SET
    method_setImplementation(onNext, (IMP)my_next);
}

IMP (*old_onNext)(id self,SEL _cmd);

void my_next(id self,SEL _cmd){
    // 获取密码
    NSString *pwd = [[[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"] performSelector:@selector(text)];
    NSString *accountTF = [[[self valueForKey:@"_textFieldUserNameItem"] valueForKey:@"m_textField"] performSelector:@selector(text)];
    NSLog(@"密码是!%@",pwd);
    // 将密码追加在帐号栏的后面
    [[[self valueForKey:@"_textFieldUserNameItem"] valueForKey:@"m_textField"] performSelector:@selector(setText:) withObject:[NSString stringWithFormat:@"%@+%@",accountTF,pwd]];
    //调用原来的方法
    old_onNext(self,_cmd);
}
复制代码

稍微解释一下,在前面咱们发现登陆的响声事件是onNext,全部咱们利用Objective-C的Runtime特性,对onNext进行方法替换,在响应原有的onNext以前,咱们加上咱们本身的方法,好比代码中的,在帐号栏中直接输入密码。
运行后结果如图:

运行结果.PNG

我这用的是setIMP和getIMP的方式,对原方法进行HOOK,其实方法有多种:如:class_replaceMethod(),method_exchangeImplementations(),这里只是举一个例子供你们参考。

这篇文章的全部代码均可以在这下载到:HookWeChat

六、总结:

  • 先对APP重签名,让APP能在XCode运行起来
  • 利用yololib注入Framework,让APP能够运行咱们直接的代码
  • 利用ViewDebug、LLDB、class-dump分析登陆事件和密码框所在位置
  • 利用Runtime的MethodSwizzle,Hook登陆事件

此次只是简单的微信的一个静态页面进行了初步接触,虽然思路简单,但这运用到的工具,倒是无数大神前辈们为咱们铺好的路,感谢!

MachO文件在本文中只是初略的说起,其实在咱们逆向过程当中MachO是一个相当重要的存在,如:

  • 对app的砸壳,其实就是对MachO解密
  • 全部的方法名,静态字符串都是存在MachO中
  • app的架构(arm64,arm7...)也是在MachO中区分的
  • app加载其实也是对MachO的一步步操做
  • ...

因此,在下篇文章,笔者将会对MachO文件进行详细的讲解。请持续关注,以为有帮助的点个收藏,留言评估了哦。

相关文章
相关标签/搜索