###微信本地文件名逆向(JAVA层静态分析)
WinanDH
思路:查看MD5文件内容,逆向apk查找拼接路径代码,破解拼接文件MD5文件命名算法
环境:JADX 1.0.0,JEB,root手机6.0以上系统,frida,weixin707android1520 7.0.7.apk
查看微信本地文件目录
点进354XXX3a7ab文件,找到方便查找路径的image2文件夹(其它也可)
-将base文件夹中apk拖入Jadx中,文本搜索image2,点进去看到image2 前面append(g.acc().fvY)拼接的字符串,推测fvY可能为我们要找的。
双击fvY,右键查找用例,找到fvy赋值位置
这里看到fvY有两部分,aaC.fvX + aaC.fwb。先跳转fwb赋值处,看到fwb最终由 y D 赋值。y D分别对应微信新旧版本文件名算法规则。D为老版本,y为新版本
找到y赋值位置,String y = e.y(a2,D);
此处用JEB分析
通过分析d(cVar)函数发现,此函数为读取account.bin中4096个字节保存为字符串。(cVar和cVar2为相同文件不同路径)
然后通过Java中MD5处理为32字节
整理Java md5部分代码(md5.java)
用Frida HOOK y(int i,String str) 参数的值。
HOOK代码
根据上面步骤中可知acconut.bin分别存在 cVar、cVar2中。
那么就可以推断 cVar中account.bin目录与MicroMsg为同级目录。在备份文件中找到account.bin位置
根据步骤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)
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"
);
}
}
}
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"
);
}
}
}
import
frida,sys
def
on_message(message,data):
if
message[
'type'
]
=
=
'send'
:
print
(
"[*] {0}"
.
format
(message[
'payload'
]))
else
:
print
(message)
jscode
=
process
=
frida.get_remote_device().attach(
'com.tencent.mm'
)
script
=
process.create_script(jscode)
script.on(
'message'
,on_message)
script.load()
sys.stdin.read()
import
frida,sys
def
on_message(message,data):
if
message[
'type'
]
=
=
'send'
:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)