最近在研究Android长连接CDN协议,调试微信,恶心的我都快疯了,是时候祭出frida代码了
对应的微信安卓 6.6.7 最新版 代码贴出来给大家用吧
拿 xposed 和frida 结合一下 看看日志 基本上想要的 都能知道了 侵权删帖
import frida
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
rdev = frida.get_remote_device()
processes = rdev.enumerate_processes()
session = rdev.attach("com.tencent.mm") #如果存在两个一样的进程名可以采用rdev.attach(pid)的方式
# modules = session.enumerate_modules()
# for module in modules:
# export_funcs = module.enumerate_exports()
# for export_func in export_funcs:
# if export_func.name == "adler32":
# print("\t%s\t%s"%(export_func.name,hex(export_func.relative_address)))
script = session.create_script("""
console.log("[*] Starting script");
var p_libMMProtocalJni = Module.findBaseAddress("libMMProtocalJni.so");
var p_libwechatmm = Module.findBaseAddress("libwechatmm.so");
send("libMMProtocalJni.so @ " + p_libMMProtocalJni.toString());
send("libwechatmm.so @ " + p_libwechatmm.toString());
var offset_makeheader = 0x000159E1;
var ptrmakeheader = p_libMMProtocalJni.add(offset_makeheader);
send("ptrmakeheader @ " +ptrmakeheader.toString());
var outbufferptr = 0;
var outbufsizeptr = 0;
var offset_Adler_32 = 0x000239E5;
var p_Adler_32 = p_libMMProtocalJni.add(offset_Adler_32);
send("p_Adler_32 @ " +p_Adler_32.toString());
var offset_md5update = 0x2DC51;
var p_md5update = p_libMMProtocalJni.add(offset_md5update);
send("p_Adler_32 @ " +p_md5update.toString());
var offset_md5fina = 0x2DCEF;
var p_md5fina = p_libMMProtocalJni.add(offset_md5fina);
send("p_md5fina @ " +p_md5fina.toString());
var md5inbuffer = 0 ;
Interceptor.attach(p_md5fina, {
onEnter: function(args) {
console.log("[*] p_md5fina onEnter");
md5inbuffer = args[0];
},
onLeave: function (retval) {
send(hexdump(md5inbuffer, { length: 0x10, ansi: true }));
send("p_md5fina onLeave()");
}
});
Interceptor.attach(p_md5update, {
onEnter: function(args) {
console.log("[*] p_md5update onEnter");
inbuffer = args[1];
send(hexdump(inbuffer, { length: args[2].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("p_md5update onLeave()");
}
});
Interceptor.attach(p_Adler_32, {
onEnter: function(args) {
console.log("[*] offset_Adler_32 onEnter");
buf = args[0];
sesssionkey = args[1];
protobuff = args[2];
send("uin "+args[0].toInt32());
send(hexdump(sesssionkey, { length: 0x10, ansi: true }));
send(hexdump(protobuff, { length: args[3].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("offset_Adler_32 onLeave()" +retval);
}
});
var offset_packheaderandbody = 0x00014F71;
var p_packheaderandbody = p_libMMProtocalJni.add(offset_packheaderandbody);
send("p_packheaderandbody @ " +p_packheaderandbody.toString());
Interceptor.attach(p_packheaderandbody, {
onEnter: function(args) {
console.log("[*] p_packheaderandbody onEnter");
buf = args[0];
send(hexdump(buf, { length: 60, ansi: true }));
}
});
Interceptor.attach(ptrmakeheader, {
onEnter: function(args) {
console.log("[*] makeheader onEnter");
buf = args[0];
outbufferptr = args[1];
outbufsizeptr = args[2];
send("a1024 "+args[3].toInt32());
send(hexdump(buf, { length: 55, ansi: true }));
},
onLeave: function (retval) {
outbufsize = Memory.readUInt(outbufsizeptr)
send(hexdump(outbufferptr, { length: outbufsize, ansi: true }));
send("makeheader onLeave()" +retval);
}
});
var offset_alder32Checksum = 0x1B1BD1;
var p_offset_alder32Checksum = p_libwechatmm.add(offset_alder32Checksum);
send("p_offset_alder32Checksum @ " +p_offset_alder32Checksum.toString());
Interceptor.attach(p_offset_alder32Checksum, {
onEnter: function(args) {
console.log("[*] p_offset_alder32Checksum onEnter");
outbufferptr = args[1];
send(hexdump(outbufferptr, { length: args[2].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("p_offset_alder32Checksum onLeave()" +retval);
}
});
""")
# Here's some message handling..
# [ It's a little bit more meaningful to read as output :-D
# Errors get [!] and messages get [i] prefixes. ]
def on_message(message, data):
if message['type'] == 'error':
print("[!] " + message['stack'])
elif message['type'] == 'send':
print("[i] " + message['payload'])
else:
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
import frida
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
rdev = frida.get_remote_device()
processes = rdev.enumerate_processes()
session = rdev.attach("com.tencent.mm") #如果存在两个一样的进程名可以采用rdev.attach(pid)的方式
# modules = session.enumerate_modules()
# for module in modules:
# export_funcs = module.enumerate_exports()
# for export_func in export_funcs:
# if export_func.name == "adler32":
# print("\t%s\t%s"%(export_func.name,hex(export_func.relative_address)))
script = session.create_script("""
console.log("[*] Starting script");
var p_libMMProtocalJni = Module.findBaseAddress("libMMProtocalJni.so");
var p_libwechatmm = Module.findBaseAddress("libwechatmm.so");
send("libMMProtocalJni.so @ " + p_libMMProtocalJni.toString());
send("libwechatmm.so @ " + p_libwechatmm.toString());
var offset_makeheader = 0x000159E1;
var ptrmakeheader = p_libMMProtocalJni.add(offset_makeheader);
send("ptrmakeheader @ " +ptrmakeheader.toString());
var outbufferptr = 0;
var outbufsizeptr = 0;
var offset_Adler_32 = 0x000239E5;
var p_Adler_32 = p_libMMProtocalJni.add(offset_Adler_32);
send("p_Adler_32 @ " +p_Adler_32.toString());
var offset_md5update = 0x2DC51;
var p_md5update = p_libMMProtocalJni.add(offset_md5update);
send("p_Adler_32 @ " +p_md5update.toString());
var offset_md5fina = 0x2DCEF;
var p_md5fina = p_libMMProtocalJni.add(offset_md5fina);
send("p_md5fina @ " +p_md5fina.toString());
var md5inbuffer = 0 ;
Interceptor.attach(p_md5fina, {
onEnter: function(args) {
console.log("[*] p_md5fina onEnter");
md5inbuffer = args[0];
},
onLeave: function (retval) {
send(hexdump(md5inbuffer, { length: 0x10, ansi: true }));
send("p_md5fina onLeave()");
}
});
Interceptor.attach(p_md5update, {
onEnter: function(args) {
console.log("[*] p_md5update onEnter");
inbuffer = args[1];
send(hexdump(inbuffer, { length: args[2].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("p_md5update onLeave()");
}
});
Interceptor.attach(p_Adler_32, {
onEnter: function(args) {
console.log("[*] offset_Adler_32 onEnter");
buf = args[0];
sesssionkey = args[1];
protobuff = args[2];
send("uin "+args[0].toInt32());
send(hexdump(sesssionkey, { length: 0x10, ansi: true }));
send(hexdump(protobuff, { length: args[3].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("offset_Adler_32 onLeave()" +retval);
}
});
var offset_packheaderandbody = 0x00014F71;
var p_packheaderandbody = p_libMMProtocalJni.add(offset_packheaderandbody);
send("p_packheaderandbody @ " +p_packheaderandbody.toString());
Interceptor.attach(p_packheaderandbody, {
onEnter: function(args) {
console.log("[*] p_packheaderandbody onEnter");
buf = args[0];
send(hexdump(buf, { length: 60, ansi: true }));
}
});
Interceptor.attach(ptrmakeheader, {
onEnter: function(args) {
console.log("[*] makeheader onEnter");
buf = args[0];
outbufferptr = args[1];
outbufsizeptr = args[2];
send("a1024 "+args[3].toInt32());
send(hexdump(buf, { length: 55, ansi: true }));
},
onLeave: function (retval) {
outbufsize = Memory.readUInt(outbufsizeptr)
send(hexdump(outbufferptr, { length: outbufsize, ansi: true }));
send("makeheader onLeave()" +retval);
}
});
var offset_alder32Checksum = 0x1B1BD1;
var p_offset_alder32Checksum = p_libwechatmm.add(offset_alder32Checksum);
send("p_offset_alder32Checksum @ " +p_offset_alder32Checksum.toString());
Interceptor.attach(p_offset_alder32Checksum, {
onEnter: function(args) {
console.log("[*] p_offset_alder32Checksum onEnter");
outbufferptr = args[1];
send(hexdump(outbufferptr, { length: args[2].toInt32(), ansi: true }));
},
onLeave: function (retval) {
send("p_offset_alder32Checksum onLeave()" +retval);
}
});
""")
# Here's some message handling..
# [ It's a little bit more meaningful to read as output :-D
# Errors get [!] and messages get [i] prefixes. ]
def on_message(message, data):
if message['type'] == 'error':
print("[!] " + message['stack'])
elif message['type'] == 'send':
print("[i] " + message['payload'])
else:
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
再补上一个xposed 的代码
package com.example.xposedhook;
import android.util.Log;
import java.security.MessageDigest;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
/**
* Created by xlzh on 2017/4/11.
*/
public class XposedHook implements IXposedHookLoadPackage {
private static String wechat_package = "com.tencent.mm";
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals(wechat_package)) {
XposedBridge.log(lpparam.packageName +" -> load");
final Class<?> clazz = XposedHelpers.findClass("com.tencent.mm.xlog.app.XLogSetup", lpparam.classLoader);
XposedBridge.log(clazz.getName() +" -> find");
XposedHelpers.findAndHookMethod(clazz, "keep_setupXLog",
boolean.class,
String.class,
String.class,
Integer.class,
Boolean.class,
Boolean.class,
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[4] = true;
param.args[5] = true;
//XposedBridge.log("isopen = " + param.args[5]);
}
});
findAndHookMethod("com.tencent.mm.sdk.platformtools.x$1", lpparam.classLoader, "getLogLevel",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// XposedBridge.log("---Hook com.tencent.mm.sdk.platformtools.v$1---");
param.setResult(0);
}
});
//
findAndHookMethod("com.tencent.mars.mm.MMLogic", lpparam.classLoader, "setMmtlsCtrlInfo",boolean.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = false;
Log.i("mars", "MMLogic setMMTLS enable= " + param.args[0]);
}
});
// findAndHookMethod("com.tencent.mm.network.t", lpparam.classLoader, "Gj",new XC_MethodReplacement()
// {
// @Override
// protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
// Log.i("mars", "StnLogic.makesureLongLinkConnected");
// return null;
// }
// });
//10788250=WeChatWi.10788250 (ASCII "req2Buf error, no find scene:%d")
final Class<?> PByteArrayclass = lpparam.classLoader.loadClass("com.tencent.mm.pointers.PByteArray"); //XposedHelpers.findClass("com.tencent.mm.pointers.PByteArray", lpparam.classLoader);
findAndHookMethod("com.tencent.mm.protocal.MMProtocalJni", lpparam.classLoader, "pack",
byte[].class, //0
PByteArrayclass.newInstance().getClass(),//1
byte[].class, //2
byte[].class, //3
String.class, //4
int.class, //5
int.class, //6
int.class, //7
byte[].class, //8
byte[].class, //9
byte[].class, //10
int.class, //11
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
byte[] pbvalues = (byte[]) param.args[0];
byte[] pbvaluesargs2 = (byte[]) param.args[2];
byte[] pbvaluesargs3 = (byte[]) param.args[3];
String pbvaluesargs4 = (String) param.args[4];
int pbvaluesargs5 = (int) param.args[5];
int pbvaluesargs6 = (int) param.args[6];
int pbvaluesargs7 = (int) param.args[7];
byte[] pbvaluesargs8 = (byte[]) param.args[8];
byte[] pbvaluesargs9 = (byte[]) param.args[9];
byte[] pbvaluesargs10 = (byte[]) param.args[10];
int pbvaluesargs11 = (int) param.args[11];
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack ###################################################### ");
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvalues : "+bytesToHex(pbvalues));
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs2 : "+bytesToHex(pbvaluesargs2));
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs3 : "+bytesToHex(pbvaluesargs3));
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs4 : "+pbvaluesargs4);
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs5 : "+ pbvaluesargs5);
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs6 : "+ pbvaluesargs6);
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs7 : "+ pbvaluesargs7);
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs8 : "+bytesToHex(pbvaluesargs8));
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs9 : "+bytesToHex(pbvaluesargs9));
if(pbvaluesargs10.length > 0) {
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs10 : " + bytesToHex(pbvaluesargs10));
}
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.pack pbvaluesargs11 : "+ pbvaluesargs11);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Object pbvaluesreturn = (Object) param.args[1];
byte[] value = (byte[])XposedHelpers.getObjectField(pbvaluesreturn,"value");
Log.i("mars", "com.tencent.mm.protocal.MMProtocalJni.packreturn pbvaluesreturn : "+ bytesToHex(value));
}
});
findAndHookMethod("com.tencent.mm.y.q", lpparam.classLoader,"BE",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String ret = (String) param.getResult();
Log.i("mars", "com.tencent.mm.y ###################################################### result : "+ret);
}
});
findAndHookMethod("com.tencent.mm.a.g", lpparam.classLoader,"p",
byte[].class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
byte[] pbvalues = (byte[]) param.args[0];
String v0_2;
int v0 = 0;
char[] v2 = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
MessageDigest v1 = MessageDigest.getInstance("MD5");
v1.update(pbvalues);
byte[] v3 = v1.digest();
int v4 = v3.length;
char[] v5 = new char[v4 * 2];
int v1_1 = 0;
while(v0 < v4) {
int v6 = v3[v0];
int v7 = v1_1 + 1;
v5[v1_1] = v2[v6 >>> 4 & 15];
v1_1 = v7 + 1;
v5[v7] = v2[v6 & 15];
++v0;
}
v0_2 = new String(v5);
Log.i("mars", "com.tencent.mm.a.g ###################################################### ");
Log.i("mars", "com.tencent.mm.a.g pbvalues : "+bytesToHex(pbvalues));
Log.i("mars", "com.tencent.mm.a.g v0_2 : "+v0_2);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String ret = (String) param.getResult();
Log.i("mars", "com.tencent.mm.a.g ###################################################### result : "+ret);
}
});
findAndHookMethod(" com.tencent.mm.protocal.MMProtocalJni",lpparam.classLoader, "computerKeyWithAllStr",
int.class,
byte[].class,
byte[].class,
PByteArrayclass.newInstance().getClass(),
int.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Object pbvaluesreturn = (Object) param.args[3];
byte[] value = (byte[])XposedHelpers.getObjectField(pbvaluesreturn,"value");
Log.i("mars", "###################################################### computerKeyWithAllStr : "+ bytesToHex(value));
}
});
}
}
}
package com.example.xposedhook;
import android.util.Log;
import java.security.MessageDigest;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
/**
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-6-22 15:17
被大魔头编辑
,原因: