12 AUG AFTERNOON APK+EXE REVERSE

下载到豌豆荚,历史迭代版本都有
最新版比较难,所以在古早版本里从简单开始,从友好开始
天涯论坛看起来就是个贴吧
看到帖子就想下载,收藏,收藏在我的下载里面
今天就研究怎么找到下载的帖子加密的数据和研究加密的代码
首先运行adb中frida server
在这里插入图片描述
天涯社区包存放位置
在这里插入图片描述

aosp:/data/data # cd cn.tianya.light
aosp:/data/data/cn.tianya.light # ls
app_bugly                                              app_textures             cache       pangle_com.byted.pangle
app_crashrecord                                        app_tt_pangle_bykv_file  code_cache  shared_prefs
app_e_qq_com_dex_37f3f88ff312fff57329035c00e2d04b      app_turingdfp            databases
app_e_qq_com_plugin_37f3f88ff312fff57329035c00e2d04b   app_turingfd             files
app_e_qq_com_setting_37f3f88ff312fff57329035c00e2d04b  app_webview              lib

目的明确,找到离线下载数据存放的位置
方法一:导出整个databases,在navicat查看
方法二:再离线下载一个看文件最后更改的时间,确定是存在files还是databases
此处略查找过程,确定在databases里

aosp:/data/data/cn.tianya.light # cd databases
aosp:/data/data/cn.tianya.light/databases # ls
bugly_db_                 downloads.db-journal
bugly_db_-journal         pangle_com.byted.pangle_bd_embed_tea_agent.db
cache.db                  pangle_com.byted.pangle_bd_embed_tea_agent.db-journal
cache.db-journal          pangle_com.byted.pangle_downloader.db
data.db                   pangle_com.byted.pangle_downloader.db-journal
data.db-journal           pangle_com.byted.pangle_npth_log.db
download_info.db          pangle_com.byted.pangle_npth_log.db-journal
download_info.db-journal  pangle_com.byted.pangle_ttopensdk.db
downloads.db              pangle_com.byted.pangle_ttopensdk.db-journal

一通随便分析,在offline.db
那下一步把他导出来’
至于怎么导呢。不知道
好像不支持arm,看不了的样子
文件里已经给了,请放心享用~
在这里插入图片描述
在这里插入图片描述

怎么查看加密算法呢???

用jadx查看(因为搜索和检索很好用)
在androidmanifest.xml里找
肯定不太现实
不论是创建字段还是访问字段里的数据,都需要用到notedata,不妨搜索关键词找到代码呢~~
问题来了,
downloaddata里被加密的是notedata
download里被加密的是attachdata
到底搜什么比较好找呢
当然是两个都搜
哪个少找哪个
反正加密算法肯定都是一个路子
PS:记得忽略大小写取消啊~会少一点点哟
在这里插入图片描述
你看,这边能有个put encryptbytes,hook这个函数就差不多能知道
但是呢,做过sqlite的小朋友很清楚,int columnIndex = query.getColumnIndex这个东东在获取索引值,已经在搞事情了在这里插入图片描述

在这里插入图片描述

查看第一个query.getColumnIndex
  Cursor query = context.getContentResolver().query(CacheContentHelper.getNoteContentUri(context), null, "CATEGORYID=? AND NOTEID=? AND PAGEINDEX=?", new String[]{str, String.valueOf(i2), String.valueOf(i3)}, null);
        if (query != null) {
            if (query.moveToFirst()) {
                query.getInt(query.getColumnIndex(ContentProviderUtil.DEFAULT_ORDER));
                int columnIndex = query.getColumnIndex("NOTEDATA");
                if (!query.isNull(columnIndex) && (uncompress = CompressEncrypt.uncompress(EncryptUtil.encryptBytes(query.getBlob(columnIndex)))) != null) {
                    noteContentList = (NoteContentList) JSONUtil.parseString(uncompress);
                    query.close();
                    query = null;
                }
            }
            noteContentList = null;
            query.close();
            query = null;
        }
        if (query != null && !query.isClosed()) {
            query.close();
        }
if (!query.isNull(columnIndex) && (uncompress = CompressEncrypt.uncompress(EncryptUtil.encryptBytes(query.getBlob(columnIndex)))) != null) {

query.getBlob(columnIndex)?
读取blob流,输出到页面,说白了就是读取加密字段
通过索引值,获取加密数据
把query.getBlob(columnIndex)传入encryptbytes方法中
encrypt加密,decrypt解密,为什么数据库中加密字段还要encrypt呢
先放着不管先,改成DEcrypt,就是这么拽
在这里插入图片描述
通过decrypt操作完后返回给uncompress操作
先看uncompress操作
别问为什么不先看decrypt,问就是程序分析的惯性思维,找到离明文最近的方法
就去hook 这个uncompress
笑死,不会写,没人教我写hook代码,自己也是蓝狗一条
我们换个东东,用GDA4看看
拜托,有这个工具,去写java层的代码,有啥子一一诶~
还记得frida server嘛,怎么在模拟器里启起来应该不用说的吧
对应目录 ./frida哦
什么GDA4不会hook?
笑死,我也不会,但我摸索出来了
点一下右边的APK入口就能看到方法函数了
找一下uncompress,然后右键firda->hook方法
(what?你不知道为什么是这个)
(冷漠)
(都是一边不就知道打开离线下载的文件会触发哪个函数了~)
在这里插入图片描述
一打开hook,就自动打开天涯论坛,
打开离线下载,哗啦啦啦hook显示一堆东西
当地警方附件
根据分析,hook函数,由密文变成明文,说明,这个方法非常的至关重要

    public static String uncompress(byte[] p0){
       try{
          return new String(CompressEncrypt.unzip(p0));
       }catch(java.lang.Exception e1){
          p0.printStackTrace();
          return null;
       }
    }

明文<-uncompress<-unzip<-
在这里插入图片描述
input:bArr
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
new:新建
bArr强行转化为byteArraayInputStream
下面又把参数传递给gZIPInputStream
Java运用gZIP进行压缩和解压缩

   public static byte[] unzip(byte[] bArr) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
        GZIPInputStream gZIPInputStream = new GZIPInputStream(byteArrayInputStream);
        byte[] bArr2 = new byte[1024];
        while (true) {
            int read = gZIPInputStream.read(bArr2);
            if (read >= 0) {
                byteArrayOutputStream.write(bArr2, 0, read);
            } else {
                gZIPInputStream.close();
                byteArrayInputStream.close();
                byte[] byteArray = byteArrayOutputStream.toByteArray();
                byteArrayOutputStream.close();
                return byteArray;
            }
        }

查看DEcrypt
try-catch操作很多,异常情况才看第二个return
重要的只有一行

return EncryptJni.encryptData(bArr);
    /* renamed from: encryptBytes */
    public static byte[] DEcryptBytes(byte[] bArr) {
        if (bArr == null || bArr.length == 0) {
            return bArr;
        }
        try {
            return EncryptJni.encryptData(bArr);
        } catch (Throwable th) {
            th.printStackTrace();
            return ByteUtils.deOrderBytes(bArr);
        }
    }

所以去看看encryptData方法对bArr是什么个操作

/* loaded from: classes.dex */
public class EncryptJni {
    static final String TIANYA_TEXT = "tianya";

    static {
        try {
            System.loadLibrary(TIANYA_TEXT);
        } catch (Throwable th) {
            th.printStackTrace();
        }
    }
    /* JADX INFO: Access modifiers changed from: package-private */
    public static native byte[] encryptData(byte[] bArr);
           static native String getLoginkey();

竟然什么都没有,说明代码不在Java层,在C语言层
打开zip解压缩过的天涯论坛下lib文件夹
在哪里看native代码在哪里呢?
上面有system loadlibrary为的是将lib加载到系统中
参数是TIANYA_TEXT,真实数据是tianya
那么要去搜索哪个关键词了呢?
lib+tianya+.so=libtianya.so
有知情人士透露:armeabi-v7a
这个elf文件用32位IDA去check
通常搜都是搜java,涉及到开发的知识,写一遍就知道了,或者听高人一言也能少走十年弯路
在这里插入图片描述
很神奇的事encrypt和decrypt是一样的代码,换而言之,对称加密
汇编转C:view+open subview+F5
没有意义的灰色内容右键hide cast

jbyteArray __fastcall Java_cn_tianya_jni_EncryptJni_encryptData(JNIEnv *env, jobject thiz, jbyteArray bytes)
{
  jsize v5; // r6
  jbyte *v6; // r4

  v5 = (*env)->GetArrayLength(env, bytes);
  v6 = malloc(v5);
  (*env)->GetByteArrayRegion(env, bytes, 0, v5, v6);
  j_EncryptData(v6, v5);
  (*env)->SetByteArrayRegion(env, bytes, 0, v5, v6);
  free(v6);
  return bytes;
}

JNIEnv *env:java和C的翻译官,无所谓
jobject thiz,:不重要
jbyteArray bytes:input
v5+v6:申请空间给传入的加密数据
GetByteArrayRegion:把申请的空间填入
关键在 j_EncryptData(v6, v5)
ps:v6为input,v5为length
双击进入

void __fastcall j_EncryptData(unsigned __int8 *s, int len)
{
  EncryptData(s, len);
}

没有内容,双击EncryptData(s, len)

void __fastcall EncryptData(unsigned __int8 *s, int len)
{
  j_j_ReOrderData(s, len);
}

没有内容,双击j_j_ReOrderData(s, len)

void __fastcall j_j_ReOrderData(unsigned __int8 *s, int len)
{
  j_ReOrderData(s, len);
}

没有内容,双击j_ReOrderData(s, len)

unsigned __int8 *__fastcall j_ReOrderData(unsigned __int8 *data, int len)
{
  return ReOrderData(data, len);
}

没有内容,双击 ReOrderData(data, len)

unsigned __int8 *__fastcall ReOrderData(unsigned __int8 *data, int len)
{
  int v2; // r6
  int v3; // [sp+7h] [bp-21h]
  char v4; // [sp+Bh] [bp-1Dh]

  v2 = 0;
  v4 = 33;
  v3 = -2127046473;
  while ( v2 < len )
  {
    data[v2] ^= *(&v3 + v2 % 5);
    v2 += v2 % 5 + 1;
  }
  return data;
}

循环异或操作,v3,v4改成16进制,右键hexadecimal

  v4 = 0x21;
  v3 = 0x8137D8B7;

方法:读取数据库加密数据,把数据给C语言异或解密
将解密数据给uncompress+unzip
数据库解密告一段落,开启下一个例子
just_hook.apk
拖入GDA和jadx和雷电

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值