吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 26741|回复: 331
收起左侧

[Android 原创] 从某小电影下载工具破解入手逆向实操

    [复制链接]
谶焮 发表于 2023-3-1 13:39

从某小电影下载工具破解入手逆向实操

本文章中所有内容仅供学习交流使用,不用于其他任何目的,若有侵权,请联系作者立即删除!

本次我们做一个相对入门级的教程,通过对一个安卓端下载工具(ZTQgYjggOGIgZTggYmQgYmQgZTUgYjcgYTUgZTUgODUgYjcgZTcgYWUgYjE=)的分析和逆向,把常见的简单分析方案都过一下,修改方案也都尝试一下,包括重打包、Hook等,那么废话不多说,现在就开始。

目标APP是一个下载工具,支持短视频、磁链等,但是对于非会员的下载有次数限制,非会员每天只能下载5次,本次我们的目的就是绕过非会员下载次数限制。

使用工具

  1. jadx
  2. frida
  3. MT管理器
  4. IDA

jadx分析VIP逻辑

拿到APK后第一步就应该先jadx打开看一下有木有加固,然后再去分析,如果加固了就会涉及到脱壳修复,当前样本并未加固😜,故可以直接进行分析。

  1. 搜索关键字

    常见的关键字如Vip、getVip,搜索后可发现如下信息

    搜索结果

    搜索结果

  2. 分析getVip方法

    可以看到,搜索到的方法中有部分为Native方法,那么类似这种App就存在两种修改方案,一个是修改Native,一个是修改Java(好像是废话),从难度来讲肯定还是Java层更容易修改和调试,所以我们就先从Java层入手,先去看上面的第二个方法,getVip

    分析结果

    分析结果

    可以看到,此方法的调用位置很有限,仅存在一处调用,方法名为h(一处调用了三次)

  3. 分析h方法
    可以看到,h方法中对于getVip的调用为Info.getVip,info为y2.a().e()的返回值,可以查看一下此返回值是什么

    目标方法

    目标方法

  4. Hooke方法,打印info的结果如下

    UserInfo

    UserInfo

    let C4836y2 = Java.use("g.d0.a.n.g.y2");
    C4836y2["e"].implementation = function () {
     console.log('e is called');
     let ret = this.e();
     let mjson = Gson.$new().toJson(ret);
     console.log('e ret value is ' + mjson2);
     return ret2;
    };

    返回信息

    返回信息

  5. 分析到现在,就可以开始思考修改思路了

修改思路

从上面的简单分析就可以看出,应用对于VIP的判断是基于info中的vip字段,则可以通过修改info中的vip字段来实现绕过vip,也可以通过修改非会员每日下载次数来实现下载次数绕过,两种方式都可以实现无限制下载的目的。

所以就可以从以下几个角度来进行修改:

  1. 那么我们就可以通过修改UserInfo对象或其返回值,使其vip信息为11-13中的一个

  2. 修改h方法的smail,修改第一个if
    可以修改第一个if判断,将info.getVip==11修改为info.getVip==0如此就可以实现非会员走会员逻辑(0为非会员,数值可以通过Hook对应方法发现)

  3. 向APP注入frida-gadget,同上一个方案一样修改UserInfo实现获取VIP

  4. 修改todayCount的值,使其一直为0
    从代码中可以看到,客户端会判断todayCount的值是否小于count,那么可以认为count就是非会员每日下载限额,可以试count变大或者todayCount变小也可以绕过下载次数限制,而不需要修改会员身份。

  5. 修改h方法调用位置,将其参数中的count改为更大的值
    例如在h方法被调用时,将其实参固定为9999

以上几个思路,每个思路都可以通过重打包或者Hook来实现,下面我们就开始实践一下,主要针对前三种方法,其他两种有兴趣的小伙伴可自行尝试

Hook(第一种方案)

  1. Hook e方法,打印返回值

    let C4836y2 = Java.use("g.d0.a.n.g.y2");
    C4836y2["e"].implementation = function () {
     console.log('e is called');
     let ret = this.e();
     let mjson = Gson.$new().toJson(ret);
     console.log('e ret value is ' + mjson2);
     return ret2;
    };
  2. 修改返回值

    修改UserInfo的返回值,步骤就是先将UserInfo序列化为JSON,修改后再用Gson反序列化为UserInfo对象,frida脚本如下

    let Gson = Java.use("com.google.gson.Gson");
    let Cy2 = Java.use("g.d0.a.n.g.y2");
    y2["e"].implementation = function () {
     console.log('e is called');
     let ret = this.e();
     let mjson = Gson.$new().toJson(ret);
     let mjson2 = JSON.parse(mjson);
     mjson2["vip"] = 11;
     mjson2["vipTime"] = "2999-01-01 08:00:00";
     mjson2["vipType"] = "永久会员";
     let ret2 = Gson.$new().fromJson(JSON.stringify(mjson2),Java.use("xxx.UserInfo").class)
     console.log('e ret value is ' + ret2);
     return ret2;
    };
  3. 验证结果
    执行后可以发现,已经是永久会员了

    验证结果

    验证结果
    为了防止仅仅是修改了显示实际仍然是非会员,所以需要再尝试一下解析次数,也可以发现非会员的解析次数限制也木有了

重打包(第二种方案)

  1. MT管理器解包找到对应的方法
  2. 修改smail并保存,在h方法中看到getVip调用的位置,将其中的一个0xb或0xc修改为0x0即可

    修改校验值

    修改校验值
  3. 反编译为java看看修改效果
  4. 重新打包安装
  5. 验证修改结果
  6. 另外需要注意,if中有两个判断,一个是userinfo 不为空,一个是是否为VIP,此修改方法仅改了VIP状态,所以还是需要登录的,如果想不登录使用可以尝试修改第一个判断,eqz修改为nez

不过目前Apk重打包目前存在一些问题,APP内置了一个native-security,会校验客户端的完整性,若被篡改,则会强制要求更新,绕过方法可以是配合httpcanary之类的抓包工具将api/security/upload这个接口的请求丢掉就可以继续走下去,但是此方法需要额外操作且对设备有一定的要求,所以不太够通用,我们继续看第三种方案。

重打包(第三种方案)

若想实现在非Root设备上直接使用,方案1和方案2都存在一定的问题,所以我们现在再来看下方案三:通过注入frida-gadget.so来实现在非Root设备上运行,此方法和方案二一样需要过掉APP的完整性验证方法,不过执行起来会相对简单一些(最起码不需要去改汇编😛,使用时也无需多余操作)

完整性校验分析(IDA)

  1. 在进行第二种方案时我们发现,App具备完整性验证,重新打包APP后会出现APP退出并跳转至更新网址的情况,所以我们需要继续分析其校验逻辑

  2. 通过抓包,我们可以看到,是收到了api/security/upload的返回值之后才弹出的错误提示,那么可以先去搜索一下请求的url、更新网址或者host

  3. 经过搜索,在jadx中并未搜索到对应的host或url信息,那么我们就可以怀疑是native层进行的校验

upload搜索结果

upload搜索结果

  1. 现在我们可以直接找一下security相关的代码,也可以直接Hook  System.loadLibrary看看是加载到哪个so时APP退出,也可以直接去lib看一下有没有相关的so,于是就可以找到libnative-security.so

    // 
    let System = Java.use('java.lang.System');
    let Runtime = Java.use('java.lang.Runtime');
    let SystemLoad_2 = System.loadLibrary.overload('java.lang.String');
    let VMStack = Java.use('dalvik.system.VMStack');
    
    SystemLoad_2.implementation = function(library) {
     console.log("Loading library =====> " + library);
     try {
       let loaded = Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), library);
       return loaded;
     } catch(ex) {
       console.log(ex);
     }
    };

加载so

加载so

  1. 之后找到so的加载位置在SecurityJNI.Java中

  2. 然后我们发现其中有一个方法叫做nativeInit(Context context);,追踪这个方法的调用,然后就看到了这个方法,通过Hook调试等方法确定了是nativeInit之后APP才退出的,于是锁定此方法,继续分析

    public void f(Context context, g.d0.c.d.a call) {
     this.b = context;
     if (this.a) {
       if (call != null) {
         call.a();
         return;
       }
       return;
     }
     this.a = true;
     SecurityJNI.nativeInit(context);
     g.d0.c.g.a.a("init finish");
     e.g();
     if (call != null) {
       call.a();
     }
    }
  3. 分析一下native-security中的nativeInit,IDA伪代码如下

    char *v15; 
    v19 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
    __android_log_print(6, "SecurityJNI", "checkApk %s", "before");
    std::string::basic_string<decltype(nullptr)>();
    v15 = (char *)sub_F63F0((__int64)v18);
    v2 = (char *)ping(a1, v15);
    if ( ((unsigned __int8)v2 & 1) != 0 )
    {
     v3 = "adverts.indabai.com";
     v2 = v18;
    }
  4. 一眼看过来,sub_F63F0应该是我们的目标,之前我们已经分析出了upload接口是校验完整性的,并且在nativeInit中并未发现对应的更新地址,且ping函数的参数中有sub_F63F0返回的V15,有可能就是接收的更新地址

  5. 直接Hook sub_F63F0

    let sub_F63F0 = get_func_addr("libnative-security.so",0xF63F0);
    console.log('sub_F63F0=' + sub_F63F0);
    Interceptor.attach(sub_F63F0, {
     onEnter: function (args) {
       console.log('onEnter');
       console.log('sub_F63F0 args[a1]=' + hexdump(args[0]));
     },
     onLeave: function (retval) {
       console.log('sub_F63F0 onLeave' + hexdump(ret);
                   }
    });
  6. 可以看到如下信息

打印返回值

打印返回值

  1. 修改返回值

    let sub_F63F0 = get_func_addr("libnative-security.so",0xF63F0);
    console.log('sub_F63F0=' + sub_F63F0);
    Interceptor.attach(sub_F63F0, {
      onEnter: function (args) {
        console.log('onEnter');
        console.log('sub_F63F0 args[a1]=' + hexdump(args[0]));
      },
      onLeave: function (retval) {
        let ret = Memory.readCString(retval);
        if(ret.indexOf("isCrack") != -1){
          console.log('===============');
          ret = ret.replace(true,false)
        }
        console.log('sub_F63F0 onLeave' + ret);
        Memory.writeUtf8String(retval,ret)
      }
    });
  2. 正常运行

修改后的返回值

修改后的返回值

开始重打包

分析完完整性验证方法后,我们就可以正式开始修改工作了

  1. 下载frida-gadget.so,选一个适合自己的版本,Releases · frida/frida (github.com),若出现在部分设备上可用部分设备不可用的情况,则可以更换一下gadget版本,目前遇到过14版本的gadget在Android12不可用的情况

  2. 编写脚本,增加js脚本将方案1的UserInfo修改脚本和绕过完整性校验脚本写入文件(eg:命名为DDD.js)

  3. 编写配置文件(配置文件名称需要和frida-gadget.so的名字相同,如frida-gadget.so的配置文件名称应该为frida-gadget.config.so)

    {
     "interaction": {
       "type": "script",
       "path": "/sdcard/Download/Script/DDD.js",
       "on_change":"reload"
     }
    }
  4. 将frida-gadget.so和frida-gadget.config.so放入lib目录对应文件夹,64位的就放arm64_v8a,可以用MT管理器操作,直接增加进去即可

  5. 挑选合适的时机加载frida-gadget.so,加载的早了,可能security.so还没加载,会导致Hook失败,加载的晚了,nativeInit执行完了,也会失败,所以我们选择在security.so load完成之后立即load frida-gadget.so

  6. MT管理器打开apk找到,在System.loadLibrary("native-security");对应的smail代码下增加如下内容

    const-string v0, "frida-gadget" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
  7. 将DDD.js文件放到配置文件中配置的位置

  8. 打包、签名、安装、给读写外置存储权限、启动

  9. 进入APP后注册、登录,若显示为永久会员则说明已成功

最后

本帖仅用于交流技术随机选择APP进行分析,但是这个工具箱我个人用下来还非常好用,可以下载几十种类型的链接,基本上包含了所有短视频,价格也很便宜,二十来块就可以买永久会员,建议大家去支持一下😛。

免费评分

参与人数 84威望 +2 吾爱币 +166 热心值 +74 收起 理由
moxuanfei6078 + 1 + 1 用心讨论,共获提升!
kuiur0810 + 1 谢谢@Thanks!
BagF + 1 用心讨论,共获提升!
jungwoo + 1 用心讨论,共获提升!
youle + 1 被小视屏app吸引,解密e4b88be8bdbde5b7a5e585b7e7aeb1--&amp;gt;&amp;gt;下载工具箱.
mad4rene + 1 + 1 我很赞同!
aiminger + 1 我很赞同!
behindeye + 1 + 1 用心讨论,共获提升!
junjia215 + 1 + 1 谢谢@Thanks!
gqdsc + 1 厉害厉害受益匪浅
nslcyg + 1 + 1 我很赞同!
1MajorTom1 + 1 热心回复!
Explo1tliu + 1 + 1 我很赞同!
colaya + 1 谢谢@Thanks!
letting + 1 + 1 我很赞同!
clhoma + 1 + 1 热心回复!
52bbQ + 1 热心回复!
Hickeyslu + 1 热心回复!
lackoflove166 + 1 + 1 我很赞同!
colect + 1 + 1 我很赞同!
ConDomCD + 1 + 1 我很赞同!
cwtbr + 1 + 1 谢谢@Thanks!
Hcj665766 + 1 + 1 我很赞同!
gaosld + 1 + 1 谢谢@Thanks!
Cheng98 + 1 + 1 我很赞同!
shadowaaa + 1 + 1 热心回复!
Ghang + 1 谢谢@Thanks!
sxcx560 + 1 + 1 用心讨论,共获提升!
半杯不倒 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
tianyueka + 1 + 1 我很赞同!
xyer8 + 1 + 1 用心讨论,共获提升!
tyb13385365995 + 1 + 1 用心讨论,共获提升!
pz1999 + 1 我很赞同!
小马奔腾2 + 1 热心回复!
swansfight + 1 谢谢@Thanks!
YXiang + 1 谢谢@Thanks!
hezhengliang + 1 + 1 我很赞同!
vieing727360 + 1 + 1 热心回复!
RickSanchez + 1 热心回复!
onlywey + 1 + 1 我很赞同!
ikun520999 + 1 + 1 用心讨论,共获提升!
fish1994 + 1 + 1 我很赞同!
ma20230313 + 1 谢谢@Thanks!
rainmote + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
duskdust + 1 谢谢@Thanks!
GAW + 1 + 1 我很赞同!
jianghuai + 1 + 1 鼓励转贴优秀软件安全工具和文档!
tuzzz + 1 我很赞同!
webcom + 1 我很赞同!
狮子歌歌 + 1 + 1 我很赞同!
fadshnbjktrasj + 1 我很赞同!
wangchaolin + 1 + 1 谢谢@Thanks!
kibi + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qlqypd + 1 + 1 我很赞同!
J14N + 1 我很赞同!
shiqi666 + 1 + 1 666,有特殊用处哦
wdhpsobb + 1 谢谢@Thanks!
ls520 + 1 + 1 我很赞同!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
lsg1975623565 + 1 我很赞同!强啊
hanlaoshi + 1 + 1 谢谢@Thanks!
偶尔的曾经 + 1 热心回复!
chen1860906 + 1 + 1 谢谢@Thanks!
pengpulin + 1 + 1 谢谢@Thanks!
macdongshen + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
抱歉、 + 1 用心讨论,共获提升!
萌男叮当 + 1 + 1 谢谢@Thanks!
shenhuawd + 1 + 1 我很赞同!
13026366163 + 1 我很赞同!
wwwj8383 + 1 用心讨论,共获提升!
a30636 + 1 鼓励转贴优秀软件安全工具和文档!
tigerxiao + 1 + 1 谢谢@Thanks!
香芋 + 1 + 1 用心讨论,共获提升!
sky0077 + 1 + 1 谢谢@Thanks!
gjdjjwzx + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xlwllm + 1 + 1 谢谢@Thanks!
ColoThor + 1 + 1 http://www.txttool.com/t/?id=NDgy
superworker2022 + 1 + 1 实战贴
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Schwarz + 1 + 1 谢谢@Thanks!
醉爱花香 + 1 + 1 通过楼主发的base64解密彩蛋后得到e4 b8 8b e8 bd bd e5 b7 a5 e5 85 b7 e7.
正己 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
朱古力 + 1 + 1 请问有名字吗?如果有蓝奏更好,几十块我想去支持下
bpzm1987 + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

  • · 好帖|主题: 549, 订阅: 87

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

我为52pojie狂 发表于 2023-3-2 11:31
小电影是什么意思?是两三个人一个场景的那种人体艺术片吗?
佚名RJ 发表于 2023-3-2 21:10
这个软件直接逆向是很好破解的,但是就是检验安装包完整性,直接跳转到浏览器强制更新下载,每个版本改的都是这样。具体软件叫什么,从第一种方案的图片用过的,一般都看出来了
zy3333351 发表于 2023-3-2 14:56
Itmedo 发表于 2023-3-3 12:01
base64解码之后是汉字的utf8编码,对照解码即可
huduke 发表于 2023-3-2 11:08
谢谢分享,有没有ios app破解实操。
adolphin 发表于 2023-3-2 11:28
可以啊,这样子就ok了
fangxiaolong 发表于 2023-3-2 11:57
谢谢分享
yboopp 发表于 2023-3-2 11:59
先码住   进收藏吃灰吧   
破凤凰 发表于 2023-3-2 12:25
感谢老师无私分享。
bpzm1987 发表于 2023-3-2 13:10
厉害,加油,前来学习下!
Kingloo 发表于 2023-3-2 13:41
看到getVIP字樣了,感覺是很厲害的工具
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 19:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表