2019年7月8日
xposed框架發(fā)消息實現(xiàn)關(guān)鍵代碼碎绎,實現(xiàn)步驟
版本:weixin705android1440
jadx打開微信
找到com.tencent.mm.ui.chatting.p.SE
找到對應(yīng)的函數(shù)實現(xiàn)
public final boolean SE(String str) {
AppMethodBeat.i(30659);
this.zcV.dJJ();
this.zcV.dGJ();
boolean atY
=((com.tencent.mm.ui.chatting.c.b.ad) this.zcV.ay(com.tencent.mm.ui.chatting.c.b.ad.class)).atY(str);
AppMethodBeat.o(30659);
return atY;
}
找到com.tencent.mm.ui.chatting.c.b.ad類
發(fā)現(xiàn)是一個接口
而jadx打開微信apk后很卡颗胡,沒辦法直接搜索
使用apktool反編譯微信
java -jar apktool.jar d weixin705android1440.apk
然后使用AndroidStudio導(dǎo)入反編譯后的文件夾
使用Ctrl + Shift + F 搜索atY
搜索結(jié)果發(fā)現(xiàn)com.tencent.mm.ui.chatting.c.ai類里面有一個atY的實現(xiàn),同時也是唯一一個實現(xiàn)
下一步查看eQ的實現(xiàn)
private boolean eQ(String str, final int i) {
int i2 = 0;
AppMethodBeat.i(31684);
final String aqk = bo.aqk(str);
if (aqk == null || aqk.length() == 0) {
ab.e("MicroMsg.ChattingUI.SendTextComponent", "doSendMessage null");
AppMethodBeat.o(31684);
return false;
}
this.zHU.atM(aqk);
b bzVar = new bz();
bzVar.cpw.cpy = aqk;
bzVar.cpw.context = this.caz.zJz.getContext();
bzVar.cpw.username = this.caz.getTalkerUserName();
com.tencent.mm.sdk.b.a.ymk.l(bzVar);
if (bzVar.cpx.cpz) {
AppMethodBeat.o(31684);
return true;
}
boolean z = WXHardCoderJNI.hcSendMsgEnable;
int i3 = WXHardCoderJNI.hcSendMsgDelay;
int i4 = WXHardCoderJNI.hcSendMsgCPU;
int i5 = WXHardCoderJNI.hcSendMsgIO;
if (WXHardCoderJNI.hcSendMsgThr) {
i2 = g.RO().dtc();
}
this.zHV = WXHardCoderJNI.startPerformance(z, i3, i4, i5, i2, WXHardCoderJNI.hcSendMsgTimeout, 202, WXHardCoderJNI.hcSendMsgAction, "MicroMsg.ChattingUI.SendTextComponent");
com.tencent.mm.ui.chatting.d.a.dJI().post(new Runnable() {
public final void run() {
AppMethodBeat.i(31681);
if (ai.this.caz == null) {
ab.w("MicroMsg.ChattingUI.SendTextComponent", "NULL == mChattingContext");
AppMethodBeat.o(31681);
return;
}
com.tencent.mm.plugin.report.service.g.Cx(20);
if (ai.a(ai.this)) {
ai.this.caz.dJD();
aw.Rc().a(new com.tencent.mm.ap.a(ai.this.caz.txj.field_username, aqk), 0);
AppMethodBeat.o(31681);
return;
}
if (((h) ai.this.caz.ay(h.class)).getCount() == 0 && com.tencent.mm.storage.ad.are(ai.this.caz.getTalkerUserName())) {
bv.abc().c(10076, Integer.valueOf(1));
}
String talkerUserName = ai.this.caz.getTalkerUserName();
int oF = t.oF(talkerUserName);
String str = aqk;
String str2 = null;
try {
str2 = ((com.tencent.mm.ui.chatting.c.b.t) ai.this.caz.ay(com.tencent.mm.ui.chatting.c.b.t.class)).atW(talkerUserName);
} catch (Throwable e) {
ab.printErrStackTrace("MicroMsg.ChattingUI.SendTextComponent", e, "", new Object[0]);
}
if (bo.isNullOrNil(str2)) {
ab.w("MicroMsg.ChattingUI.SendTextComponent", "tempUser is null");
AppMethodBeat.o(31681);
return;
}
String str3;
o oVar = (o) ai.this.caz.ay(o.class);
int lastIndexOf = str.lastIndexOf(8197);
if (lastIndexOf <= 0 || lastIndexOf != str.length() - 1) {
str3 = str;
} else {
str3 = str.substring(0, lastIndexOf);
ab.w("MicroMsg.ChattingUI.SendTextComponent", "delete @ last char! index:".concat(String.valueOf(lastIndexOf)));
}
ChatFooter dIg = oVar.dIg();
int i = i;
int i2 = dIg.vWk.vYg.containsKey(talkerUserName) ? ((LinkedList) dIg.vWk.vYg.get(talkerUserName)).size() > 0 ? 291 : i : i;
m hVar = new com.tencent.mm.modelmulti.h(str2, str3, oF, i2, oVar.dIg().hW(talkerUserName, str));
((com.tencent.mm.ui.chatting.c.b.t) ai.this.caz.ay(com.tencent.mm.ui.chatting.c.b.t.class)).g(hVar);
aw.Rc().a(hVar, 0);
if (t.oB(talkerUserName)) {
aw.Rc().a(new j(q.LO(), aqk + " key " + bs.dyO() + " local key " + bs.dyN() + "NetType:" + at.getNetTypeString(ai.this.caz.zJz.getContext().getApplicationContext()) + " hasNeon: " + n.Lu() + " isArmv6: " + n.Lw() + " isArmv7: " + n.Lv()), 0);
}
AppMethodBeat.o(31681);
}
});
this.caz.qT(true);
AppMethodBeat.o(31684);
return true;
}
參考鏈接:
https://bbs.pediy.com/thread-228441.htm
關(guān)鍵代碼為
m hVar = new com.tencent.mm.modelmulti.h(str2, str3, oF, i2, oVar.dIg().hW(talkerUserName, str));
aw.Rc().a(hVar, 0);
找到aw的類里的靜態(tài)方法
com.tencent.mm.model.aw
參考代碼:
*//構(gòu)造new里面的參數(shù):l iVar = new i(aao, str, hQ, i2, mVar.cvb().fD(talkerUserName, str));*
Class<?> classiVar = XposedHelpers.findClassIfExists(**"com.tencent.mm.modelmulti.i"**, loadPackageParam.**classLoader**);
Object objectiVar = XposedHelpers.newInstance(classiVar,
** new **Class[]{String.**class**, String.**class**, **int**.**class**, **int**.**class**, Object.**class**},
strChatroomId, strContent, 1, 1, **new **HashMap<String, String>() {{
put(strChatroomId, strChatroomId);
}});
Object[] objectParamiVar = **new **Object[]{objectiVar, 0};
*//創(chuàng)建靜態(tài)實例對象au.DF()栓霜,轉(zhuǎn)換為com.tencent.mm.ab.o對象*
Class<?> classG = XposedHelpers.findClassIfExists(**"com.tencent.mm.kernel.g"**, loadPackageParam.**classLoader**);
Object objectG = XposedHelpers.callStaticMethod(classG, **"Eh"**);
Object objectdpP = XposedHelpers.getObjectField(objectG, **"dpP"**);
*//查找au.DF().a()方法*
Class<?> classDF = XposedHelpers.findClassIfExists(**"com.tencent.mm.ab.o"**, loadPackageParam.**classLoader**);
Class<?> classI = XposedHelpers.findClassIfExists(**"com.tencent.mm.ab.l"**, loadPackageParam.**classLoader**);
Method methodA = XposedHelpers.findMethodExactIfExists(classDF, **"a"**, classI, **int**.**class**);
*//調(diào)用發(fā)消息方法*
**try **{
XposedBridge.*invokeOriginalMethod*(methodA, objectdpP, objectParamiVar);
XposedBridge.*log*(**"invokeOriginalMethod()執(zhí)行成功"**);
} **catch **(Exception e) {
XposedBridge.*log*(**"調(diào)用微信消息回復(fù)方法異常"**);
XposedBridge.*log*(e);
}
上面代碼是參考
https://blog.csdn.net/weixin_42127613/article/details/81841099
把里面的關(guān)鍵類和方法名更改,即可成功調(diào)用
com.tencent.mm.modelmulti.i->com.tencent.mm.modelmulti.h
com.tencent.mm.kernel.g ->com.tencent.mm.kernel.g
EH->RK
dpP -> eHt
com.tencent.mm.ab.o->com.tencent.mm.ai.p
com.tencent.mm.ab.l -> com.tencent.mm.ai.m