前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >apicloud的APP文件解密

apicloud的APP文件解密

作者头像
田小檬
发布2022-08-30 17:04:20
9110
发布2022-08-30 17:04:20
举报
文章被收录于专栏:田小檬博客

本文最后更新于2022年06月10日,已超过3天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

文件的解密入口定义在 WebViewClient中的 shouldInterceptRequest方法 在apiCloud中对应的类为 com.uzmap.pkg.uzcore.h.d 对应的方法定义如下

代码语言:javascript
复制
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (!this.b) {
return super.shouldInterceptRequest(view, url);
}
String d = b.d(url);
if (!b.e(d)) {
return b(url, d);
}
WebResourceResponse a = a(url, d);
return a == null ? super.shouldInterceptRequest(view, url) : a;
}

其中 this.b 的值决定了 是否使用解密 (this.b的值对应于 compile.Properties.smode() 具体可以参考 com.uzmap.pkg.uzcore.h.f.y()方法 如下

代码语言:javascript
复制
public void y() {
setNetworkAvailable(true);
d B = B();
boolean z = B.q;        ===>  这个值决定了是否进行资源文件的解密
String j = B.j();
com.uzmap.pkg.a.k.e.a((WebView) this, z);
a a = a.a(this.f);
a.a((b) this);
setWebChromeClient(a);
setWebViewClient(c.a(this.f, z, j));
this.g = new com.uzmap.pkg.uzcore.uzmodule.c(this);
this.g.a(z, j);
}

B.q的值在 com.uzmap.pkg.uzcore.b.e.a(InputStream , boolean) 和 com.uzmap.pkg.uzcore.r.y() 这里两个方法中进行设置 通过分析得出最终取决于 compile.Properties.smode()的值 当 this.b = false 时候不使用解密 即此时对应的资源文件没有加密 否则 则判断是否为 html,js,css的文件类型再进行相应的解密处理

从已知的分析来看, apicloud使用的加密算法是RC4, 而且密钥的长度为 20 只不过在不同版本中使用的RC4算法略有不同 descriptor属性为 "sdk" 或者 uz_version在 1.2.0以后的(包括1.2.0) 使用 com.uzmap.pkg.uzcore.external.Enslecb.ohs方法进行解密 这个方法在目前的分析来看使用的都是通用的RC4算法 没有uz_version属性 或者 uz_version 在 1.2.0 以前的 则使用变种的RC4算法 这个算法定义在java层 而不是在jni层 这个RC4的state大小只有20字节(通用的RC4的state大小由256字节)

关于这个的判断逻辑可以参考下边的代码逻辑(属性k为true 则调用ohs方法解密, 否则使用变种的rc4算法解密)

代码语言:javascript
复制
​
if ("sdk".equals(b.q())) {    // 这里对应的是 compile.Properties.descriptor 方法的返回值
    k = true;
    return;
}
String v = this.v.metaData.getString("uz_version");
if (!TextUtils.isEmpty(v)) {
    String[] vs = v.split("\\.");
    if (vs != null && vs.length >= 3) {
        String v1 = vs[0];
        String v2 = vs[1];
        int ver1 = Integer.valueOf(v1).intValue();
        int ver2 = Integer.valueOf(v2).intValue();
        if ((ver1 == 1 && ver2 >= 2) || ver1 > 1) {   // uz_version>=1.2.x 则 i.k = True
            k = true;
        }
    }
}
​

当然这里 ohs 的实现逻辑不一定是rc4算法 保险的话可以考虑通过 unicorn/AndroidNativeEmu/Unidbg 之类的工具来直接调用得到解密结果

对于变种的rc4算法,密钥则来源于 Enslecb.oc 方法 和 compile.Properties.cloudKey 密钥具体构造如下 1、提取compile.Properties.cloudKey 中的10个字符 如果 cloudKey 长度为10 则直接返回 ; 否则 每4个字符取前两个字符拼接成长度为10的字符串 2、Enslecb.oc() + 第1步中的字符串 对于上述的两种解密方法都涉及到对 jni的调用 而且jni里边有对apk签名的校验 签名的校验过程是: 先对apk的签名字节进行rc4加密 接着对加密的apk签名字节进行base64编码 然后对 base64字符串进行 md5 得到长度为 32 的 hex字符串最后将这个字符串与jni中的字符串常量进行比对, 相等则通过校验, 否则校验失败apk签名串的初始化过程在 Enslecb.sm 中调用 这个方法会在application的onCreate方法中先调用 所以如果使用 AndroidNativeEmu之类的工具的话需要先手动调用 Enslecb.sm 方法, 传入apk对应的签名字节 保证后续的调用能通过校验

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档