某A系电商App doCommandNative浅析

简介: 某A系电商App doCommandNative浅析

一、目标


李老板: 奋飞呀,x-sign你都水了好几篇了,一直在Apk里面打转,咱们啥时候分析分析它的so?


奋飞: 循序渐进嘛,我们上次刚定位了它的so,今天我们来分析分析。


App版本: v4.15.1


二、步骤

Native层的入口


先回忆下这个堆栈

[NewStringUTF] bytes:x-sign
Rc Full call stack:dalvik.system.VMStack.getThreadStackTrace(Native Method)
 tt: java.lang.Thread.getStackTrace(Thread.java:1538)
 tt: com.txxxao.wireless.security.adapter.JNICLibrary.doCommandNative(Native Method)
 tt: com.axxbxxx.wireless.security.mainplugin.а.doCommand(Unknown Source:0)
 tt: com.axxbxxx.wireless.security.middletierplugin.c.d.a.a(Unknown Source:280)
 tt: com.axxbxxx.wireless.security.middletierplugin.c.d.a$a.invoke(Unknown Source:56)
 tt: java.lang.reflect.Proxy.invoke(Proxy.java:913)
 tt: $Proxy12.getSecurityFactors(Unknown Source)
 tt: mtopsdk.security.d.a(lt:620)
 tt: mtopsdk.mtop.a.a.a.a.a(lt:218)
 tt: mtopsdk.framework.a.b.d.b(lt:45)
 tt: mtopsdk.framework.b.a.a.a(lt:60)
0xcb434e10 libsgmiddletierso-6.5.50.so!0x33e10
0xcb404e28 libsgmiddletierso-6.5.50.so!0x3e28
0xc9dd5536 libsgmainso-6.5.49.so!0x10536
0xc9dd71c8 libsgmainso-6.5.49.so!0x121c8
0xf365607a libart.so!art_quick_generic_jni_trampoline+0x29
0xf364068a libart.so!MterpAddHotnessBatch+0x29
0xf3651b76 libart.so!art_quick_invoke_stub_internal+0x45


堆栈会说话的,他告诉我们


1、jni函数叫 com.txxxao.wireless.security.adapter.JNICLibrary.doCommandNative。

2、doCommandNative的实现在libsgmainso-6.5.49.so中,可能在偏移 0x121c8 附近。


先Hook jni函数一把


jni函数会告诉我们入参和返回值的类型,所以不能放过。


这个jni函数的声明在 libsgmain.so 这个假so里面

50.png


这个jni函数有两个参数,第一个参数是int型,第二个参数是Object数组


我们先上frida看看它是不是我们的目标。

Java.enumerateClassLoaders({
    "onMatch": function(loader) {
        if (loader.toString().indexOf("libsgmain.so") >= 0 ) {
            Java.classFactory.loader = loader; // 将当前class factory中的loader指定为我们需要的          
            console.log("loader = ",loader.toString());
        }
    },
    "onComplete": function() {
        console.log("success");
    }
});
// 此处需要使用 Java.classFactory.use
var  signCls =  Java.classFactory.use('com.txxxao.wireless.security.adapter.JNICLibrary');
signCls.doCommandNative.implementation = function(a,b){
    var retval = this.doCommandNative(a,b);
    console.log(" #### >>> a = " + a);
    if( a == 70102){
        console.log(" #### >>> Obj = " + b);
    }
    console.log(" #### >>> rc= " + retval)  // .entrySet().toArray());
    // var stack = threadinstance.currentThread().getStackTrace();
    // console.log("#### >>> Rc Full call stack:" + Where(stack));
    return retval;
}
// */


这里先解释下这个 70102 的来历,doCommandNative明显承担了很多功能,我们全部打印出来太乱了。


从之前的堆栈 com.axxbxxx.wireless.security.middletierplugin.c.d.a.a 这个类里面知道做 x-sign 签名的时候使用的命令参数是 70102 (对应的代码在 libsgmiddletier.so 这个假so里面)


跑一下51.png


确认过眼神,就是它了。


TIP:  Frida spawn模式跑这个脚本的时候, loader 没有输出, 这时候把脚本任意修改个空格,然后再保存。Frida会重新自动载入,这时候才能 有输出。


ida一下 libsgmainso-6.5.49.so


这个so还是很有料的。


首先他的导出函数里面找不到 doCommandNative 说明它是动态注册的。52.png

其次是so里面稍微有点身份的函数都是这种动态跳转。有效的抵抗了ida的F5。

53.png

我们一个一个来解决。


动态注册我们不怕,Hook RegisterNatives就可以搞定它

[RegisterNatives] java_class: com.txxxao.wireless.security.adapter.JNICLibrary name: doCommandNative sig: (I[Ljava/lang/Object;)Ljava/lang/Object; fnPtr: 0x7637c25ba4 module_name: libsgmainso-6.5.49.so module_base: 0x7637c07000 offset: 0x1eba4


结果出来,我们的目标是 0x1eba4


比较尴尬的是,ida中的 0x1eba4 的位置怎么看都不像函数的样子。


怎么办?


从这个so的种种表现来看,会不会它在运行时有些自修改之类的玩法?


先不管那么多了,我们把这个so从运行时dump出来再说。


TIP:   dump so的方法参考 91fans.com.cn/post/carcom…


我的测试手机是 64位的,所以dump出来了一个 64位的so56.png


这次有那么点意思了,不过由于烦人的 BR X11 动态跳转,导致我们还是不能愉快的f5


修复一下


如果我们知道这个 BR X11 指令的 x11的值,然后把它改成一个静态跳转,是不是可以修复可怜的F5?


说干就干

var mbase = Module.getBaseAddress('libsgmainso-6.5.49.so');
Interceptor.attach(mbase.add(0x1EC18),{
    onEnter:function(args){           
    console.log('Context  : ' + JSON.stringify(this.context));
  }
});


打印出来

Context  : {"pc":"0x7637921c18","sp":"0x7639089340","x0":"0x20","x1":"0x76390893e4","x2":"0x2776","x3":"0x28","x4":"0x1","x5":"0x0","x6":"0x4","x7":"0x0","x8":"0x16","x9":"0x7639089350","x10":"0x7637a6cd60","x11":"0x7637921c2c","x12":"0x76390893e8","x13":"0x76390893d8","x14":"0x1","x15":"0x0","x16":"0x76dadbf000","x17":"0x76da67d440","x18":"0x0","x19":"0x76506125e0","x20":"0x0","x21":"0x2776","x22":"0x76390896bc","x23":"0x7650261ddf","x24":"0x8","x25":"0x196","x26":"0x763908d588","x27":"0x2","x28":"0x76390893e8","fp":"0x76390893b0","lr":"0x76dadbf60c"}


当前地址是 0x7637921c18 - 0x1EC18 = 0x763793000,说明so基地址是 0x763793000 , x11的值是  0x7637921c2c - 0x763793000 = 0x1EC2C, 说明这里要跳转到 0x1EC2C


那就把这行指令修改成 b 0x1EC2C

57.png

再F5一下,就比原来漂亮一些了58.png


Hook 这个Native层的doCommandNative


这里主要就是介绍下 Hook Native函数的时候,如何打印 Object[] 类型的参数

var mbase = Module.getBaseAddress('libsgmainso-6.5.49.so');
// 1ed4c
Interceptor.attach(mbase.add(0x1EBA4),{
    onEnter:function(args){
        console.log('doCommandNative = ' + args[2].toString(10));
        var Object_javaArray = Java.use('[Ljava.lang.Object;');
        var ArrayArgs_3 = Java.cast(args[3], Object_javaArray);
        var ArrayClz = Java.use("java.lang.reflect.Array");
        var len = ArrayClz.getLength(ArrayArgs_3);
        if( args[2].toString(10) == 70102) {
            for(let i=0;i!=len;i++){
                var objUse = ArrayClz.get(ArrayArgs_3,i);
                if(objUse != null){
                    console.log("args[3] String value:", objUse.toString());
                }
            }
        }
    }
});


先用 Java.cast 转一下类型,然后再 java.lang.reflect.Array 来遍历。


结果还是比较漂亮的59.png


三、总结


Native层的保护措施更多,大家都太卷了。


熟练掌握java的反射用法,是玩好frida的必要条件。


ida的F5也是大家严防死守的,所以修复的方案也要了解下。

60.png


本想游戏人间,为何最后反被人间游戏。


TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。


关注微信公众号: 奋飞安全,最新技术干货实时推送

相关文章
|
安全 搜索推荐 数据挖掘
电商类app开发定制,电商app制作开发
在电商行业的蓬勃发展下,越来越多的企业和个体商户开始向移动化方向转型,希望借助电商App提升销售额和用户粘性。然而,纷繁复杂的电商App市场,如何设计出一个功能强大又符合自身需求的电商App成为了迫切需要解决的问题。
|
6月前
|
架构师 Java
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
98 0
|
算法 Java 数据安全/隐私保护
App逆向百例|12|某电商App Sign分析
App逆向百例|12|某电商App Sign分析
397 0
|
6月前
|
XML Android开发 数据格式
Android Studio App开发实战项目之实现淘宝电商App首页界面(附源码,可用于大作业参考)
Android Studio App开发实战项目之实现淘宝电商App首页界面(附源码,可用于大作业参考)
798 1
|
存储 安全 小程序
电商在做独立系统或者APP的时候如何确保其安全性
在网络高度发展的今天,信息安全是人们关心的永恒话题。保证信息的安全,包括各个方面,不单单指消费客户信息,还包括产品信息,系统收付款等等。总的来说,保证整个系统,重要API的参数安全是非常之重要的!
|
算法 安全 数据安全/隐私保护
某电商App sign签名算法解析(六)
某电商App sign签名算法解析(六)
某电商App sign签名算法解析(六)
|
算法 安全 Java
某电商App sign签名算法解析(五)
某电商App sign签名算法解析(五)
某电商App sign签名算法解析(五)
|
JSON 算法 安全
某电商App 返回数据加密解密分析(四)
某电商App 返回数据加密解密分析(四)
某电商App 返回数据加密解密分析(四)
|
安全 Java
某A系电商App x-sign签名分析
某A系电商App x-sign签名分析
某A系电商App x-sign签名分析