鱼C论坛

 找回密码
 立即注册
查看: 3421|回复: 0

带360壳分析umeng协议

[复制链接]
发表于 2018-2-1 10:35:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 蓝铁 于 2018-2-1 15:06 编辑

0x00 序
为什么要带壳分析umeng协议啊,因为嘬呗。
0x01 charles抓包
直接打开 charles 手机设置好代理,过滤掉肯定无关的链接,从手机打开需要抓包的软件。发现只有2条网络请求 http://alog.umeng.com/app_logs
1.png
一看就知道是umeng的协议,但是参数加密了,只能反编译看看他是如何加密的。挂起 jadx 打开apk,发现apk 360加固了,没有办法只能脱壳。拿出我的脱壳神机google5儿子(自己编译的android4.4的系统,修改了内核代码,能过掉proc文件状态的反调试)
0x02 针对性反编译&&过掉签名验证
可是安装的时候提示
2.png
我靠设备版本太低,没关系,反编译修改一下最低sdk版本。
3.png
加上-s参数,只反编译资源文件,然后打开apktool.yml这个文件
4.png
把这里修改成19.ok。重打包提示签名被修改,没关系继续安装xposed hook签名模块(DisableVerifySignature.apk)。然后软件就可以打开了。
0x03 过掉反调试&&脱壳(不一样的脱壳)
根据吾爱 欧阳锋锋大神的帖子 https://www.52pojie.cn/thread-595960-1-1.html 过掉 时间差,rtld_db_dlactivity 这两个反调试一路走到这里 图片描述dump 出dex
5.png
文件。再次拖入 jadx 发现还是不对啊。是真实代码,可是没有umeng的代码。这是怎么回事啊。和我之前脱的软件不一样,难道360又升级了。带着疑惑我又打开了我自己写的一个通用脱壳软件。先给大家介绍下我的软件:

本工具是一个apk软件,打开后listview显示手机上安装的所有用户apk(图标➕apk名字),然后可以选择需要脱壳apk,然后再运行需要脱壳apk。即可完成脱壳。

代码实现: (java+jni)

1xmlpull解析选择apk的apkminifest,获取其包名,ApplicationName,MainActityName。

2Xposed hook android.content.ContextWrapper attachBaseContext得到壳的classloder

3根据classloder继续hook真正类的oncreate。

4继续根据classloader获取内存中的所有cookie。

5继续调用jni。根据cookie能转换成DexFile,然后其实就是解析dex文件了。

6在内存其实他的指向都是完整的。只不过没有在连续的地方。dump下来的也就不完整。那么我就分部dump。1。classdef之前的,2classdef之后的,3classdef4.classdata,5opcode。然后修改指向组合。
0x04 dump后的代码修复
通过这个软件dump下来的dex文件有60个,我把每个dex文件都打开看看,发现jar包都单独是一个dex文件,感觉和分包一样。想了想再把他们组合再修复oncrete 肯定是需要很长时间。不修复了。只看umeng这个dex把。
jadx 打开dex 搜索 host  
6.png
直接就找到了。
7.png
看到了参数传递了byte[],继续跟踪调用的地方。
9.png
跟到这里发现 调用了ch的b函数,里面肯定是处理了a变量,最后返回了 byte[].但是我怎么搜索都收拾不到a变量在哪里调用了,继续跟踪 b函数,
跟了一圈发现umeng的代码写的真是好啊,各种继承,接口,越看越晕都不知道谁掉的谁。
8.png
怎么和我之前 抓包的情况不一样啊。之前抓过几次都是 几个变量拼接,然后在调用 通用加密函数,虽然加密函数可能在jni,可能有ollvm混淆,但是都能看懂大概啊。这个是越看越懵。

最后才想起原来dump出来的指令被优化了,需要修复
11.png

全局搜索替换所有优化的地方,修复完看到了引用的地方
这下代码看懂了
12.png
13.png
14.png
他把每一个参数都单独取出来转换成byte[] 然后写入OutputStream
既然看懂了那么就看看她这几个参数都是啥直接传进去就ok了。刚好他有一个tostring函数
15.png
0x05 带壳hook原始类
拖出来的dex没有修复不能 动态调试,那么我hook一下打印出来就好了
        XposedBridge.log("开始hook....360加固");
            //hook加固后的包,首先hook getNewAppInstance这个方法来获取context对象
            XposedHelpers.findAndHookMethod("com.stub.StubApp", lpparam.classLoader,
                    "getNewAppInstance", Context.class, new XC_MethodHook() {
                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.afterHookedMethod(param);
                            //获取到360的Context对象,通过这个对象来获取classloader
                            Context context = (Context) param.args[0];
                            //获取360的classloader,之后hook加固后的就使用这个classloader
                            final ClassLoader classLoader = context.getClassLoader();
                            //下面就是强classloader修改成360的classloader就可以成功的hook了


                            Class<?> db = XposedHelpers.findClass("u.aly.db", classLoader);
                            Class<?> dg = XposedHelpers.findClass("u.aly.dg", classLoader);
                            Class<?> bp = XposedHelpers.findClass("u.aly.bp", classLoader);
                            Class<?> ap = XposedHelpers.findClass("u.aly.ap", classLoader);
                            final Class<?> bn = XposedHelpers.findClass("u.aly.bn", classLoader);
                            final Class<?> ao = XposedHelpers.findClass("u.aly.ao", classLoader);
                            final Class<?> ar = XposedHelpers.findClass("u.aly.ar", classLoader);
                            final Class<?> bf = XposedHelpers.findClass("u.aly.bf", classLoader);
                            final Class<?> az = XposedHelpers.findClass("u.aly.az", classLoader);
                            final Class<?> ax = XposedHelpers.findClass("u.aly.ax", classLoader);
                            final Class<?> bb = XposedHelpers.findClass("u.aly.bb", classLoader);
                            final Class<?> bl = XposedHelpers.findClass("u.aly.bl", classLoader);


                            XposedHelpers.findAndHookMethod("u.aly.bp", classLoader, "e",String.class, new XC_MethodHook() {//hook 參數生成的地方
                                @Override
                                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                    super.beforeHookedMethod(param);
                                    XposedBridge.log(  "參數生成的地方2:"+   param.thisObject.toString());

17.png
参数是都打印出来了,简单的能看懂,看不懂的继续跟代码发现又他娘的是加密了,不过还好加密函数还是同一个,但是看了看加密的串是10个对象的100个参数。

630232_zw104lkgfx8gomd.png
18.png

继续xposed hook打印参数把,幸好他们的类名有规律
  final String class_name[] = {"at", "cr", "av", "bc", "bg", "be", "bm", "bl", "ba", "an", "bd", "aq", "bn"};
                            for (int i = 0; i < class_name.length; i++) {
                                final int finalI = i;
                                XposedHelpers.findAndHookMethod("u.aly." + class_name[i], classLoader, "b", dg, new XC_MethodHook() {//hook 參數生成的地方
                                    @Override
                                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                        super.beforeHookedMethod(param);
                                        XposedBridge.log(class_name[finalI] + "------:" + param.thisObject.toString());
                                    }
                                });
                            }
并且有2个类是他们的组合
20j.png

继续看懂参数:有的参数是设备固定值,有些参数是固定值的md5,有些参数是固定参数加上时间戳的md5.都看懂了模拟代码。ok大功告成。继续看下一条协议。
0x06 打印堆栈查看调用关系
1
第二条协议其实还是这个接口,就是参数多了一点,多的那点就是第一条协议的返回值。虽然看懂了,但是不知道她是怎么解析返回值的啊,
21.png

install_channel 找到这个参数 hook 赋值的地方,打印堆栈
XposedHelpers.findAndHookConstructor("u.aly.bb", classLoader, new XC_MethodHook() {
                                @Override
                                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                    super.beforeHookedMethod(param);
                                     StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();
                                    for (int i = 0; i <wodelogs.length ; i++) {
                                        XposedBridge.log( wodelogs[i].toString());
                                    }
                                }
                            });
发现是这里读的
23.png
0x07 后续
嗯。加密,解密逻辑都找到了,模拟代码把。直接拿他代码就可以,稍微修改一下,根据hook下来的参数,多比较几次。测试,请求参数一摸一样的还原。。。。
由于不会排版,排版是参考了别人的,
最后,感谢论坛中各大神的分享,让我学习到了很多东西。

评分

参与人数 1荣誉 +4 鱼币 +4 贡献 +2 收起 理由
李星 + 4 + 4 + 2

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-31 03:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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