首页
社区
课程
招聘
[原创]关于android 微信 frida 使用技巧
发表于: 2018-6-22 15:14 17249

[原创]关于android 微信 frida 使用技巧

2018-6-22 15:14
17249

最近在研究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 被大魔头编辑 ,原因:
收藏
免费 3
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  junkboy   +1.00 2018/06/22
最新回复 (12)
雪    币: 546
活跃值: (520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
太给力了
2018-6-22 20:14
0
雪    币: 226
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢大神分享,先收藏以后慢慢研究
2018-6-25 11:42
0
雪    币: 402
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大神,这是python2还是python3啊?
2018-7-7 10:39
0
雪    币: 29
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
用那个py都可以吧,我也是用这个来跑的,都还不错的,我跑android wx, 需要沟通的加Q:2650249406
2018-7-15 17:16
0
雪    币: 34
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
cdn协议是明文 有问题的是部分加密参数
2018-7-15 23:46
0
雪    币: 15
活跃值: (765)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
大神 我问下我怎么挂不上最新版的微信呢?直接在这里出错 session = rdev.attach("com.tencent.mm")  
2018-8-28 23:29
0
雪    币: 574
活跃值: (405)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
膜拜大神,先记录下,慢慢学习消化
2018-12-12 15:09
0
雪    币: 1490
活跃值: (9913)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
9
大神能否告知下分析过程啊?我想知道偏移量是怎么找出来的
2019-1-3 15:26
0
雪    币: 121
活跃值: (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
大神 为何 libwechatnetwork.so 这个hook不到,找不到这个so。但是mmtls关键代码在里面啊
2019-5-14 19:29
0
雪    币: 16
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
求加qq 411874483 大牛真有事情找你
2019-7-23 15:55
0
雪    币: 7
活跃值: (188)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
何时才能像大佬一样优秀!
2020-11-16 19:08
0
游客
登录 | 注册 方可回帖
返回
//