###微信本地文件名逆向(JAVA层静态分析)
WinanDH

  • 目的:解密新版微信本地文件 tencent/MicroMsg/...MD5,文件命名算法
  • 思路查看MD5文件内容,逆向apk查找拼接路径代码,破解拼接文件MD5文件命名算法
  • 环境JADX 1.0.0,JEB,root手机6.0以上系统,frida,weixin707android1520 7.0.7.apk

  • 查看微信本地文件目录
  • 点进354XXX3a7ab文件,找到方便查找路径的image2文件夹(其它也可)
    3

-将base文件夹中apk拖入Jadx中,文本搜索image2,点进去看到image2 前面append(g.acc().fvY)拼接的字符串,推测fvY可能为我们要找的。
4
4.1

  • 双击fvY,右键查找用例,找到fvy赋值位置
    5
  • 这里看到fvY有两部分,aaC.fvX + aaC.fwb。先跳转fwb赋值处,看到fwb最终由 y D 赋值。y D分别对应微信新旧版本文件名算法规则。D为老版本,y为新版本
    7
  • 找到y赋值位置,String y = e.y(a2,D);
    8
  • 跟进函数y(),函数中cVar 、 cVar2 为路径字符串,d(cVar)函数,为读写文件操作。
    9
  • 分析d(cVar)函数,这里JADX挂了,转用JEB
    10
  • 此处用JEB分析
    11
  • 通过分析d(cVar)函数发现,此函数为读取account.bin中4096个字节保存为字符串。(cVar和cVar2为相同文件不同路径)
    然后通过Java中MD5处理为32字节
    12
  • 整理Java md5部分代码(md5.java)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.security.MessageDigest;
import java.util.Random;
import java.io.*;
public class md5{
public static void main (String args[]){
try {
File f = new File("F:\\WXHOOK\\account.bin");
byte[] data = new byte[4096];
new FileInputStream(f).read(data);
MessageDigest instance = MessageDigest.getInstance("MD5");
instance.update(data);
instance.update(Integer.toString(270843106).getBytes());
byte[] md5Key = instance.digest();
System.out.println("oooo:"+md5Key);
StringBuilder stringBuilder = new StringBuilder(md5Key.length * 2);
char[] cArr = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
for (int i2 = 0; i2 < 16; i2++) {
byte b = md5Key[i2];
stringBuilder.append(cArr[(b >>> 4) & 15]).append(cArr[b & 15]);
}
String stringBuilder2 = stringBuilder.toString();
System.out.println("xxxx:"+stringBuilder2);
}catch (Throwable t) {
System.out.println("222222");
}
}
}
  • account.bin还缺少关键路径,即static String y(int i, String str) 中str的值

13

  • 用Frida HOOK y(int i,String str) 参数的值。
    14
  • HOOK代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import frida,sys
def on_message(message,data):
if message['type']=='send':
print("[*] {0}".format(message['payload']))
else:
print(message)
jscode="""
console.log("Script loaded successfully ");
Java.perform(function(){
var StringClass=Java.use("java.lang.String");
var haha=Java.use('com.tencent.mm.kernel.e');
var arr = Java.use("java.util.Arrays");
send("com.tencent.mm.kernel.e...");
haha.y.overload("int","java.lang.String").implementation=function(i,str){
send(" -+y +-!");
console.log("xxxx:"+i);
console.log("oooo:"+str);
}
});
"""
process=frida.get_remote_device().attach('com.tencent.mm')
script=process.create_script(jscode)
script.on('message',on_message)
script.load()
sys.stdin.read()
  • 结果正是我们要解密的文件名
  • 根据上面步骤中可知acconut.bin分别存在 cVar、cVar2中。
    那么就可以推断 cVar中account.bin目录与MicroMsg为同级目录。在备份文件中找到account.bin位置
    15
  • 根据步骤8中,从account.bin中读取4096字节保存成字符串,并用JAVA md5算法加密字符串(java中与C++ mD5存在差异。实现:读取指定字符串长度并实现C++与JAVA相同MD5算法)
    https://www.cnblogs.com/dh666/p/11821233.html
  • md5.java测试(测试微信版本为7.0.15)
    16