日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何做到微信机器人不封号_利用 Xposed 快速实现一个简易微信机器人

發(fā)布時間:2023/12/14 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何做到微信机器人不封号_利用 Xposed 快速实现一个简易微信机器人 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文同步至:github

目標(biāo)

當(dāng)前微信網(wǎng)頁版限制越來越多,考慮嘗試在手機(jī)上實(shí)現(xiàn)類似機(jī)器人的功能。本文目的是利用 Xposed 快速實(shí)現(xiàn)簡易機(jī)器人功能,包括獲取好友發(fā)來的消息,以及回復(fù)消息。后續(xù)可以增加智能回復(fù),比如接入圖靈機(jī)器人,或者自己自定義實(shí)現(xiàn)一些功能。

快速實(shí)現(xiàn)

項(xiàng)目框架的搭建

WechatSpellbook - 站在"巨人"的肩膀上

WechatSpellbook 是微信巫師作者在微信巫師的基礎(chǔ)提取出來的通用微信 Xposed 插件框架。它提供了友好的的 API,提供自動分析微信內(nèi)部結(jié)構(gòu)特征的API(忽略微信版本差異),對 hook 微信出現(xiàn)的常見問題都做了優(yōu)化,總之就是使用它會更容易對微信 hook,感謝作者的貢獻(xiàn),項(xiàng)目的集成和詳細(xì)介紹參見wiki,以下步驟的實(shí)現(xiàn)都是基于這個框架的。

以下源碼均基于微信 6.6.6 版本,由于使用了 WechatSpellbook 框架動態(tài)匹配的原理,大部分微信版本均可自動適配。

獲得好友發(fā)來的消息

實(shí)現(xiàn)機(jī)器人功能的首要步驟就是獲得好友發(fā)來的消息,獲得消息之后才能回復(fù)吧,才能叫“機(jī)器人”吧。

使用了 WechatSpellbook,獲取消息是很容易的,參見api,當(dāng)新消息存入數(shù)據(jù)庫后回調(diào),具體代碼:

object WechatMessageHook : IMessageStorageHook {

override fun onMessageStorageInserted(msgId: Long, msgObject: Any) {

XposedBridge.log("onMessageStorageInserted msgId=$msgId,msgObject=$msgObject")

// 這些都是消息的屬性,內(nèi)容,發(fā)送人,類型等

val field_content = XposedHelpers.getObjectField(msgObject, "field_content") as String?

val field_talker = XposedHelpers.getObjectField(msgObject, "field_talker") as String?

val field_type = (XposedHelpers.getObjectField(msgObject, "field_type") as Int).toInt()

val field_isSend = (XposedHelpers.getObjectField(msgObject, "field_isSend") as Int).toInt()

XposedBridge.log("field_content=$field_content,field_talker=$field_talker," +

"field_type=$field_type,field_isSend=$field_isSend")

if (field_isSend == 1) {// 代表自己發(fā)出的,不處理

return

}

// 做其他事情

}

}

其中字段名含義如下:

field_content: 消息內(nèi)容

field_talker: 發(fā)送者

field_type: 消息類型

field_isSend: 是誰發(fā)出的,我自己發(fā)出為1

這步到此就完成了,下一步是機(jī)器人怎么將消息回復(fù)給好友。

機(jī)器人回復(fù)消息

機(jī)器人回復(fù)消息需要找到發(fā)送消息出去這個 API,然后 hook 它,在我們的代碼里調(diào)用就行了。

利用 Monitor 的 Method Profiling 功能分析

首先在模擬器中打開微信聊天窗口,打開 Monitor,選中微信進(jìn)程,點(diǎn)擊Start Method Profiling,然后在聊天窗口隨便發(fā)送一條消息,然后回來點(diǎn)擊Stop Method Profiling,會生成分析文件。分析步驟如下:

先搜索 click,點(diǎn)擊發(fā)送按鈕,肯定是觸發(fā)了點(diǎn)擊事件的嘛,先找找看

發(fā)現(xiàn)調(diào)用了 ChatFooter$3.onClick() 方法,單從名字上來看,應(yīng)該就是這里了,點(diǎn)進(jìn)去,看這個函數(shù)調(diào)用了哪里

它調(diào)用了 chatting.o.FZ 方法,注意參數(shù)是 String,返回值是 Boolean,大膽猜測一下,這個字符串就是消息文本,返回值應(yīng)該是發(fā)送是否成功。驗(yàn)證一下,直接 Hook 這個函數(shù),運(yùn)行發(fā)現(xiàn)猜測是真的,這里比較簡單就不貼代碼了。

分析到這里,已經(jīng)知道了chatting.o.FZ 方法就是發(fā)送消息的,參數(shù)就是消息文本,但是有個很重要的地方忽略了,為什么沒有接收者參數(shù)?,微信內(nèi)部聯(lián)系人 ID 一般是以 wx_idxxx 開頭的,接收者 id 設(shè)置在哪,怎么設(shè)置 hook,現(xiàn)在就差這個問題了。

到這里已經(jīng)知道了發(fā)送消息的 API,hook 掉就可以搞事情了,但是缺少接收者這個重要參數(shù)的設(shè)置,分析下源碼吧。

反編譯查看源碼分析

反編譯之后分析 chatting.o.FZ 方法源碼:

public final boolean FZ(String str) {

mS(false);

ctQ();

return this.yOg.yRO.dt(str, 0);

}

然后分析yOg.yRO.dt方法,它是com.tencent.mm.ui.chatting.b類的方法,看下源碼:

public final boolean dt(String str, int i) {

int i2 = 0;

String Xf = bh.Xf(str);

if (Xf == null || Xf.length() == 0) {

w.e("MicroMsg.ChattingUI.TextImp", "doSendMessage null");

return false;

}

x xVar = this.yXC;

if (!ah.oB(Xf)) {

az azVar = new az();

azVar.setContent(Xf);

azVar.eW(1);

xVar.aB(azVar);

}

bt btVar = new bt();

// 省略

}

可以看到在azVar.setContent(Xf);這里將發(fā)送的消息文本放在放在了az這個類中,setContent() 是 az 的父類com.tencent.mm.g.c.cg的方法,看下這個類的源碼:

// 截取了幾個方法

public final void av(long j) {

this.field_createTime = j;

this.eRw = true;

}

public final long wQ() {

return this.field_createTime;

}

public final void ed(String str) {

this.field_talker = str;

this.feh = true;

}

public final String wR() {

return this.field_talker;

}

public final void setContent(String str) {

this.field_content = str;

this.eRE = true;

}

只截取了幾個方法,可以看到這個類不僅僅包含消息文本,還包含了接受者field_talker,發(fā)送時間field_createTime等,大膽猜想,這個類就是消息的包裝類,包含消息所有的屬性,這里關(guān)注的字段是接收者 field_talker,只要知道在哪里調(diào)用了ed方法 hook 掉就可以為所欲為了。

但是,通過 AS 查找調(diào)用這個的地方有很多,根本無法判斷具體發(fā)消息是哪里調(diào)用了,怎么辦。

借助 Xposed 分析com.tencent.mm.g.c.cg.ed()方法,也就是設(shè)置接收者 field_talker 的方法,只要 hook 這個方法,然后打印出調(diào)用堆棧看看到底是哪里回調(diào)了。

val clz = XposedHelpers.findClass("com.tencent.mm.g.c.cg", WechatGlobal.wxLoader)

XposedHelpers.findAndHookMethod(clz, "ed", String::class.java, object : XC_MethodHook() {

override fun beforeHookedMethod(param: MethodHookParam?) {

log("set field_talker start")

LogUtil.logStackTraces() // 打印調(diào)用堆棧

log("set field_talker end")

}

})

打印結(jié)果:

可以看到函數(shù)調(diào)用鏈,關(guān)鍵點(diǎn)在com.tencent.mm.modelmulti.i.,看下這個方法的源碼:

public i(String str, String str2, int i, int i2, Object obj) {

w.d("MicroMsg.NetSceneSendMsg", "dktext :%s", new Object[]{bh.cjG()});

if (!bh.oB(str)) {

cg azVar = new az();

azVar.eV(1);

azVar.ed(str);

azVar.av(bd.in(str));

azVar.eW(1);

azVar.setContent(str2);

azVar.setType(i);

String a = a(((o) g.l(o.class)).s(azVar), obj, i2);

if (!bh.oB(a)) {

azVar.ej(a);

w.d("MicroMsg.NetSceneSendMsg", "NetSceneSendMsg:MsgSource:%s", new Object[]{azVar.fnF});

// 省略很多代碼

}

可以看到這個類的構(gòu)造方法實(shí)例化了cg azVar = new az();,并調(diào)用了ed()方法。分析下這個構(gòu)造函數(shù),很有意思的是:參數(shù) str 就是微信 id,str2是文本內(nèi)容,后幾個不知道,大膽猜測下這個類就是去發(fā)送消息的,從源碼很難分析,hook 掉看看。

hook com.tencent.mm.modelmulti.i的構(gòu)造方法打印參數(shù),看下是否和發(fā)送消息有關(guān)。這里就不貼代碼和截圖了,結(jié)論是有關(guān)。那可以 hook 這個類的構(gòu)造方法發(fā)送消息啊。

找到的 hook 關(guān)鍵點(diǎn)

com.tencent.mm.ui.chatting.o.FZ(String) 方法,參數(shù)是消息文本,調(diào)用該方法可以發(fā)消息,但是無法設(shè)置接收者

com.tencent.mm.modelmulti.i()構(gòu)造方法,第0個參數(shù)是接收者 id,第1個參數(shù)是消息文本

機(jī)器人回復(fù)消息思路:調(diào)用第一個 API 發(fā)送消息文本,hook 第二個 API 修改接收者 id,然后就可以愉快的發(fā)消息了

關(guān)鍵點(diǎn)存在的問題

上述 hook 思路存在的問題:當(dāng) hook 第二個API 時,不知道該條消息的接收者是誰,不太好設(shè)置。

問題解決方法

既然我能 hook 這兩個 API,那么我可不可以直接在調(diào)用第一個 API 的時候,將接收者 id 放在文本消息前面,然后在 hook 第二個 API 時將文本消息中的接收者 id 解析出來賦值給第0個參數(shù)。

新消息文本 = 接收者ID + 分隔符號 + 真實(shí)消息文本

分割符號可以采用特殊字符,用戶不會輸入的字符,比如 \t 等

代碼實(shí)現(xiàn)

源碼在這里,關(guān)鍵地方都有注釋,有興趣可以 star

效果圖

總結(jié)

以上是生活随笔為你收集整理的如何做到微信机器人不封号_利用 Xposed 快速实现一个简易微信机器人的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。