REVERSEENGINEERING

    探探逆向之旅

    一阵子下来才明白,逆向其实会上瘾,尤其是我这种~ 天生就爱搞破坏的坏孩子来讲
    探探是一个社交APP, 似乎不少人在上面找到另一半的. 这种卡片社交简单,背后隐藏的推荐逻辑,筛选逻辑才是它能如此盛名的原因.
    要重点说明,这些需求是我一产品的同学给我提的, 绝非个人偏好~ 我不是那种人…

    梗概

    先上下图

    (功能入口在 新手引导->探探怎么玩-> ):

    这是目前逆向后我给它新增的功能,因为工作也比较忙,就没有新增过多的需求,但是整个App的架构逻辑其实已经很清晰了, 基本可以合理的新增一些需求在里面, 这也说明探探的开发架构逻辑挺棒的.

    功能简介


    下方是一个简单的tableview, 功能的启动都在这里,当然功能是有互斥和优先级的,

    • 同时开启无条件选妹和选妹子onlyStudent, 无条件选妹子优先.
    • 为了更好的效果在主页的地方选妹子,我最后采取的是模拟点击likeButton,在NSTimer中执行,当刷的人对已拉取用户求余==0的时候停止, 如果不想停止就把infinite打开,这是一个疯狂的爬取,没有停止的线性条件,除非杀APP. 为什么这么做呢, 因为我把自动拉取的信息默认是保存到Document/cache.txt里面, 主要是照片的url和部分简介
    • 自动尬聊采用的是图灵的API, 你拿到源码后需要替换为您的key, 谷歌搜索”图灵机器人”,打开后进入到某个想聊天的窗口, 它如果收到信息会自动跟她尬聊.
    • 上方是用Mapkit,新增Mapview在上方,用来更改定位,然后下面的打开(不过测了下证明这块功能还有点问题的,有兴趣的哥们继续挖掘下)

    开始调试

    调试工具

    • 依然是最酷的 MonkeyDev
    • FLEX (reveal过期了,这是一个很棒的替代品), 下载后编译一下, 然后按照monkeyDev中wifi加入第三方库的方式操作即可
    • frida-ios-dump 还是庆哥出品,砸壳后顺带把整个APP导出
    • 其它的全程是cycript+LLDB调戏 就不累述了…
    #import 
    // open it in here
    [[FLEXManager sharedManager] showExplorer];
    

    导入库之后,在注入成功的这个通知回调里,启动这个方法

    调试遇到的问题

    探探是有反调试的, 用的是sysctl. 很强
    那么你调试的时候需要讲MonkeyDev里面的打开, 这个反反调试检测默认是关闭的,原因注释上有

    从需求粗发的debug

    逆向App,我一般的套路都是酱紫.
    设计需求 -> 需求在哪里会展示 -> 从view到Controller-> controller方法猜测 -> 结合monkeyDev进行方法trace -> 确认需求方法 -> hopper找方法地址 -> LLDB调试下断点 -> 查看调用栈(bt) -> 然后开始埋点尝试hook

    用笔记在记录每次你发现的新宇宙(虽然开始的很早,实际没有时间弄它…)

    Dec 18, 2017
    reverseEngineering

    mac逆向-窗口管理Divvy

    Divvy个人感觉是最棒的一款窗口管理软件了~, 但是它动不动就会提示个五秒的窗口让你注册License,最近小试牛刀完IOSApp, 它给我提供一个入门的机会…

    工具准备


    mac上的逆向其实比较省, 你不需要额外的砸壳,直接就能能从包里面拿到执行文件.
    class-dump 头文件.
    用Hopper打开,反汇编一下方便待会查看.
    然后神器依旧是monkeyDev, 它帮我们省去注入.dylib 和 重签名等”繁杂步骤”~

    入口分析

    本来大多数的步骤一定是从view开始, 有一款神器就[interface inspector], 但总会报错一些乱七八糟的问题,暂时还没调好, 于是乎我粗糙的从hopper搜索”Register”,(如果一开始搜的是首字母小写的话可能不会饶那么弯…),结果是这样子的,

    也查到其他无关的,最后确定就是这里,伪代码和汇编看并没有看出什么头绪,于是乎先看看有没有调用这里这个类相关.

    追踪前,这里有一款强大的工具说下:
    frida-trace: frida-trace -m “-[PTHotKeyCenter _]” Divvy

    用法是frida-trace -m “<+类方法/-实例方法>[类名 方法名<_代表全部>]”
    执行后它会自动帮你生成跟踪的js文件,然后监听所指定的方法.

    一开始觉得吧, PTHotKeyCenter不像是很关键的类, 也是没怎么写Mac的App的原因,但还是监听了一下:

    我尝试打开它,然后随便输入一串号码注册, 发现他怎么整都只打印这些, 而且就在我使用快捷键的时候~
    随意也明白了,这就是”热键”,仅此而已…

    动态调试

    进行到这里其实是无头绪的, 然后想着是从mondev进行动态调试,看看能不能从调用栈看看这里的情况.
    想着hook哪个方法的时候,脑子冒个灵光,想到了这个view的展示, 我就输入”)show”看看有没有什么可疑的,结果:
    十分意外第一个方法,很明显这个方法应该是展示注册这个View的,而且还待会参数时间.
    如果是这个方法果然没错, 那么我可能得到,一是找不到更好的hook方法,duration的参数改为最少的时间,或者可以尝试return这部展示的操作. 其次先Hook下看看调用栈,是什么决定它展示也是可以的, 于是开始我的Hook代码.
    MonkeyDev默认是subStrate的hook方法代码, 当然也是可以替换成其它的(按道理当然可以~):
    这是一开始的代码:

    但是允许会报错,其中需要修改:

    static void newHookFunc(AppController* self,SEL _cmd,id array){ }
    
    //replacet to | //下面
    // 需要指明多少个参数, 不知道参数类型就使用泛型id
    static void newHookFunc(AppController* self,SEL _cmd,id arg1, id arg2){ }
    

    build一下且进入调试后, 用时在static void newHookFunc(AppController* self,SEL _cmd,id arg1, id arg2){ 这里Xcode断点一下:
    但如果直接执行还需要做两部:

    Dec 3, 2017
    reverseEngineering

    逆向-UNREAD去除阅读限制

    背景 : UNREAD是一款很棒的RSS阅读器, 免费版本有50条阅读的限制. 强化在非越狱机上的逆向之旅
    因为是巩固逆向的知识阶段,踩坑是必然的, 但是多么绕的就不讲了, 但是要mark最后走对这个方式,后面也要逐渐总结对的方法

    准备工作

    UNREAD要求ios10以上才可以下载,所以我的935设备无法下载也无法砸壳, 所幸的是PP助手能搜到,不过版本低了0.2, 用起来没差别.

    确认需求 : 去除阅读限制

    分析

    正向分析思路


    如果是我设计呢:
    目标是个tableview , “UNLOCK UNREAD”这一cell显示了当前剩余可阅读的数量.每次点击进入文章阅读的时候,可读数量 -= 1; 有一个模型来记录这里的数量,
    在tableview这个控制器,viewWillApear:的时候刷新row.

    当时想的是:
    那么如果是tableiview, dataSource方法必然有tableview:cellForRowAtIndexPath:被调用, 如果能找到模型,直接hook模型的调用或许是第一思路.但是熬到三点还没睡我才明白我踩坑了, 这里不累赘了,一把泪.

    view层嵌入

    从monkeyDev启动项目,拖入我们的APP后启动到设备上, 默认是会注入reveal动态库的, APP启动成功后, 进入到主页, 然后mac启动reveal:

    reveal启动后点到我们目标view,可以看到这是一个tableview的cell,”50 ARTICLES LEFT”是cellContentView的label, 查看右边, 我们能看到这个页面的控制器.
    “NSRHomeViewController”

    分析控制器

    把class-dump出来的头文件拖到Xcode项目, 搜一下”NSRHomeViewController.h”可以看到这个头文件, 所幸头文件不多,我有了部分时间慢慢看这些方法,尝试发现敏感名称, 其中最让我敏感的是这个:


    第二个方法这未免太明显~, 其它大概也预览了一下, 图一看到是NSArray, 或许会存储数据的模型.

    断点可疑调用

    二进制文件拉到Hopper反汇编后, 搜一下三个方法

    moreItems & setMoreItems & updateUnlockInfo

    获取它们的静态地址后,在LLDB查看下初始偏移地址, 加上并断点这三位.
    分析的时候知道, 它是在点击文章阅读的时候才减一. 那么现在就进入文章里面,触发我们的断点. 果不其然它触发了,查看一下调用栈:

    Nov 28, 2017
    reverseEngineering

    砸壳最稳dumpdecrypted

    之前写过一篇 clutch砸壳 的, 但clutch似乎没有100%成功的情况, 所以还是得老司机来.

    编译得到.dylib

    https://github.com/stefanesser/dumpdecrypted
    下载后make一下会生成一个.dylib

    拷贝到设备上

    iproxy 2222 22
    开启一个映射后:
    scp -P 2222 dumpdecrypted.dylib root@localhost:/tmp/

    获取App目录

    启动下目标App,cycript到进程中, 输入:

    NSHomeDirectory()
    

    拷贝.dylib到App目录

    退出cycript,切换到App目录后:
    拷贝.dylib 到得到的目录:

    cp /tmp/dumpdecrypted.dylib  .
    

    mible用户查看进程:

    su mobile    #切换普通用户
    

    开始砸壳

    启动下App,然后:

    ps -e  | grep /Application   #查看App进程,我们需要正确的二进制文件地址
    
    DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib <上面的二进制地址>
    

    查看文件


    Nov 24, 2017
    reverseEngineering

    去除OplayerLite广告提示-越狱机

    最近在学习逆向相关的实践+踩坑, 庆哥的视频中一个课程是对于OPlayerLite进行进行广告处理了, 因为是去年的课程App也更新了逻辑, 我沿着先辈的道路把坑撸了一把, mark这场一天一夜的战斗.

    分析层级结构

    定位目标对象

    连接到越狱机(切换到无网络模式, 因为Oplayer lite有网络的时候加载的广告是不同的,不利于分析), 同时点击任意视频,进入到视频播放页面, 我们会看到广告的view,上面有一行文本”Buy the full version to remove ads?”
    这时候我们连接到cycript打印下层级:

    UIApp.keyWindow.recursiveDescription().toString()
    


    由于我已去除了过了,又从App Store重新下载, 发现还是没有广告,图片暂时就没哈
    其中有引起我们注意的层级是:

    |    |    | >
    |    |    |    | >
    |    |    |    |    | >
    |    |    |    | >
    

    其中UILabel: 0x176b1380中的text属性跟我们看到的ads上是一样的,它的同级view是UIButton, 父view是UIView .
    因为咱们要解决的目标是view, 尤为关注是这里的frame.size, 它们都是320 50, label也是height=50. 把这部分截图保存下来,待会查找的时候需要用到

    正向分析设计

    划重点: 从正向的开发的角度, 分析它是如何设计的

    如果是我开发君, 我的伪代码大概如下

    if  (!payBuyFullViersion)  {
        AdsView *adsview =  [[AdsView alloc] init];
        [self.palyerView addSubview:adsview]
    }
    

    可能其他的逻辑未必跟我符合. 但是一定必然的是, 这个adsView 必须是addSubview上去的,addSubview是UIKit中view的方法, 咱们需要静态分析这个地址, 通过断点来查看它对应的调用者/参数, 从而拿到地址,来定位到OplayerLite

    Nov 24, 2017
    reverseEngineering

    clutch对app进行砸壳

    逆向学习相关,实战一下对app的砸壳,砸壳必须要越狱手机哦.

    什么是壳

    一个App无论是Android还是ios, 或者是PC平台, 为了保护app都会加上一层壳, 加壳的app可能无法被一些IDA之类的工具解析, 那么也就无法搞事情,所以砸壳是必须走的一步,也可以从某助手平台下载已砸壳的, 当然最好用下面的命令确认下先.
    怎么查看一个app是否有壳, 可以使用下面的命令, 替换为App的二进制文件查看:

    otool -l targetBinary | grep cryptid
    

    得到的结果如果是1则是未砸壳的, 0是已砸壳.
    还有一种情况是一些App支持多种架构的,可能会展示多个cryptid=1/0, 在哪个平台跑就砸哪个.

    确定目标后安装App

    我这里以麦当劳App(听说改名金拱门)为例,从appStore下载安装.

    编译clutch二进制文件

    clutch神器 下载地址 , 下载编译后允许会得到一个二进制文件, 这里不累述哈, 或者你可以直接从我的 git地址 clone我编译后的,在clutch_binary文件下.

    拷贝clutch到设备

    连接手机


    我这里用iproxy从22映射到2222端口,并整个过程保持. 右边线尝试登录下,默认密码是alpine, 其他情况就自行谷歌帮助,我相信这没什么难度.

    iproxy 2222 22
    ssh root@localhost -p 2222
    

    测试连接成功后输入 exit 退出,接着下一步

    scp拷贝到手机

    scp(secure copy) 支持ssh协议远程拷贝, 我们用它拷贝到设备上, 前提是上面的
    的测试成功了.

    scp -P 2222 ./clutch root@localhost:/usr/bin/
    


    如果这样子的话就成功了, /usr/bin/默认已经在环境变量查找内, 拷贝到这里可以省事很多多.

    找到目标

    先介绍下clutch用法:

    推荐ios-deploy -B可以获取bundleID, brew install ios-deploy就可以安装了.

    例如我这里的目标是麦当劳app, 尝试搜一下mc,果不其然就是它了.
    拿到的bundleID就是com.mcdonalds.gma
    (嗯, 还有个grep的方法更简单,但是我真的不知道它是麦当劳, 因为他显示的是Arch,所以靠谱的话就还是上面,BundleID基本会跟名称一直吧)

    Nov 17, 2017
    reverseEngineering