• app逆向java层一般步骤


    0.

    frida版本号14.2.2
    objection==1.9.6
    app版本4.22.0
    1.抓包

    使用CharlesPostern,通过VPN代理形式进行抓包,而不是通过给WIFI设置HTTP代理的方式。使用VPN可以同时抓到Http(s)Socket的包。

    2.抓取目标用户的用户信息

    URLhttps://yapi.haohaozhu.cn/member/getUserInfo

    加密参数shawshank,打开jadx搜索shawshank,得知该参数是一个n2类里名为E的常量,接下来搜n2.E,调用的位置锁定位置。

    com.hzhu.m.f.b.d.a

    关健代码:

        public static String a(TreeMap<String, String> treeMap) {
            String replace = com.hzhu.base.f.x.a.a(com.hzhu.base.f.x.b.a(new Gson().toJson((Object) treeMap), n2.B)).replace("+", com.xiaomi.mipush.sdk.Constants.ACCEPT_TIME_SEPARATOR_SERVER).replace(com.appsflyer.share.Constants.URL_PATH_DELIMITER, "_");
            StringBuilder sb = new StringBuilder();
            sb.append(n2.A);
            sb.append(replace);
            return sb.toString();
        }
    
    

    使用objection动态调试下

    objection -g  com.hzhu.m explore
    

    hook下上面的方法

    android hooking watch class_method com.hzh
    u.m.f.b.d.a --dump-args --dump-backtrace --dump-return
    

    得到结果

    (agent) Attempting to watch class com.hzhu.m.f.b.d and method a.
    (agent) Hooking com.hzhu.m.f.b.d.a(java.util.TreeMap)
    (agent) Hooking com.hzhu.m.f.b.d.a(boolean)
    (agent) Registering job 1408148254974. Type: watch-method for: com.hzhu.m.f.b.d.a
    

    由结果得知他有两个重载方法。

    因为通过jadx分析我们知道参数java.util.TreeMap的方法才是我们想要的。所以修改objection代码,在需要hook的方法后面加个空格加上参数类型,可以进一步锁定具体是那个hook方法的。

    android hooking watch class_method com.hzh
    u.m.f.b.d.a java.util.TreeMap --dump-args --dump-backtrace --dump-return
    

    --dump-args:打印参数

    --dump-backtrace: 打印调用栈

    --dump-return:打印返回值

    然后现在objection处于等待状态,重新点击app上的内容,可以得到下面的内容,其中关键代码

    (agent) [0475123810009] Arguments com.hzhu.m.f.b.d.a("<instance: java.util.TreeMap>")
    (agent) [0475123810009] Return Value: "qEpcsu2CCkruqxB6h.itrY2p2tx1wchcSiAE5QNgxOMAtH4yGpq4n4C9P3JM9nDz4I23igrYVBNTsiY9eVP5NvV-bE3Su6aspx_z2xZfusGGtETbuehv2g="
    (agent) [1408148254974] Called com.hzhu.m.f.b.d.a(boolean)
    (agent) [1408148254974] Backtrace:
    	com.hzhu.m.f.b.d.a(Native Method)
    	com.hzhu.m.f.b.d$b.intercept(HttpInit.java:3)
    	okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:10)
    	okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:1)
    	com.hzhu.m.f.b.c.intercept(HhzExceptionCheckInterceptor.kt:16)
    	.....后面的调用栈省略
    
    

    通过上面的结果 我们知道了返回值

    qEpcsu2CCkruqxB6h.itrY2p2tx1wchcSiAE5QNgxOMAtH4yGpq4n4C9P3JM9nDz4I23igrYVBNTsiY9eVP5NvV-bE3Su6aspx_z2xZfusGGtETbuehv2g=就是我们的目标结果,然后参数就不知道是个啥了,只知道是java.util.TreeMap实例, objection对于这种复杂的参数类型是无法打印的,这个时候我们就要借助frida了

    。先用objection生成个frida代码模版。

    android hooking generate simple com.hzhu.m.f.b.d
    

    结果

    Java.perform(function() {
        var clazz = Java.use('com.hzhu.m.f.b.d');
        clazz.a.implementation = function() {
    
            //
    
            return clazz.a.apply(this, arguments);
        }
    });
    
    

    objection只能生成一个大概的框架代码,具体内容还需要自己加,保存下来先运行看看。之后执行代码

    frida -U com.hzhu.m -l crack_haohaozhu.js
    

    得到错误提示,我们可以根据错误提示进一步优化代码,这里我们知道了a有两个重载方法。

    Error: a(): has more than one overload, use .overload(<signature>) to choose from:
    	.overload('java.util.TreeMap')
    	.overload('boolean')
    
    Java.perform(function() {
        const gson = Java.use('com.r0ysue.gson.Gson').$new();
    
        var clazz = Java.use('com.hzhu.m.f.b.d');
        clazz.a.overload('java.util.TreeMap').implementation = function(x) {
            //
            console.log("x:=",x);
            const json_x=gson.toJson(x)
            console.log("json_x",json_x);
            return clazz.a.apply(this, arguments);
        }
    });
    

    得到传入的参数为

    {"uid":"3171385"}
    

    接下来就是找到算法的位置。将之前静态分析的代码简化

      String replace = com.hzhu.base.f.x.a.a(com.hzhu.base.f.x.b.a(new Gson().toJson((Object) treeMap), null)).replace("+", "-").replace("/", "_");;
    

    首先,

    com.hzhu.base.f.x.b.a(new Gson().toJson((Object) treeMap), n2.B)
    

    我们知道他的返回值为byte[] 类型,然后看外层的com.hzhu.base.f.x.a.a

    根据jadx上面的提示

    /* compiled from: Base64 */
    

    盲猜之后做了一个base64操作(后来证实确实是)。

    得到结果replace之后还没完,接下来还有个

         StringBuilder sb = new StringBuilder();
            sb.append(n2.A);
            sb.append(replace);
            return sb.toString();
    

    查看代码得知n2.A是qEpcsu2CCkruqxB6h.itrY2p2tx。

    至此到这里就分析完了。

    最终的shawshank的结果就是上面的sb.toString()的值。

    简单捋一下结果

    1.传入目标字符串{"uid":"3171385"},注意是字符串。uid就是用户的id

    2.com.hzhu.base.f.x.b.a一顿操作生成byte数组

    3.然后做个base64操作,将字节数组转成字符串。

    4.在得到的结果前面拼接上n2.A,得到最终加密参数。

  • 相关阅读:
    性能战术
    易用性
    可操作性
    软件架构师如何工作
    idea安装
    Windows下安装TensorFlow
    进度十四(11.01)
    进度十三(10.31)
    进度十二(10.30)
    进度十一(10.29)
  • 原文地址:https://www.cnblogs.com/c-x-a/p/15145781.html
Copyright © 2020-2023  润新知