吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12283|回复: 57
上一主题 下一主题
收起左侧

[Android 原创] 对XX水印相机的分析

  [复制链接]
跳转到指定楼层
楼主
Forgo7ten2020 发表于 2021-8-10 02:31 回帖奖励
本帖最后由 Forgo7ten2020 于 2021-8-11 13:05 编辑

看了@闷骚小贱男 帖子https://www.52pojie.cn/thread-1353870-1-1.html,也想自己实战分析一下

今日水印相机自定义水印

apk没有加壳,还是比较好分析的

抓包

打开app开始抓包,有以下几个api

逆向分析

分析天气参数的获取

jeb分析

jeb中搜索相应的URI

选择第二个来到 一个所有request方法的类

摁X进行交叉引用

参数1和参数2即为经纬度坐标

来到这里

发现内部类对其进行了解析,强转为WeatherInfo

public class WeatherInfo {
    public String apparentTemperature; // 体感温度:30
    public String aqi;   // 空气质量指数:37
    public String aqiLevel; // 空气质量等级:优
    public String humidity; // 湿度:75%
    public String pressure; // 压强:1001
    public String temperature; // 温度:27
    public String weather; // 天气:晴
    public String winddirection; // 风向:西南风
    public String windpower; // 风力:1级
}

接下来就是如何hook该内部类了

调试验证

运行fridaserver

使用frida的objection工具

先启动目标app

objection -N -h 192.168.0.104 -p 8888 -d -g com.xhey.xcamera explore

然后查找com.xhey.xcamera.e的类

com.xhey.xcamera on (google: 8.1.0) [net] # android hooking search classes com.xhey.xcamera.e                                                       
com.xhey.xcamera.e
com.xhey.xcamera.e$1
com.xhey.xcamera.e$5
com.xhey.xcamera.e$6
com.xhey.xcamera.e$8
com.xhey.xcamera.e$a
com.xhey.xcamera.e$b

Found 7 classes

挨个查看每个内部类的方法

com.xhey.xcamera on (google: 8.1.0) [net] # android hooking list class_methods com.xhey.xcamera.e$1                                                 
private static void com.xhey.xcamera.e$1.b(xhey.com.network.model.BaseResponse)
public static void com.xhey.xcamera.e$1.lambda$Wc1CpEPvMWi1606k4HUcLAjQgiw(xhey.com.network.model.BaseResponse)
public void com.xhey.xcamera.e$1.a(xhey.com.network.model.BaseResponse<com.xhey.xcamera.data.model.bean.ConfigStatus>)
public void com.xhey.xcamera.e$1.onError(java.lang.Throwable)
public void com.xhey.xcamera.e$1.onSuccess(java.lang.Object)

Found 5 method(s)

发现e$1,e$5,e$8具有相同的方法,且与上反编译源码中方法类似

function main(){
    Java.perform(function () {
        var clazz = Java.use('com.xhey.xcamera.e$5');
        clazz.a.implementation = function (response_argu) {
            var result = clazz.a.apply(this, arguments);
            var response = Java.cast(response_argu, Java.use("xhey.com.network.model.BaseResponse"));
            console.log("BaseResponse.code", response.code.value);
            console.log("BaseResponse.data", response.data.value);
            console.log("BaseResponse.msg", response.msg.value);
            console.log("BaseResponse.toast_msg", response.toast_msg.value);
            return result;
        }
    });
}
setImmediate(main)

frida来运行调试

frida -H 192.168.0.104:8888 -f com.xhey.xcamera -l syxj.js --no-pause

打印出如下信息

[Remote::com.xhey.xcamera]-> BaseResponse.code 200
BaseResponse.data com.xhey.xcamera.data.model.bean.WeatherInfo@1d5fef8
BaseResponse.msg success
BaseResponse.toast_msg 

发现WeatherInfo,就是解密后的类

分析时间的获取

部分同天气获取,定位到

其中v1.build()调用了aes,来对json字符串进行加密

得到key和iv均为"xhey-cc4275fd-43",AES模式为"AES/CBC/PKCS5Padding"

package xhey.com.network.retrofit2;
public enum AESUtil {
    private static final String ENCRYPTION_IV = "xhey-cc4275fd-43";
    private static final String ENCRYPTION_KEY = "xhey-cc4275fd-43";
    public static String decrypt(String arg4) {
    }

    public static String encrypt(String arg5) {
        if(TextUtils.isEmpty(arg5)) {
            return arg5;
        }

        try {
            Cipher v0 = Cipher.getInstance("AES/CBC/PKCS5Padding");
            v0.init(1, AESUtil.makeKey(), AESUtil.makeIv());
            Log.e("time", "==" + Base64.encode(v0.doFinal(arg5.getBytes()), 0));
            return new String(Base64.encode(v0.doFinal(arg5.getBytes()), 2)).trim();
        }
        catch(Exception v5) {
            Log.e("AESUtil", "=encrypt=" + v5.getMessage());
            return "";
        }
    }

    static AlgorithmParameterSpec makeIv() {
        return new IvParameterSpec("xhey-cc4275fd-43".getBytes("utf-8"));
    }

    static SecretKeySpec makeKey() {
        return new SecretKeySpec("xhey-cc4275fd-43".getBytes("utf-8"), "AES");
    }
}

此时我们就可以对Fiddler抓到的包来进行加解密了。

requestTimeInChina继续查看上层引用,同样来到了com.xhey.xcamera.e类中

同样frida分析后发现是e$8

分析定位

当程序获取天气参数的时候,使用了定位

交叉引用向上追溯

com.xhey.xcamera.network.service.NetWorkServiceKt.requestWeatherInfocom.xhey.xcamera.e.b(java.lang.String[])+2Ahcom.xhey.xcamera.e.a(boolean, com.baidu.location.BDLocation)+5D8h

找到赋值的地方

hook这两个方法就可以修改经纬度也就是定位了

而BDLocation是百度地图的api

同理速度也可以hookBDLocation.getSpeed来修改

插件编写

Frida hook脚本

(换行全部都没了,重新格式化下是可以的)

function printStack(name) {    Java.perform(function () {        var Exception = Java.use("java.lang.Exception");        var ins = Exception.$new("Exception");        var straces = ins.getStackTrace();        if (straces != undefined && straces != null) {            var strace = straces.toString();            var replaceStr = strace.replace(/,/g, "\\n");            console.log("=============================" + name + " Stack strat=======================");            console.log(replaceStr);            console.log("=============================" + name + " Stack end=======================\r\n");            Exception.$dispose();        }    });}function main() {    Java.perform(function () {        /**         * 解析 /next/android/config         */        var clazz = Java.use('com.xhey.xcamera.e$1');        clazz.a.implementation = function (response_argu) {            var response = Java.cast(response_argu, Java.use("xhey.com.network.model.BaseResponse"));            // console.log("BaseResponse.code",response.code.value);            // console.log("BaseResponse.data",response.data.value);            // console.log("BaseResponse.msg",response.msg.value);            // console.log("BaseResponse.toast_msg",response.toast_msg.value);            var result = clazz.a.apply(this, arguments);            return result;        }    });    Java.perform(function () {        Java.openClassFile("/data/local/tmp/r0gson.dex").load();        const gson = Java.use('com.r0ysue.gson.Gson');        /**         * 解析天气 /next/GetCurrentWeather         * public class WeatherInfo {         *      public String apparentTemperature; // 体感温度:30         *      public String aqi;   // 空气质量指数:37         *      public String aqiLevel; // 空气质量等级:优         *      public String humidity; // 湿度:75%         *      public String pressure; // 压强:1001         *      public String temperature; // 温度:27         *      public String weather; // 天气:晴         *      public String winddirection; // 风向:西南风         *      public String windpower; // 风力:1级         * }         */        var clazz = Java.use('com.xhey.xcamera.e$5');        clazz.a.implementation = function (response_argu) {            var response = Java.cast(response_argu, Java.use("xhey.com.network.model.BaseResponse"));            var weather_info = Java.cast(response.data.value, Java.use("com.xhey.xcamera.data.model.bean.WeatherInfo"))            // 对值做修改            weather_info.temperature.value = Java.use("java.lang.String").$new("-99");            //            // console.log("BaseResponse.code", response.code.value);            // console.log("weather_info", gson.$new().toJson(weather_info));            // console.log("BaseResponse.msg", response.msg.value);            // console.log("BaseResponse.toast_msg", response.toast_msg.value);            var result = clazz.a.apply(this, arguments);            return result;        }    });    Java.perform(function () {        Java.openClassFile("/data/local/tmp/r0gson.dex").load();        const gson = Java.use('com.r0ysue.gson.Gson');        /**         * 解析时间 /next/inchina         *      public class TimeStatus {         *      private boolean in_china;   // 是否在中国:true         *      private boolean stopDevice; // false         *      private int timestamp;      // 时间戳         * }         */        var clazz = Java.use('com.xhey.xcamera.e$8');        clazz.a.implementation = function (response_argu) {            var response = Java.cast(response_argu, Java.use("xhey.com.network.model.BaseResponse"));            var time_info = Java.cast(response.data.value, Java.use("com.xhey.xcamera.data.model.bean.TimeStatus"));                        // console.log("=== TIME ===")            // console.log("BaseResponse.code", response.code.value);            // console.log("BaseResponse.data", response.data.value);            // console.log("BaseResponse.msg", response.msg.value);            // console.log("BaseResponse.toast_msg", response.toast_msg.value);            // console.log("Time", gson.$new().toJson(time_info));            // console.log("TimeStatus.timestamp", time_info.timestamp.value);            time_info.timestamp.value = Java.use("java.lang.Integer").$new("1912521600").intValue();            var result = clazz.a.apply(this, arguments);            return result;        }    });    Java.perform(function () {        var clazz = Java.use('com.baidu.location.BDLocation');        // 纬度        clazz.getLatitude.implementation = function () {            var result = clazz.getLatitude.apply(this, arguments);            // console.log("Latitude", result);            result = Java.use("java.lang.Double").$new("36.269893").doubleValue();            // console.log("Change Latitude", result);            return result;        }        // 经度        clazz.getLongitude.implementation = function () {            var result = clazz.getLongitude.apply(this, arguments);            // console.log("Longitude", result);            result = Java.use("java.lang.Double").$new("117.094738").doubleValue();            // console.log("Change Longitude", result);            return result;        }        // 速度        clazz.getSpeed.implementation = function () {            var result = clazz.getSpeed.apply(this, arguments);            // console.log("Speed", result);            result = Java.use("java.lang.Float").$new("99.99").floatValue();            // console.log("Change Speed", result);            return result;        }    });}function func() {    Java.perform(function () {        var clazz = Java.use('xhey.com.network.retrofit2.AESUtil');        clazz.decrypt.implementation = function (data) {            var result = clazz.decrypt.apply(this, arguments)            printStack("AES decrypt");            console.log("aes decrypt data:", data);            console.log("aes decrypt result: ", result);            return result;        }    });    Java.perform(function () {        var clazz = Java.use('xhey.com.network.retrofit2.AESUtil');        clazz.encrypt.implementation = function (data) {            var result = clazz.encrypt.apply(this, arguments)            printStack("AES encrypt");            console.log("aes encrypt data:", data);            console.log("aes encrypt result: ", result);            return result;        }    });}setImmediate(main)

Xposed插件开发

hook的类已经分析完了,懒得造轮子了

效果图

总结

这算是自己分析的第一个app。花了差不多一天的时间,第一次接触这么大的代码量,刚开始有些懵逼。

但分析完发现这个app还是很简单的,没有壳也没有混淆,比较适合我这样的新手。

Frida啥的还是不熟练,疯狂找bug。

刚开始修改时间没有效果,最后发现是因为先执行了原方法result = clazz.a.apply(this, arguments);,导致时间在方法体内被直接应用了。



该文章也同步上传至我的GitHub博客 Example(0) 今日水印相机自定义水印 | Forgo7ten'blog

中间也多次向@闷骚小贱男 寻求指导,再次感谢



免费评分

参与人数 13威望 +1 吾爱币 +34 热心值 +13 收起 理由
枝条 + 1 + 1 谢谢@Thanks!
stanba + 1 + 1 热心回复!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
123Ambition + 1 + 1 热心回复!
elevo + 1 + 1 谢谢@Thanks!
泡泡汽水 + 1 + 1 谢谢@Thanks!
sunning-H-C + 1 + 1 谢谢@Thanks!
10086abc + 1 + 1 我很赞同!
arrymarry + 1 + 1 我很赞同!
芽衣 + 2 + 1 用心讨论,共获提升!
lf1314 + 1 + 1 谢谢@Thanks!
wangyuan004 + 1 + 1 我很赞同!
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

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

推荐
涛之雨 发表于 2021-8-10 10:06
鉴于初入坑,写的还算完整,鼓励一下,
此外本文中有图片炸了应该是漏传了,
顺便说一下,你的博客里的图片全炸了。。。
推荐
mengma1120 发表于 2021-8-10 12:58
可以可以不错,加水印的这些app都不知道为啥要出
4#
xunxunmimi0936 发表于 2021-8-10 10:19
头像被屏蔽
5#
asdswd 发表于 2021-8-10 11:19
提示: 作者被禁止或删除 内容自动屏蔽
6#
丶不负年华 发表于 2021-8-10 11:54
下载不到,打开就404了
7#
xyz星人 发表于 2021-8-10 11:56
楼主强啊~感谢楼主分享
8#
hubohang 发表于 2021-8-10 12:05
大佬 学习了
9#
 楼主| Forgo7ten2020 发表于 2021-8-10 12:47 |楼主
涛之雨 发表于 2021-8-10 10:06
鉴于初入坑,写的还算完整,鼓励一下,
此外本文中有图片炸了应该是漏传了,
顺便说一下,你的博客里的图 ...

感谢鼓励
图片漏传已补,发了帖子后发现hexo出问题了,但是当时太晚了就睡了
10#
 楼主| Forgo7ten2020 发表于 2021-8-10 13:03 |楼主
丶不负年华 发表于 2021-8-10 11:54
下载不到,打开就404了

博客在修,修完了我再告诉你哈
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-26 15:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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