首页
社区
课程
招聘
vx逆向分析随笔
发表于: 2021-8-20 16:27 26386

vx逆向分析随笔

2021-8-20 16:27
26386

图片太多了,就直接用的github博客的图片链接……

@app_version = 7.0.20

@app_date = 2020.11.19

本来是想分析vx8的,但是电脑性能不够……反编译工具直接卡死

当进行分析时,发现反复调用了ae.i,ae.d方法

image-20210814171654155

来到com.tencent.mm.sdk.platformtools.ae;查看

image-20210814171854620

同时找到了setConsoleLogOpen方法,猜测这是对控制台log全局控制的方法

image-20210814172452010

对该方法向上追溯,得到

其中设置log的是keep_setupXLog的p5参数

于是开启log只需要给p5赋值为true

frida脚本

使用DDMSStart Method Profiling功能,同时点击【发送】键

然后停止记录,搜索onClick关键字,定位到类com.tencent.mm.pluginsdk.ui.chat.ChatFooter$7

其中sstr为输入的字符串内容

image-20210815161220040

尝试hook ChatFooter.a方法

可以得到输出

使用DDMSDump View Hierarchy for UI Automator来定位控件ID

image-20210815003423908

查看顶层activity

再找控件ID,最终定位到com.tencent.mm.ui.chatting.view.MMChattingListView

image-20210815003515022

这是一个ListView

发现了List的Adapter

image-20210815004245534

交叉引用查看是哪里调用了这个方法

跟到com.tencent.mm.ui.chatting.ChattingUIFragmentfTJ方法

image-20210815004604975

发现这个Fragment对Adapter进行了设置,同时存放在了this.Lrn字段

其中this.Lrr类型为MMChattingListViewthis.Lro的类型为ListView

也可以得到Adapter的类型为com.tencent.mm.ui.chatting.a.a,同时继承了BaseAdapter

根据其重写的getCount方法,得到数据源是this.LtF字段

image-20210815010612094

this.LtF字段的定义是

使用frida hook一下,查看一下SparseArray每个元素的类型

随便hook了一个Fragment的zt方法(因为看Log日志每次操作都会执行)

获得Fragment的Lrn字段也就是Adapter

再直接调用getCount()getItem()获取到数据源的单个数据

此时手机界面为

img

获得输出为

可以知道每个数据的类型是com.tencent.mm.storage.bz

该类的继承关系为

查看个方法,发现里面有如下字段

image-20210815143427853

这些字段是ej类的

image-20210815144136894

同时bz还有5个子类

bz$a

image-20210815152148504

bz$b,大概是有关位置的

image-20210815152234412

bz$c

image-20210815152302867

bz$d,可以看到nickname, cityCode, CountryCode字段

image-20210815152614851

最终选择hook的是Adapter的notifyDataSetChanged方法,这样可以对最后的消息进行查看以及修改

修改一下消息内容

运行脚本之前的界面

img

可以得到以下输出

同时界面被修改为了

img

当然只能修改本地数据(虽然没什么卵用)

同时json输出该消息的数据结构为

其中接收到的消息比发送的消息要多了几个字段(普通文本消息)

因此可以分析到聊天窗口UI以及数据的类为

先用DDMS的记录功能找到点击事件为com.tencent.mm.emoji.panel.a.q$1.onClick()

image-20210816123125656

随后进入了glG.a方法,也就是com.tencent.mm.emoji.panel.a.d.a()方法

image-20210816123331547

frida调试arg14.type一直等于0

刚开始没咋看代码,然后去了v0_2.A(v6)方法,然后找了三四层。:confused:后来发现里面的有的方法不止是投骰子的时候才被调用才发觉找错了。

然后frida查看了一下v1.getGroup(),发现我添加的自定义表情是81,而骰子和石头剪刀布都是18;同时EmojiGroupInfo.Qbd也为18

然后分析.getProvider().p(v1)方法,交叉引用有多个,分别是com.tencent.mm.ca.a.p()com.tencent.mm.plugin.emoji.e.f.p()

frida打印调用信息发现com.tencent.mm.ca.a.p()先被调用

image-20210816124809022

frida调试发现进入了getEmojiMgr().p(arg9)方法,也就是com.tencent.mm.plugin.emoji.e.f.p()

image-20210816130822813

Cursor是数据库的游标,通过aec方法来查询相应内容

image-20210816132210776

然后v0.moveToPosition(v1)让游标v0移动到v1位置

arg6.convertFrom(v0)这个方法,位于EmojiInfo的父类com.tencent.mm.g.c.bj,查询该行相应的值然后给字段赋值

image-20210816132511952

之后发送的emoji表情就是这个arg6

所以看int v1 = bu.jE(v0.getCount() - 1, 0);

frida得到,石头剪刀布getCount()为3;而投骰子getCount()为6

查看com.tencent.mm.sdk.platformtools.bu.jE()方法

image-20210816132833909

public int nextInt(int n)

该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。

arg6是恒为0的。也就是说返回的v0是介于[0,arg5]的。

经Frida调试,骰子点数1-6对应着0-5;剪刀石头布分别对应着0 1 2

若想修改相应点数,直接hook该函数返回值就好

相应堆栈信息(不太懂为什么有的方法出现了两次,并且有个(Native Method)有大佬可以解释一下嘛:yum:)

防撤回难点是监听消息啥时候发送过来,真没啥思路。刚开始从聊天页面的ListView的notifyDataSetChanged开始回溯,回溯了好久找不到。

就搜索Log日志revoke

image-20210816160615130

然后去类中搜索字符串定位到com.tencent.mm.plugin.msgquote.PluginMsgQuote.handleRevokeMsgBySvrId

打印一下堆栈信息

之后写出如下frida脚本

对方发送一条消息

对方撤回该消息

发现是从processAddMsg()方法开始不一样的,也就是最先在这里判断是否为撤回消息的

而判断是否进入第五层的消息是靠v2!=null来判断的,而v2来自v3.vkP,v3来自参数一arg10.gpg

image-20210816201709925

经调试,普通文本消息的v3.vkP1,而撤回消息的v3.vkP10002

image-20210816210123382

而这恰好有个10002,不过并没有详细分析这里

进入调用的b(arg10)方法,也就是com.tencent.mm.s.b.b()没发现啥东西

image-20210816210228078

因为正常消息不会执行这个方法,当直接将该方法替换为空的时候,已经可以实现防撤回:joy:暴力yyds,但是没有撤回提示,还得继续分析

Image-20210816211759

直接进入下一层com.tencent.mm.model.ch.b方法,在一开始又对.vkP做了一次判断

image-20210816210702683

至于10001暂不知作用。对于10001只有那一点处理,之后就return null了;而default分支最后也是return null,可以得知.vkp的含义是msgType

可以知道这一个函数都是对撤回消息也就是msgType==10002进行处理的

然后该方法下面都是对v5的判断逻辑,而v5=v0.GYI.IYz

v0.GYIjson化输出,得到

而v5也就是

尝试一下修改信息

虽然消息还是被撤回了,但也说明这种修改提示信息的方式是可行的

img

通过hooknotifyDataSetChanged,json打印最后一条消息发现

撤回消息与撤回提示,仅有field_content"(文本内容)、"field_type""exe"字段不一样

其中正常消息的field_type=1,exe=true;撤回提示field_type=10000,exe=false

被撤回消息和撤回消息的提示的field_msgSvrId字段是一样的,同时对应着撤回提示xml的<newmsgid>字段

尝试修改撤回提示的<newmsgid>字段,发现没有什么用。直接就变成不撤回了。

大概是对xml进行分析处理的一些东西

image-20210816235316259

之后就去了com.tencent.mm.model.f.a()方法

参数一为字符串String,获取过程为上图中蓝框

参数二是一个XML内容转成的Map数组

参数三保存着原始的所有数据

这个方法里面是分块对参数一也就是.sysmsg.$type的值进行判断

image-20210817135838492

之后发现将.a()方法置为空则消息不会撤回,继续跟入

image-20210817140049459

在里面发现了数据库操作方法update

image-20210817140125502

之后嵌套了三个update,最后来到了updateWithOnConflict方法

image-20210817142313024

附上堆栈信息

经过一系列分析之后……(其实上面肯定都有分析的,只不过是很杂乱无从记录,这块就简写了

自己撤回消息提示的msgType=10002,别人撤回消息提示的msgType=10000

updateWithOnConflict()方法将参数进行sql的拼接,然后使用new SQLiteStatement()创建SQLiteStatement对象,再用executeUpdateDelete()来执行

Frida hook一下executeUpdateDelete()方法

当消息被撤回时,得到了以下输出

而我的目的主要是想 有撤回消息提示,同时不撤回消息

其中的参数msgId是本地的消息id,只有第一条数据库操作指令是WHERE msgId=?

所以实际上将被撤回消息 替换成撤回提示的就是这一条。

当然 已经找到数据库操作了。。剩下的就想怎么操作就怎么操作了

我想的是 将该条撤回提示直接INSERT进去,不知道msgId会不会重复,重复的话可以挨个调整?(不知道为啥无法使用select count(*)

或者让提示在指定位置的就是让他被撤回,然后聊天内容添加到撤回提示后边。原聊天内容可以通过select content from message where msgId = ?查询,缺点是只能文字内容;弥补的话只能判断非文本内容不让他撤回了

是想用frida来写的,毕竟frida比较方便。但是构造不出方法参数Object []来。

这两种都尝试了,但都会报错

image-20210817185555176

mark一下,有知道的大佬麻烦分享一下呀。

这里只用xposed实现了,文本被撤回,但是有撤回提示;图片等等直接暴力不执行方法了...因为撤回提示无法解释图片啥的

效果图

image-20210817235450332

其实也想将被撤回消息下面的每条消息都msgId+1然后将撤回消息insert进去。但是select count(*)不能使用,这块知识掌握也不太熟练,就没实现……

自动抢红包肯定是先要监听到消息

之前已经分析到数据库,接收到消息肯定要插入或者更新数据库,于是hook了com.tencent.wcdb.database.SQLiteDatabase.insertWithOnConflictupdateWithOnConflict方法。观察接收消息时候的参数

当接收红包的时候,insertWithOnConflict被触发了4次,分别对WalletLuckyMoney,LuckyMoneyDetailOpenRecord,message,AppMessage数据库进行了插入

其中对message数据库操作参数字段

updateWithOnConflict则被触发了三次,都是对rconversation数据库进行的操作

同时发现,普通消息在插入的时候,插入到message数据库的"type":1;图片"type":3;语音"type:34";撤回消息上面说过了,为"type":10000(“你领取了xxx的红包”也是这种形式);红包"type":436207665;转账"type":419430449

同时发现了语音文件是藏在/storage/emulated/0/Android/data/com.tencent.mm/MicroMsg/####/voice2/##/##/msg_###.amr下,不知道为啥打不开

打开红包的时候,聊天界面也就是message数据库插入了一条消息"领取了xxx的红包"同时向WalletLuckyMoney数据库插入了两条消息

其中一条消息有"receiveTime": ,"hbType":0,"receiveAmount":1,"receiveStatus":2,"hbStatus":4,"mNativeUrl":等参数,而且如果点开了红包没有点击【开】按钮选择关闭的话,仍会插入上述参数,只是"receiveTime":0,"hbType":0,"receiveAmount":0,"receiveStatus":0,"hbStatus":2,"mNativeUrl":

还是先DDMS寻找按钮点击事件,发现在聊天页面点击红包消息触发的方法为com.tencent.mm.ui.chatting.t$e.onClick()

最后在onDone方法里调用了startActivity

image-20210818172734198

堆栈信息为

其中com.tencent.mm.ui.chatting.viewitems.g$b.c中的判断,这个url是收到红包时插入WalletLuckyMoney数据库中的那条

image-20210818221446826

com.tencent.mm.br.d.b(android.content.Context, java.lang.String, java.lang.String, android.content.Intent) : void截取一下intent的参数

而红包界面的【开】按钮是在LuckyMoneyNotHookReceiveUI$10.onClick()这里触发的

image-20210818214917150

然后进入了auQ()方法

监听红包消息,然后让软件执行这些流程。我分析了一些,没有找到最直接的控制红包入账的方法(:joy:分析躁了,开学补考得开始复习了)

这里参考了skyun1314/WeChat-plug-in (github.com)

监听insertWithOnConflict方法,当接收到红包消息的时候,先使用com.tencent.mm.br.d.b(android.content.Context, java.lang.String, java.lang.String, android.content.Intent) : void这个静态方法初始化LuckyMoneyNotHookReceiveUI,然后监听onCreate()方法,来执行this.wrX按钮的点击事件。

这样实现的缺点是会弹窗……,如果想实现不弹窗,估计要继续追着【开】按钮onClick方法进去找最主要的那个方法了:astonished::sleepy:

auto_luckymoney

输出

微信Log日志分析——初步探索 (toutiao.com)

简单分析骰子流程 - 『移动安全区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

某聊天软件撤回流程的分析与防撤回实现 - 『移动安全区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

[原创]Xposed第二课(微信篇) 聊天界面修改文字-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com

[原创]Xposed第三课(微信篇) 防止好友消息撤回-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com

[下载]微信6.6.1 Xposed模块 包含 主动发消息 防撤回 抢红包 骰子作弊 模拟位置 步数最高-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com

深表谢意

代码啥的格式有些乱,太多了也不好改,麻烦大家手动格式化下。或者移步我的个人博客vx逆向分析随笔 | Forgo7ten'blog见谅啦

 
 
 
 
 
 
 
 
com.tencent.mm.sdk.platformtools.ae$a;setConsoleLogOpen
com.tencent.mm.sdk.platformtools.ae;setConsoleLogOpen
com.tencent.mm.xlog.app.XLogSetup;keep_setupXLog
com.tencent.mm.xlog.app.XLogSetup;realSetupXlog
com.tencent.mm.plugin.account.ui.SimpleLoginUI;onCreate/com.tencent.mm.ui.LauncherUI;onResume
com.tencent.mm.sdk.platformtools.ae$a;setConsoleLogOpen
com.tencent.mm.sdk.platformtools.ae;setConsoleLogOpen
com.tencent.mm.xlog.app.XLogSetup;keep_setupXLog
com.tencent.mm.xlog.app.XLogSetup;realSetupXlog
com.tencent.mm.plugin.account.ui.SimpleLoginUI;onCreate/com.tencent.mm.ui.LauncherUI;onResume
public static void keep_setupXLog(boolean p0,String p1,String p2,Integer p3,Boolean p4,Boolean p5,String p6){
   // ...
   XLogSetup.cachePath = p1;    // 缓存目录:/data/user/0/com.tencent.mm/files/xlog
   XLogSetup.logPath = p2;      // log目录:/storage/emulated/0/Android/data/com.tencent.mm/MicroMsg/xlog
   XLogSetup.toolsLevel = p3;   // 工具版本:null
   XLogSetup.appendIsSync = p4;
   XLogSetup.isLogcatOpen = p5; // 是否开启日志:false
   XLogSetup.nameprefix = p6;   // 前缀:MM
   if (!p0) {  
      // ...
   }else if(XLogSetup.setup){      
      // ...
   }else
      // ...
      ae.setConsoleLogOpen(XLogSetup.isLogcatOpen.booleanValue());
      // ...
   }
   return;
}
public static void keep_setupXLog(boolean p0,String p1,String p2,Integer p3,Boolean p4,Boolean p5,String p6){
   // ...
   XLogSetup.cachePath = p1;    // 缓存目录:/data/user/0/com.tencent.mm/files/xlog
   XLogSetup.logPath = p2;      // log目录:/storage/emulated/0/Android/data/com.tencent.mm/MicroMsg/xlog
   XLogSetup.toolsLevel = p3;   // 工具版本:null
   XLogSetup.appendIsSync = p4;
   XLogSetup.isLogcatOpen = p5; // 是否开启日志:false
   XLogSetup.nameprefix = p6;   // 前缀:MM
   if (!p0) {  
      // ...
   }else if(XLogSetup.setup){      
      // ...
   }else
      // ...
      ae.setConsoleLogOpen(XLogSetup.isLogcatOpen.booleanValue());
      // ...
   }
   return;
}
 
Java.perform(function() {
    /*
    * 开启vx全局日志
    */
    var clazz = Java.use('com.tencent.mm.xlog.app.XLogSetup');
    clazz.keep_setupXLog.overload('boolean', 'java.lang.String', 'java.lang.String', 'java.lang.Integer', 'java.lang.Boolean', 'java.lang.Boolean', 'java.lang.String').implementation = function(p0,p1,p2,p3,p4,p5,p6) {
 
        //console.log("arguments",arguments[5]);
        arguments[5] = Java.use("java.lang.Boolean").TRUE.value;
        console.log("已开启vx Log打印");
        return clazz.keep_setupXLog.apply(this, arguments);
    }
});
Java.perform(function() {
    /*
    * 开启vx全局日志
    */
    var clazz = Java.use('com.tencent.mm.xlog.app.XLogSetup');
    clazz.keep_setupXLog.overload('boolean', 'java.lang.String', 'java.lang.String', 'java.lang.Integer', 'java.lang.Boolean', 'java.lang.Boolean', 'java.lang.String').implementation = function(p0,p1,p2,p3,p4,p5,p6) {
 
        //console.log("arguments",arguments[5]);
        arguments[5] = Java.use("java.lang.Boolean").TRUE.value;
        console.log("已开启vx Log打印");
        return clazz.keep_setupXLog.apply(this, arguments);
    }
});
 
 
 
 
Java.perform(function() {
    var clazz = Java.use('com.tencent.mm.pluginsdk.ui.chat.ChatFooter');
    clazz.a.overload('com.tencent.mm.pluginsdk.ui.chat.ChatFooter', 'java.lang.String').implementation = function() {
        console.log("Send Message",arguments[1]);
        return clazz.a.apply(this, arguments);
    }
});
Java.perform(function() {
    var clazz = Java.use('com.tencent.mm.pluginsdk.ui.chat.ChatFooter');
    clazz.a.overload('com.tencent.mm.pluginsdk.ui.chat.ChatFooter', 'java.lang.String').implementation = function() {
        console.log("Send Message",arguments[1]);
        return clazz.a.apply(this, arguments);
    }
});
Send Message 1
Send Message 2
Send Message [微笑]
Send Message
Send Message 1
Send Message 2
Send Message [微笑]
Send Message
 
 
adb shell dumpsys activity top
adb shell dumpsys activity top
 
 
 
 
 
 
 
 
 
 
public SparseArray LtF;
public SparseArray LtF;
 
 
 
Java.perform(function() {
 
    var clazz = Java.use('com.tencent.mm.ui.chatting.ChattingUIFragment');
    clazz.zt.implementation = function() {
        console.log("this.Lrn.value",this.Lrn.value);
        var adapter = Java.cast(this.Lrn.value,Java.use("com.tencent.mm.ui.chatting.a.a"))
        console.log("adapter",adapter);
        console.log("adapter.getCount",adapter.getCount());
        console.log("LtF",adapter.LtF.value);
        var adapter_size = adapter.getCount();
        var msg = adapter.getItem(0);
        console.log("msg",msg);
        return clazz.zt.apply(this, arguments);
    }
});
Java.perform(function() {
 
    var clazz = Java.use('com.tencent.mm.ui.chatting.ChattingUIFragment');
    clazz.zt.implementation = function() {
        console.log("this.Lrn.value",this.Lrn.value);
        var adapter = Java.cast(this.Lrn.value,Java.use("com.tencent.mm.ui.chatting.a.a"))
        console.log("adapter",adapter);
        console.log("adapter.getCount",adapter.getCount());
        console.log("LtF",adapter.LtF.value);
        var adapter_size = adapter.getCount();
        var msg = adapter.getItem(0);
        console.log("msg",msg);
        return clazz.zt.apply(this, arguments);
    }
});
 
 
this.Lrn.value com.tencent.mm.ui.chatting.a.a@f945978
adapter com.tencent.mm.ui.chatting.a.a@f945978
adapter.getCount 5
LtF {0=com.tencent.mm.storage.bz@cc74ce8, 1=com.tencent.mm.storage.bz@dba9f01, 2=com.tencent.mm.storage.bz@ae31a6, 3=com.tencent.mm.storage.bz@9afe7e7, 4=com.tencent.mm.storage.bz@c384f94}
msg com.tencent.mm.storage.bz@cc74ce8
this.Lrn.value com.tencent.mm.ui.chatting.a.a@f945978
adapter com.tencent.mm.ui.chatting.a.a@f945978
adapter.getCount 5
LtF {0=com.tencent.mm.storage.bz@cc74ce8, 1=com.tencent.mm.storage.bz@dba9f01, 2=com.tencent.mm.storage.bz@ae31a6, 3=com.tencent.mm.storage.bz@9afe7e7, 4=com.tencent.mm.storage.bz@c384f94}
msg com.tencent.mm.storage.bz@cc74ce8
com.tencent.mm.storage.bz
com.tencent.mm.ah.aa
com.tencent.mm.g.c.ej
com.tencent.mm.sdk.e.c
com.tencent.mm.storage.bz
com.tencent.mm.ah.aa
com.tencent.mm.g.c.ej
com.tencent.mm.sdk.e.c
 
 
 
 
 
 
 
 
 
 
 
 
 
Java.perform(function() {
    var clazz = Java.use('com.tencent.mm.ui.chatting.a.a');
    clazz.notifyDataSetChanged.implementation = function() {
        console.log("notifyDataSetChanged");
        var data = this.LtF.value;
        var data_size = data.size();
        console.log("data_size",data_size);
        for(var i=0;i<data_size;++i){
            console.log("Message"+i,Java.cast(data.get(i),Java.use("com.tencent.mm.storage.bz")).field_content.value);
        }
        Java.cast(data.get(5),Java.use("com.tencent.mm.storage.bz")).field_content.value = Java.use("java.lang.String").$new("heheheheh");
         return clazz.notifyDataSetChanged.apply(this, arguments);
    }
});
Java.perform(function() {
    var clazz = Java.use('com.tencent.mm.ui.chatting.a.a');
    clazz.notifyDataSetChanged.implementation = function() {
        console.log("notifyDataSetChanged");
        var data = this.LtF.value;
        var data_size = data.size();
        console.log("data_size",data_size);
        for(var i=0;i<data_size;++i){
            console.log("Message"+i,Java.cast(data.get(i),Java.use("com.tencent.mm.storage.bz")).field_content.value);
        }
        Java.cast(data.get(5),Java.use("com.tencent.mm.storage.bz")).field_content.value = Java.use("java.lang.String").$new("heheheheh");
         return clazz.notifyDataSetChanged.apply(this, arguments);
    }
});
 
 
notifyDataSetChanged
data_size 7
Message0 1
Message1 2
Message2 3
Message3 4
Message4 5
Message5 哈哈哈哈哈哈哈哈哈哈哈哈
Message6 6
notifyDataSetChanged
data_size 7
Message0 1
Message1 2
Message2 3
Message3 4
Message4 5
Message5 哈哈哈哈哈哈哈哈哈哈哈哈
Message6 6
 
 
 
// com.tencent.mm.storage.bz
{
    "KzF": false,
    "KzG": false,
    "Zq": false,
    "__hadSetcreateTime": false,
    "__hadSettype": false,
    "dvP": "",
    "eBD": false,
    "eBO": false,
    "eBf": false,
    "eEH": 0,
    "eEI": "",
    "eEL": false,
    "eEM": false,
    "eEN": false,
    "eEO": false,
    "eEP": false,
    "eEQ": false,
    "eER": false,
    "eES": false,
    "eEf": false,
    "eEg": false,
    "eEh": false,
    "eEi": false,
    "eEj": false,
    "eEq": false,
    "ewj": true,
    "ewq": false,
    "exe": true,
    "fdE": false,
    "fdF": false,
    "fdI": "",
    "fdJ": 0,
    "fdK": 0,
    "fdL": 0,
    "fdM": 1,
    "fdN": 0,
    "fdO": 0,
    "fdP": "",
    "fdQ": "",
    "fdR": "",
    "fdS": 0,
    "fdT": [],
    "fdU": "",
    "fdV": "",
    "fdW": 0,
    "fdX": 0,
    "field_bizChatId": -1,
    "field_bizClientMsgId": "",
    "field_content": "",            // 聊天内容
    "field_createTime": 1629009756000,      // 聊天时间戳
    "field_flag": 0,
    "field_isSend": 0,
    "field_isShowTimer": 0,
    "field_lvbuffer": [0, 0, 125],
    "field_msgId": 00,                      // 消息id
    "field_msgSeq": 000000000,
    "field_msgSvrId": 4746617000000000000,
    "field_status": 0,
    "field_talker": "wxid_00000000000000"// 对话的微信用户ida
    "field_talkerId": 00,
    "field_type": 1,
    "systemRowid": -1
}
// com.tencent.mm.storage.bz
{
    "KzF": false,
    "KzG": false,
    "Zq": false,
    "__hadSetcreateTime": false,
    "__hadSettype": false,
    "dvP": "",
    "eBD": false,
    "eBO": false,
    "eBf": false,
    "eEH": 0,
    "eEI": "",
    "eEL": false,
    "eEM": false,
    "eEN": false,
    "eEO": false,
    "eEP": false,
    "eEQ": false,
    "eER": false,
    "eES": false,
    "eEf": false,
    "eEg": false,
    "eEh": false,
    "eEi": false,
    "eEj": false,
    "eEq": false,
    "ewj": true,
    "ewq": false,
    "exe": true,
    "fdE": false,
    "fdF": false,
    "fdI": "",
    "fdJ": 0,
    "fdK": 0,
    "fdL": 0,
    "fdM": 1,
    "fdN": 0,
    "fdO": 0,
    "fdP": "",
    "fdQ": "",
    "fdR": "",
    "fdS": 0,
    "fdT": [],
    "fdU": "",
    "fdV": "",
    "fdW": 0,
    "fdX": 0,
    "field_bizChatId": -1,
    "field_bizClientMsgId": "",
    "field_content": "",            // 聊天内容
    "field_createTime": 1629009756000,      // 聊天时间戳
    "field_flag": 0,
    "field_isSend": 0,
    "field_isShowTimer": 0,
    "field_lvbuffer": [0, 0, 125],
    "field_msgId": 00,                      // 消息id
    "field_msgSeq": 000000000,
    "field_msgSvrId": 4746617000000000000,
    "field_status": 0,
    "field_talker": "wxid_00000000000000"// 对话的微信用户ida
    "field_talkerId": 00,
    "field_type": 1,
    "systemRowid": -1
}
描述 类名
Fragment com.tencent.mm.ui.chatting.ChattingUIFragment
ListView com.tencent.mm.ui.chatting.view.MMChattingListView
Adapter com.tencent.mm.ui.chatting.a.a
单条消息类 com.tencent.mm.storage.bz
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
com.tencent.mm.sdk.platformtools.bu.jE(Native Method)
com.tencent.mm.plugin.emoji.e.f.p(SourceFile:91)
com.tencent.mm.plugin.emoji.e.f.p(Native Method)
com.tencent.mm.ca.a.p(SourceFile:240)
com.tencent.mm.ca.a.p(Native Method)
com.tencent.mm.emoji.panel.a.d.a(SourceFile:66)
com.tencent.mm.emoji.panel.a.d.a(Native Method)
com.tencent.mm.emoji.panel.a.q$1.onClick(SourceFile:41)
android.view.View.performClick(View.java:6294)
android.view.View$PerformClick.run(View.java:24770)
android.os.Handler.handleCallback(Handler.java:790)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:164)
android.app.ActivityThread.main(ActivityThread.java:6494)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
com.tencent.mm.sdk.platformtools.bu.jE(Native Method)
com.tencent.mm.plugin.emoji.e.f.p(SourceFile:91)
com.tencent.mm.plugin.emoji.e.f.p(Native Method)
com.tencent.mm.ca.a.p(SourceFile:240)
com.tencent.mm.ca.a.p(Native Method)
com.tencent.mm.emoji.panel.a.d.a(SourceFile:66)
com.tencent.mm.emoji.panel.a.d.a(Native Method)
com.tencent.mm.emoji.panel.a.q$1.onClick(SourceFile:41)
android.view.View.performClick(View.java:6294)
android.view.View$PerformClick.run(View.java:24770)
android.os.Handler.handleCallback(Handler.java:790)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:164)
android.app.ActivityThread.main(ActivityThread.java:6494)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Java.perform(function () {
 
    var clazz = Java.use('com.tencent.mm.sdk.platformtools.bu');
    clazz.jE.implementation = function () {
        for(var i=0;i<arguments.length;i++){
            console.log("bu.jE arguments"+i,arguments[i]);
        }
        var result = clazz.jE.apply(this, arguments);
        if(arguments[0]==2){
            console.log("石头剪刀布结果为:",result==0?"剪刀":result==1?"石头":"布");
        }else{
            console.log("骰子点数为:",result+1);
        }
        // 进行修改
        // result = Java.use("java.lang.Integer").parseInt("1");
        return result;
    }
});
Java.perform(function () {
 
    var clazz = Java.use('com.tencent.mm.sdk.platformtools.bu');
    clazz.jE.implementation = function () {
        for(var i=0;i<arguments.length;i++){
            console.log("bu.jE arguments"+i,arguments[i]);
        }
        var result = clazz.jE.apply(this, arguments);
        if(arguments[0]==2){
            console.log("石头剪刀布结果为:",result==0?"剪刀":result==1?"石头":"布");
        }else{
            console.log("骰子点数为:",result+1);
        }
        // 进行修改
        // result = Java.use("java.lang.Integer").parseInt("1");
        return result;
    }
});
 
 
 
 
com.tencent.mm.plugin.msgquote.PluginMsgQuote.handleRevokeMsgBySvrId(Native Method)
com.tencent.mm.model.f.a(SourceFile:2190)
com.tencent.mm.model.ch.b(SourceFile:258)
com.tencent.mm.s.b.b(SourceFile:40)
com.tencent.mm.plugin.messenger.foundation.c.processAddMsg(SourceFile:165)
com.tencent.mm.plugin.messenger.foundation.c.a(SourceFile:1059)
com.tencent.mm.plugin.messenger.foundation.f.a(SourceFile:118)
com.tencent.mm.plugin.zero.c.a(SourceFile:57)
com.tencent.mm.modelmulti.q$a$1.onTimerExpired(SourceFile:830)
com.tencent.mm.sdk.platformtools.aw.handleMessage(SourceFile:86)
com.tencent.mm.sdk.platformtools.aq$2.handleMessage(SourceFile:362)
android.os.Handler.dispatchMessage(Handler.java:106)
com.tencent.mm.sdk.platformtools.aq$2.dispatchMessage(SourceFile:350)
android.os.Looper.loop(Looper.java:164)
android.os.HandlerThread.run(HandlerThread.java:65)
com.tencent.mm.plugin.msgquote.PluginMsgQuote.handleRevokeMsgBySvrId(Native Method)
com.tencent.mm.model.f.a(SourceFile:2190)
com.tencent.mm.model.ch.b(SourceFile:258)
com.tencent.mm.s.b.b(SourceFile:40)
com.tencent.mm.plugin.messenger.foundation.c.processAddMsg(SourceFile:165)
com.tencent.mm.plugin.messenger.foundation.c.a(SourceFile:1059)
com.tencent.mm.plugin.messenger.foundation.f.a(SourceFile:118)
com.tencent.mm.plugin.zero.c.a(SourceFile:57)
com.tencent.mm.modelmulti.q$a$1.onTimerExpired(SourceFile:830)
com.tencent.mm.sdk.platformtools.aw.handleMessage(SourceFile:86)
com.tencent.mm.sdk.platformtools.aq$2.handleMessage(SourceFile:362)
android.os.Handler.dispatchMessage(Handler.java:106)
com.tencent.mm.sdk.platformtools.aq$2.dispatchMessage(SourceFile:350)
android.os.Looper.loop(Looper.java:164)
android.os.HandlerThread.run(HandlerThread.java:65)
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.msgquote.PluginMsgQuote');
    clazz.handleRevokeMsgBySvrId.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
        console.log("8 handleRevokeMsgBySvrId", log_str);
 
        return clazz.handleRevokeMsgBySvrId.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.model.f');
    clazz.a.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("7 f.a()", log_str);
 
        return clazz.a.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.model.ch');
    clazz.b.overload('com.tencent.mm.ak.e$a').implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("6 ch.b()", log_str);
 
        return clazz.b.overload('com.tencent.mm.ak.e$a').apply(this, arguments);
    }
});
 
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.s.b');
    clazz.b.overload('com.tencent.mm.ak.e$a').implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
        console.log("5 b.b()", log_str);
 
        return clazz.b.overload('com.tencent.mm.ak.e$a').apply(this, arguments);
    }
});
 
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.messenger.foundation.c');
    clazz.processAddMsg.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("4 c.processAddMsg()", log_str);
 
        return clazz.processAddMsg.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.messenger.foundation.c');
    clazz.a.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("3 c.a()", log_str);
 
        return clazz.a.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.messenger.foundation.f');
    clazz.a.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("2 f.a()", log_str);
 
        return clazz.a.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.zero.c');
    clazz.a.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("1 c.a()", log_str);
 
        return clazz.a.apply(this, arguments);
    }
});
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.msgquote.PluginMsgQuote');
    clazz.handleRevokeMsgBySvrId.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
        console.log("8 handleRevokeMsgBySvrId", log_str);
 
        return clazz.handleRevokeMsgBySvrId.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.model.f');
    clazz.a.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("7 f.a()", log_str);
 
        return clazz.a.apply(this, arguments);
    }
});
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.model.ch');
    clazz.b.overload('com.tencent.mm.ak.e$a').implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("6 ch.b()", log_str);
 
        return clazz.b.overload('com.tencent.mm.ak.e$a').apply(this, arguments);
    }
});
 
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.s.b');
    clazz.b.overload('com.tencent.mm.ak.e$a').implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
        console.log("5 b.b()", log_str);
 
        return clazz.b.overload('com.tencent.mm.ak.e$a').apply(this, arguments);
    }
});
 
 
Java.perform(function () {
    var clazz = Java.use('com.tencent.mm.plugin.messenger.foundation.c');
    clazz.processAddMsg.implementation = function () {
        var log_str = "arguments:"
        for (var i = 0; i < arguments.length; i++) {
            log_str += " [" + i + "]" + arguments[i]
        }
 
        console.log("4 c.processAddMsg()", log_str);
 
        return clazz.processAddMsg.apply(this, arguments);

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-8-20 18:33 被Forgo7ten编辑 ,原因: 修改好代码格式
收藏
免费 18
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  erfze   +1.00 2021/08/20
最新回复 (16)
雪    币: 1809
活跃值: (3252)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
2
可以一起学习交流呀呜呜呜,一个人闷头子搞太难了呜呜呜
2021-8-20 16:30
0
雪    币: 2380
活跃值: (573)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
卧槽,顶一波,热乎的
2021-8-20 17:07
0
雪    币: 2295
活跃值: (3000)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2021-8-20 17:22
0
雪    币: 6573
活跃值: (3873)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
5
代码排版再好一些就完美了
2021-8-20 17:31
0
雪    币: 1809
活跃值: (3252)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
6
代码本来是格式化的,,,但是复制上去就变乱了。。。主要是太多了
2021-8-20 18:16
0
雪    币: 1809
活跃值: (3252)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
7
LowRebSwrd 代码排版再好一些就完美了
已经重新排版,感谢版主大大提醒
2021-8-20 18:35
0
雪    币: 1483
活跃值: (534)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
感谢分享
2021-8-21 10:02
0
雪    币: 5182
活跃值: (2830)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好文收藏
2021-8-21 18:47
0
雪    币: 5235
活跃值: (3260)
能力值: ( LV10,RANK:175 )
在线值:
发帖
回帖
粉丝
10
帮顶  总结的很全
2021-8-21 20:39
0
雪    币: 235
活跃值: (303)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
牛啊,感谢分享
2021-8-23 15:00
0
雪    币: 486
活跃值: (583)
能力值: ( LV12,RANK:238 )
在线值:
发帖
回帖
粉丝
12
过年的时候再来看楼主。
2021-8-24 11:36
0
雪    币: 39
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
有没有获取微信图片的方法呢?从hook到的insert里面找到图片信息是cdnbigimgurl,而且是加密的
2021-10-12 18:37
0
雪    币: 755
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
NIXEVOL 有没有获取微信图片的方法呢?从hook到的insert里面找到图片信息是cdnbigimgurl,而且是加密的
这个是AES加密的 需要去CDN下载 你去抓个包看一下就知道了
2021-12-8 15:05
0
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
文章太长了。。估计没人能完整读完
2021-12-8 18:50
0
雪    币: 39
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
安小白MCY 这个是AES加密的 需要去CDN下载 你去抓个包看一下就知道了
能详细说说吗
2022-2-4 02:24
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
支持一下
2022-2-4 12:27
0
游客
登录 | 注册 方可回帖
返回
//