xposed输出qq加密前明文数据

这章主要介绍java层的hook,首先需要找到qq加密的函数在哪里,这里采用最简单的monitor的录制方法。

monitor是android sdk里面的一个小工具,就是之前的ddms,里面的录制调用的功能可以快速定位。

这里有一个疑问:为什么搜不到onClick的操作呢,没有的话他是通过什么实现的呢?有知道的评论一下呀,谢谢

定位之后发现了一个函数:com.tencent.qphone.base.util.CodecWarpper.nativeEncodeRequest

猜测这个函数就是最终的加密函数,通过jadx反编译qq的dex,找到该函数,是一个多态函数,有3中参数的可能。

这里不知道最终调用哪一种,所以3个都写了Hook,打印输出,判断出哪个被最终调用。

得到第二个是最常见的调用。故我们最终hook第二个。

这里然后打印即可得到加密前后的数据:可以看到最终发送的数据应该是携带版本号,qq号,以及该行为的类型的:第7和第15个参数是个数组,应该包含加密前明文,这里看介绍是使用了类似google的probuf的序列化操作,腾讯这里是jcestruct,过年前研究完了加上。

01-25 03:50:26.614 I/Xposed  ( 6657): param1 = class java.lang.Integer data =  50538
01-25 03:50:26.617 I/Xposed  ( 6657): param2 = class java.lang.String data =  312576676479927
01-25 03:50:26.617 I/Xposed  ( 6657): param3 = class java.lang.String data =  
01-25 03:50:26.617 I/Xposed  ( 6657): param4 = class java.lang.String data =  7.9.7.390008
01-25 03:50:26.617 I/Xposed  ( 6657): param5 = class java.lang.String data =  
01-25 03:50:26.617 I/Xposed  ( 6657): param6 before = class java.lang.String data =  StatSvc.GetOnlineStatus
01-25 03:50:26.617 I/Xposed  ( 6657): param7 before = class [B data =  [B@b9790c9
01-25 03:50:26.617 I/Xposed  ( 6657): param7 now= [-84, -19, 0, 5, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 4, -52, 73, 124, -95]
01-25 03:50:26.617 I/Xposed  ( 6657): param7 = ACED0005757200025B42ACF317F8060854E0020000787000000004CC497CA1
01-25 03:50:26.617 I/Xposed  ( 6657): param8 = class java.lang.Integer data =  537060431
01-25 03:50:26.617 I/Xposed  ( 6657): param9 = class java.lang.Integer data =  537060431
01-25 03:50:26.617 I/Xposed  ( 6657): param10 = class java.lang.String data =  2100327022
01-25 03:50:26.617 I/Xposed  ( 6657): param11 = class java.lang.Byte data =  0
01-25 03:50:26.617 I/Xposed  ( 6657): param12 = class java.lang.Byte data =  1
01-25 03:50:26.617 I/Xposed  ( 6657): param13 = class java.lang.Byte data =  1
01-25 03:50:26.617 I/Xposed  ( 6657): param15 type = class [B
01-25 03:50:26.617 I/Xposed  ( 6657): param15 before = [-84, -19, 0, 5, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 12, 0, 0, 0, 12, 8, -18, -28, -63, -23, 7, 16, 0]
01-25 03:50:26.617 I/Xposed  ( 6657):  data =  [B@21c13ce
01-25 03:50:26.617 I/Xposed  ( 6657): param15 = [-84, -19, 0, 5, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 0, 12, 0, 0, 0, 12, 8, -18, -28, -63, -23, 7, 16, 0]
01-25 03:50:26.617 I/Xposed  ( 6657): param14 before = null
01-25 03:50:26.617 I/Xposed  ( 6657): param14 be error : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
01-25 03:50:26.618 I/Xposed  ( 6657): hook nativeEncodeRequest afterok???
01-25 03:50:26.618 I/Xposed  ( 6657): return now is : class [B[-84, -19, 0, 5, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, 0, 1, 60, 0, 0, 1, 60, 0, 0, 0, 10, 1, 0, 0, 0, 68, -99, 68, 46, -66, -78, 95, 57, -24, -40, -54, 78, -89, -110, -72, -77, -28, 11, 26, -68, -60, -58, -20, 75, -103, -32, -36, 0, 49, -68, 92, 118, 18, -2, -57, 92, -127, -109, 17, 78, 35, -6, 55, -82, -13, 123, -55, 104, -59, 61, 110, 82, -20, 15, -60, 35, 51, -52, -119, -78, -63, -107, -33, 16, 46, 0, 0, 0, 0, 14, 50, 49, 48, 48, 51, 50, 55, 48, 50, 50, -12, -116, 109, 94, 39, 10, 31, 13, -59, 110, -85, 84, -109, 98, -105, 26, -51, 73, 12, -117, 118, 77, 78, 74, 92, 57, 49, -61, 64, -18, 56, 100, 7, -66, 45, -128, 37, 76, -99, 118, -113, 102, 94, 117, -11, 45, 3, 106, -72, 19, 37, 52, -58, -116, 60, -2, -95, 92, 57, 13, 42, -128, 37, -99, 32, -11, -16, 28, 80, 51, 70, -28, 56, -61, -34, 18, -61, -10, -57, 83, 61, -29, -86, 116, 112, 34, 6, -94, 57, -57, 55, -79, 38, -53, 78, -58, 98, -18, 52, -58, -15, -98, -49, 73, 47, 23, -29, -74, -118, -16, -8, -103, 34, 9, -45, 87, 93, -105, -80, 103, 4, 82, -111, -128, 25, 68, 63, -101, 116, 113, 124, -122, 103, 92, 69, 111, 23, -98, 3, 0, 49, -98, 17, -7, -127, -63, 0, 55, 37, 90, 126, -125, 105, 115, 8, 32, -70, 64, -74, -89, -44, -67, 1, 5, -116, 32, 88, 42, 110, 5, -80, 120, 4, 15, 111, 9, 124, -80, 38, 57, 7, -23, 110, 124, 15, 57, -118, -76, 27, 48, 24, -114, -4, -12, -98, 44, -50, 47, -116, 124, -59, -47, 5, -110, 76, 68, -7, -27, -79, -38, 13, 81, -120, 13, 19, 63, 73, -77, 117, 76, -107, 10, 110, -120]
01-25 03:50:26.618 I/Xposed  ( 6657): return is : ACED0005757200025B42ACF317F8060854E002000078700000013C0000013C0000000A01000000449D442EBEB25F39E8D8CA4EA792B8B3E40B1ABCC4C6EC4B99E0DC0031BC5C7612FEC75C8193114E23FA37AEF37BC968C53D6E52EC0FC42333CC89B2C195DF102E000000000E32313030333237303232F48C6D5E270A1F0DC56EAB549362971ACD490C8B764D4E4A5C3931C340EE386407BE2D80254C9D768F665E75F52D036AB8132534C68C3CFEA15C390D2A80259D20F5F01C503346E438C3DE12C3F6C7533DE3AA74702206A239C737B126CB4EC662EE34C6F19ECF492F17E3B68AF0F8992209D3575D97B0670452918019443F9B74717C86675C456F179E0300319E11F981C10037255A7E8369730820BA40B6A7D4BD01058C20582A6E05B078040F6F097CB0263907E96E7C0F398AB41B30188EFCF49E2CCE2F8C7CC5D105924C44F9E5B1DA0D51880D133F49B3754C950A6E88

这里不知道为什么第14个参数,jadx显示是个byte[]类型的入参,但是不管怎么打印都打印不出来,显示是个空指针。猜测是不是这个地方传递密钥,但是只有第一次有,后面没有了,真的就是只传递一个空指针了。但是这里加密函数应该是传密钥的呀。。

所以这两天还会接着分析一下so层的。

代码如下:


package com.example.liuti.hooksport;


import android.app.Application;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.util.Log;
import android.util.SparseArray;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Arrays;

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.XposedBridge.log;
import static de.robv.android.xposed.XposedHelpers.findClass;





public class HookSport implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

        // filter
        if (!loadPackageParam.packageName.equals("com.tencent.mobileqq")) {
            return;
        }
//
//        XposedHelpers.findAndHookMethod("com.tencent.qphone.base.util.QLog",loadPackageParam.classLoader, "setManualLogLevel",int.class,new XC_MethodHook(){
//            //进行hook操作
//            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//                param.setResult(true);
//                log("hook setManualLogLevel ok");
//
//            };
//
//        });



        XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                ClassLoader cl = ((Context)param.args[0]).getClassLoader();
                Class<?> hookclass = null;
                try {
                    hookclass = cl.loadClass("com.tencent.qphone.base.util.CodecWarpper");
                    log("hook CodecWarpper ok");
                } catch (Exception e) {
                    return;
                }

//                XposedHelpers.findAndHookMethod(hookclass, "nativeOnReceData",byte[].class,new XC_MethodHook(){
//                    //进行hook操作
//                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//                        //param.setResult(true);
//                        log("hook nativeEncodeRequest ok");
//
//                    };
//
//                });


                XposedHelpers.findAndHookMethod(hookclass, "nativeEncodeRequest",int.class,String.class,String.class,String.class,String.class,String.class,byte[].class,int.class,int.class,String.class,byte.class,byte.class,byte[].class,byte[].class,boolean.class,new XC_MethodHook(){
                    //进行hook操作
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        //param.setResult(true);
                        log("hook nativeEncodeRequest 1ok???");
                        //log("1" + param.args[2].toString());

                    };

                });

                XposedHelpers.findAndHookMethod(hookclass, "nativeEncodeRequest",int.class,String.class,String.class,String.class,String.class,String.class,byte[].class,int.class,int.class,String.class,byte.class,byte.class,byte.class,byte[].class,byte[].class,boolean.class,new XC_MethodHook(){
                    //进行hook操作
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        //param.setResult(true);
                        log("hook nativeEncodeRequest 2ok???");
                        //log("param count = " + param.)
                        log("param1 = " + param.args[0].getClass() + " data =  " + param.args[0].toString());
                        log("param2 = " + param.args[1].getClass() + " data =  " + param.args[1].toString());
                        log("param3 = " + param.args[2].getClass() + " data =  " + param.args[2].toString());
                        log("param4 = " + param.args[3].getClass() + " data =  " + param.args[3].toString());
                        log("param5 = " + param.args[4].getClass() + " data =  " + param.args[4].toString());
                        log("param6 before = " + param.args[5].getClass() + " data =  " + param.args[5].toString());
                        //String param6 = ByteArrayToHexString(objectToByteArray(param.args[5]));
                        //log("param6 = " + param6);
                        try {
                            log("param7 before = " + param.args[6].getClass() + " data =  " + param.args[6].toString());
                        } catch (Exception e) {
                            log("param7 be error : " + e.toString());
                            return;
                        }
                        try {
                            log("param7 now= " + Arrays.toString(objectToByteArray(param.args[6])));
                            String param7 = ByteArrayToHexString(objectToByteArray(param.args[6]));
                            log("param7 = " + param7);
                        } catch (Exception e) {
                            log("param7 error : " + e.toString());
                            return;
                        }

                        log("param8 = " + param.args[7].getClass() + " data =  " + param.args[7].toString());
                        log("param9 = " + param.args[8].getClass() + " data =  " + param.args[8].toString());
                        log("param10 = " + param.args[9].getClass() + " data =  " + param.args[9].toString());
                        log("param11 = " + param.args[10].getClass() + " data =  " + param.args[10].toString());
                        log("param12 = " + param.args[11].getClass() + " data =  " + param.args[11].toString());
                        log("param13 = " + param.args[12].getClass() + " data =  " + param.args[12].toString());
                        //String param13 = ByteArrayToHexString(objectToByteArray(param.args[12]));
                        //log("param13 = " + param13);

//                        try {
//                            log("param14 before = " + param.args[13].getClass());
//                            log(" data =  " + param.args[13].toString());
//                        } catch (Exception e) {
//                            log("param14 be error : " + e.toString());
//                            return;
//                        }
//                        try {
//                            String param14 = Arrays.toString(objectToByteArray(param.args[13]));
//                            log("param14 = " + param14);
//                        } catch (Exception e) {
//                            log("param14 error : " + e.toString());
//                            return;
//                        }

                        try {
                            log("param15 type = " + param.args[14].getClass());
                            log("param15 before = " + Arrays.toString(objectToByteArray(param.args[14])));
                            log( " data =  " + param.args[14].toString());
                        } catch (Exception e) {
                            log("param15 be error : " + e.toString());
                            return;
                        }
                        try {
                            String param15 = Arrays.toString(objectToByteArray(param.args[14]));
                            log("param15 = " + param15);
                        } catch (Exception e) {
                            log("param15 error : " + e.toString());
                            return;
                        }


                        try {
                            log("param14 before = " + param.args[13]);
                            log(param.args[13].toString());
                            log(" data =  " + param.args[13].toString());
                        } catch (Exception e) {
                            log("param14 be error : " + e.toString());
                            return;
                        }
                        try {
                            String param14 = Arrays.toString(objectToByteArray(param.args[13]));
                            log("param14 = " + param14);
                        } catch (Exception e) {
                            log("param14 error : " + e.toString());
                            return;
                        }
                    };

                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        //param.setResult(true);
                        log("hook nativeEncodeRequest afterok???");

                        String res = ByteArrayToHexString(objectToByteArray(param.getResult()));
                        log("return now is : " + param.getResult().getClass() + Arrays.toString(objectToByteArray(param.getResult())));

                        log("return is : " + res);

                    };

                });

                XposedHelpers.findAndHookMethod(hookclass, "nativeEncodeRequest",int.class,String.class,String.class,String.class,String.class,String.class,byte[].class,int.class,int.class,String.class,byte.class,byte.class,byte[].class,boolean.class,new XC_MethodHook(){
                    //进行hook操作
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        //param.setResult(true);
                        log("hook nativeEncodeRequest 3ok???");
                        //log("1" + param.args[2].toString());

                    };

                });


            }
        });

    }

    private static String ByteArrayToHexString(byte[] bytes) {
        final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for ( int j = 0; j < bytes.length; j++ ) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static byte[] objectToByteArray(Object obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(obj);
        return byteArrayOutputStream.toByteArray();
    }


}

这个输出byte[]的方式,因为没学过java。。都是百度的,后面有时间还是要多补补基础知识呀。。关于byte[]打印有想法的欢迎留言呀。

发布了40 篇原创文章 · 获赞 22 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/liutianheng654/article/details/86640533