Android微信数据库解密

Android微信数据库解密

本篇主要讲下解密EnMicroMsg.db 。

1:数据库密码

微信的数据库密码规则 是 imei +uin ,获取bytes[], 生成md5,截取前 7位。

不过目前imei微信写死的"1234567890ABCDEF";

uin 一般会在微信的 shared_prefs 中的 auth_info_key_prefs.xml 或者

system_config_prefs.xml 。

2:相关代码

以下代码 以微信8.0.31 为例.

首先对应的是 数据库下的openDatabase方法。

复制代码
   public static SQLiteDatabase openDatabase(String str, byte[] bArr, SQLiteCipherSpec sQLiteCipherSpec, CursorFactory cursorFactory, int i14, DatabaseErrorHandler databaseErrorHandler, int i15) {
        SQLiteDatabase sQLiteDatabase = new SQLiteDatabase(str, i14, cursorFactory, databaseErrorHandler);
        sQLiteDatabase.open(bArr, sQLiteCipherSpec, i15);
        return sQLiteDatabase;
    }

接着是o83.e类下,可以看到有下面这块代码.

复制代码
if (str3.endsWith("EnMicroMsg.db")) {
    eVar.f216755a = SQLiteDatabase.openDatabase(str3, bytes, sQLiteCipherSpec, null, i15, eVar, 8);
} else {
    eVar.f216755a = SQLiteDatabase.openDatabase(str3, bytes, sQLiteCipherSpec, null, i15, eVar);
}

根据方法,找到调用的地方.

复制代码
linkedHashSet.add("1234567890ABCDEF");
it = linkedHashSet.iterator();
z17 = false;
while (true) {
    if (!it.hasNext()) {
        break;
    }
    //此处写死的1234567890ABCDEF.
    String str5 = (String) it.next();
    //此处就是获取到的数据库密码 ,h.f获取md5值. 
    String substring = h.f((str5 + j14).getBytes()).substring(0, 7);
    this.f216727b = substring;
    try {
        //传入数据库密码substring
        e r14 = e.r(str2, substring, 0, true);
        this.f216726a = r14;
        a(r14);
        if (!t.d(true).equals(str5)) {
            Log.i("MicroMsg.DBInit", "IMEI changed detected: " + str5);
            n.a().b(258, str5);
            tb2.e.INSTANCE.idkeyStat(181L, 5L, 1L, false);
            break;
        }
        break;
    } catch (SQLiteException e17) {
        if (e17 instanceof SQLiteDatabaseCorruptException) {
            z17 = true;
        } else {
            z17 = false;
            break;
        }
    }
}

h.f()如下:

复制代码
public static final String f(byte[] bArr) {
    char[] cArr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bArr);
        byte[] digest = messageDigest.digest();
        char[] cArr2 = new char[digest.length * 2];
        int i14 = 0;
        for (byte b14 : digest) {
            int i15 = i14 + 1;
            cArr2[i14] = cArr[(b14 >>> 4) & 15];
            i14 = i15 + 1;
            cArr2[i15] = cArr[b14 & 15];
        }
        return new String(cArr2);
    } catch (Exception unused) {
        return null;
    }
}

j14 是通过参数传递过来 . o83.f 类的 n()

复制代码
public boolean n(String str, String str2, String str3, long j14, String str4, HashMap<Integer, b> hashMap, boolean z14) {
    int lastIndexOf;
    if (str.lastIndexOf("/") != -1) {
        this.f216782a += "." + str.substring(lastIndexOf + 1);
    }
    k(str2);
    if (this.f216785d.f(str, str2, str3, j14, hashMap, z14)) {
        o83.a aVar = this.f216785d;
        if (aVar.f216726a != null) {
            aVar.e();
            this.f216788g = "";
            this.f216783b = this.f216785d.f216726a;
            return true;
        }
    }
    this.f216785d.e();
    this.f216788g = "";
    this.f216783b = null;
    this.f216785d = null;
    Log.i(this.f216782a, "initDB failed. %s", "");
    return false;
}

继续 查找j14的来源 可以找到c10.x.b().g(). 而这个方法返回值就是uin.

相关推荐
kymjs张涛2 小时前
零一开源|前沿技术周报 #7
android·前端·ios
九皇叔叔2 小时前
【9】PostgreSQL 之 vacuum 死元组清理
数据库·postgresql
风雅的远行者2 小时前
mysql互为主从失效,重新同步
数据库·mysql
宇钶宇夕3 小时前
S7-1200 系列 PLC 中 SCL 语言的 PEEK 和 POKE 指令使用详解
运维·服务器·数据库·程序人生·自动化
绿蚁新亭3 小时前
Spring的事务控制——学习历程
数据库·学习·spring
wuwu_q3 小时前
RK3566/RK3568 Android11 修改selinux模式
android·rk3568
_一条咸鱼_4 小时前
Android Runtime内存共享与访问控制原理剖析(71)
android·面试·android jetpack
scilwb4 小时前
占用栅格地图数据集
数据库
嘉小华4 小时前
第三章:焦点分发全链路源码解析
android
嘉小华4 小时前
Android 协程全景式深度解析:第六章 高阶并发模式
android