某动画app的签名验证学习

最近一直在折腾ollvm,结果折腾了几天一直编译不通过,持续踩坑中,只好暂时放在一边整点app分析分析

该app为某动画app,我在看雪上看到有人分析过这个app:https://bbs.pediy.com/thread-258593.htm,
感觉分析的不是很详细,就自己分析了一下,写了一篇分析过程

目的:修改该app为永久会员

首先打开apk看了一下:
在这里插入图片描述

显然想要修改会员日期就需要找到该界面对应的activity,修改方式很多,比如直接搜索会员字符串,然后就能定位到相关位置UserInfoActivity
在这里插入图片描述
查看getExpire:

在这里插入图片描述
查看setExpire:

在这里插入图片描述
发现就是dateFormat对象进行了几次转换变成字符串和“2100-01-01”字符串进行比较,只要大于等于该值就是永久会员了。

那么久很简单了,直接使用androidKiller修改getExpire返回值就可。

然后当我反编译之后开始运行的时候,却发现并不行

在这里插入图片描述

那怎么办呢,我首先考虑到的是搜索字符串,果然软件没有这么单纯,搜不到,所以估计是在服务器端进行的验证

使用fiddler抓个包:

在这里插入图片描述

imei映入眼帘,直接搜索一下试试:

在这里插入图片描述

果然搜到了,查看getV():

在这里插入图片描述

原来是一个native方法,返回类型为String,传入了一个当前的时间戳,想来直接修改返回值是不现实的了,只能看so层代码分析校验码是怎么产生的了。

然而不幸的是使用ida静态分析发现有些参数没有显示,所幸找到了参数的位置,可以根据动态调试找到具体的值:
在这里插入图片描述
但是网上说jeb也有了查看so的功能,用其查看发现非常的清晰:
在这里插入图片描述
由图中可知,一共有三个check分别和定值"dt8re"+"rt9ws"拼接其中有两个参数一个hash1,一个hash2
经过计算得出

目前想到过两种方法动态调试也可以:(1)动态调试获取该值;(2)使用hook技术取定值的时间戳并打印返回值,按照控制变量法计算出结果

下面仅展示hook法:

(1)首先使用frida hook js脚本

Java.perform(function () {
    
    
    var CheckUtils = Java.use("info.zzjian.dididh.util.CheckUtils");
    CheckUtils.getV.overload("long").implementation = function (j) {
    
    
        var ret = this.getV(j);
        console.log(this.getV(0));
        return (ret);
    };
});

打印结果为:

33cc6f39fdt8re3af08b80crt9ws3ff2a033f

根据结果拆分为:

(check1)33cc6f39f + dt8re + (check2)3af08b80c + 9ws3f + (check3)f2a033f

根据控制变量法求出

hash1 = -1916912749L;
hash2 = 1344359219L;

求出最终的字符串为:

String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;

根据还原的算法,重写一个CheckUtils.java让它在java层直接返回字符串

public class CheckUtils {
    
    
    public CheckUtils() {
    
    
    }
 
    public String getV(long ts) {
    
    
        String check1 = Long.toHexString(13904573343L + ts * 2);
        String check2 = Long.toHexString(15821486092L + ts);
        String check3 = Long.toHexString(17165845311L + ts);
        return check1 + "dt8re" + check2 + "rt9ws" + check3;
    }
}

使用命令行将编写的java文件转化为smali文件,这里有写好的脚本可以在我的资源文件中查看下载(转化的根据实际情况对包名进行更改):

.class public Linfo/zzjian/dididh/util/CheckUtils;
.super Ljava/lang/Object;
.source "CheckUtils.java"


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 3
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    .line 4
    return-void
.end method


# virtual methods
.method public getV(J)Ljava/lang/String;
    .registers 8

    .prologue
    .line 7
    const-wide v0, 0x33cc6f39fL

    const-wide/16 v2, 0x2

    mul-long/2addr v2, p1

    add-long/2addr v0, v2

    invoke-static {v0, v1}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v0

    .line 8
    const-wide v2, 0x3af08b80cL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v1

    .line 9
    const-wide v2, 0x3ff2a033fL

    add-long/2addr v2, p1

    invoke-static {v2, v3}, Ljava/lang/Long;->toHexString(J)Ljava/lang/String;

    move-result-object v2

    .line 10
    new-instance v3, Ljava/lang/StringBuilder;

    invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V

    invoke-virtual {v3, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v3, "dt8re"

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v1, "rt9ws"

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v0

    return-object v0
.end method

再用写好的代码覆盖androidkiller中的类
然后在反编译就成功的得到了结果:
在这里插入图片描述

补:当然由于这个apk是没有检测hook的,我们可以直接通过Xposed或者fridahook实现破解VIP的功能,当我查看作者声明的时候发现作者也不反对使用Xposed等进行修改:
在这里插入图片描述
因此还是非常感谢作者给了我这个学习的机会,但是破解版的apk就不在这里提供了,如果大家有需要可以直接上官网下载原版:http://dddh.pub/

补:经过动态调试发现该程序是64位的程序,所以ida32会无法显示字符串,使用ida64能够正常看到字符串

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43632667/article/details/105778450