Skip to content

Commit

Permalink
support message tail
Browse files Browse the repository at this point in the history
  • Loading branch information
fuqiuluo committed Jul 21, 2024
1 parent d39eba2 commit 7e31a9a
Show file tree
Hide file tree
Showing 39 changed files with 3,190 additions and 26 deletions.
1 change: 1 addition & 0 deletions app/src/main/java/moe/qwq/miko/ActionManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ object ActionManager {
HotUpdateSoPatch::class.java,

RepeatMessage::class.java,
MessageHook::class.java,
DisableFlashPictures::class.java,
AllowGroupFlashPic::class.java
)
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/moe/qwq/miko/actions/WebJsBridge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ class WebJsBridge: AlwaysRunAction() {
).json.toString()
}

@JavascriptInterface
fun setSettingString(key: String, value: String) {
val setting = QwQSetting.getSetting<Any>(key)
setting.setValue(setting, null, value)
}

@JavascriptInterface
fun setSetting(key: String, value: Boolean) {
val setting = QwQSetting.getSetting<Any>(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@ import com.tencent.qqnt.kernel.api.impl.MsgService
import de.robv.android.xposed.XposedBridge
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.entries.InfoSyncPush
import moe.fuqiuluo.entries.MessagePush
import moe.qwq.miko.ext.hookMethod
import moe.qwq.miko.internals.AioListener
import moe.qwq.miko.internals.setting.QwQSetting

internal object NTServiceFetcher {
private lateinit var iKernelService: IKernelService
Expand Down Expand Up @@ -63,8 +60,6 @@ internal object NTServiceFetcher {
XposedBridge.log(it)
}
}

//msgService.addMsgListener(AioListener)
}

val kernelService: IKernelService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,14 @@ class DefaultPacketHijacker: IAction {
companion object {
private val TRASH_PACKET = setOf(
"AuthSvr.ThemeAuth", // 主题验证
"FeedCloudSvr.trpc.feedcloud.eeveeundealmsg.EeveeMsgChannel.FcUndealMsgs",
"trpc.qqva.uni_log_server.uni_log_server.Report",
"OidbSvc.0x5eb_ForTheme",
"QQClubComm.getNewFlag",
"LightAppSvc.mini_app_ad.GetAd",
"TianShu.GetAds", // noteworthy
"LightAppSvc.mini_app_info.GetAppInfoByLink",
"SQQzoneSvc.getActiveFeeds",
"trpc.qqshop.adpush.PushService.GetAd"
)
private val TEST_PACKET = setOf(
"SQQzoneSvc.getUndealCount",
"trpc.qq_new_tech.status_svc.StatusService.SsoHeartBeat",
"Heartbeat.Alive"
)
}

override val process: ActionProcess
Expand Down
123 changes: 123 additions & 0 deletions app/src/main/java/moe/qwq/miko/internals/hooks/MessageHook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package moe.qwq.miko.internals.hooks

import android.content.Context
import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.kernel.nativeinterface.TextElement
import com.tencent.qqnt.msg.api.IMsgService
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XposedBridge
import moe.fuqiuluo.processor.HookAction
import moe.qwq.miko.actions.ActionProcess
import moe.qwq.miko.actions.IAction
import moe.qwq.miko.internals.setting.QwQSetting

@HookAction("发送消息预劫持")
class MessageHook: IAction {
private fun handleMessageBody(msgs: ArrayList<MsgElement>) {
if (msgs.isActionMsg()) return
val tail by QwQSetting.getSetting<String>(name)
val encrypt by QwQSetting.getSetting<String>(QwQSetting.MESSAGE_ENCRYPT)
if (tail.isNotBlank()) {
handleMessageTail(msgs, tail)
}
if (encrypt.isNotBlank()) {
handleMessageEncrypt(msgs, encrypt)
}
}

private fun handleMessageTail(msgs: ArrayList<MsgElement>, tail: String) { // 给消息添加小尾巴
msgs.add(MsgElement().apply {
this.elementType = MsgConstant.KELEMTYPETEXT
this.textElement = TextElement()
this.textElement.content = tail
})
}

private fun handleMessageEncrypt(msgs: ArrayList<MsgElement>, encryptKey: String) {

}

override fun onRun(ctx: Context) {
/* val msgService = QRoute.api(IMsgService::class.java)
msgService.javaClass.methods.forEach {
if ((it.name == "sendMsg" || it.name == "sendMsgWithMsgId") && it.parameterTypes.size > 3) {
val isV1Hook = it.parameterTypes[1] == ArrayList::class.java
val isV2Hook = it.parameterTypes[2] == ArrayList::class.java
if (isV1Hook) {
XposedBridge.hookMethod(it, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
hookSendMsgV1(param)
}
})
} else if (isV2Hook) {
XposedBridge.hookMethod(it, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
hookSendMsgV2(param)
}
})
}
}
}*/
com.tencent.qqnt.kernel.api.impl.MsgService::class.java.methods.forEach {
if ((it.name == "sendMsg") && it.parameterTypes.size > 3) {
val isV1Hook = it.parameterTypes[1] == ArrayList::class.java
val isV2Hook = it.parameterTypes[2] == ArrayList::class.java
if (isV1Hook) {
XposedBridge.hookMethod(it, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
hookSendMsgV1(param)
}
})
} else if (isV2Hook) {
XposedBridge.hookMethod(it, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
hookSendMsgV2(param)
}
})
}
}
}
}

private fun hookSendMsgV1(params: XC_MethodHook.MethodHookParam) {
val msgs = params.args[1] as ArrayList<MsgElement>
handleMessageBody(msgs)
}

private fun hookSendMsgV2(params: XC_MethodHook.MethodHookParam) {
val msgs = params.args[2] as ArrayList<MsgElement>
handleMessageBody(msgs)
}

override fun canRun(): Boolean {
val tail by QwQSetting.getSetting<String>(name)
val encrypt by QwQSetting.getSetting<String>(QwQSetting.MESSAGE_ENCRYPT)
return tail.isNotEmpty() || encrypt.isNotEmpty()
}

override val name: String = QwQSetting.MESSAGE_TAIL

override val process: ActionProcess
get() = ActionProcess.MAIN
}


private fun ArrayList<MsgElement>.isActionMsg(): Boolean {
return any {
it.elementType == MsgConstant.KELEMTYPEACTIVITY ||
it.elementType == MsgConstant.KELEMTYPEFEED ||
it.elementType == MsgConstant.KELEMTYPEAVRECORD ||
it.elementType == MsgConstant.KELEMTYPECALENDAR ||
it.elementType == MsgConstant.KELEMTYPEGIPHY ||
it.elementType == MsgConstant.KELEMTYPEGRAYTIP ||
it.elementType == MsgConstant.KELEMTYPEINTEXTGIFT ||
it.elementType == MsgConstant.KELEMTYPELIVEGIFT ||
it.elementType == MsgConstant.KELEMTYPEYOLOGAMERESULT ||
it.elementType == MsgConstant.KELEMTYPEWALLET ||
it.elementType == MsgConstant.KELEMTYPEUNKNOWN ||
it.elementType == MsgConstant.KELEMTYPETOFU
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import mqq.app.MobileQQ
import kotlin.reflect.KProperty

object QwQSetting {
const val MESSAGE_ENCRYPT: String = "message_encrypt"
const val MESSAGE_TAIL: String = "message_tail"
const val INTERCEPT_RECALL = "intercept_recall"
const val ANTI_BROWSER_ACCESS_RESTRICTIONS = "anti_browser_access_restrictions"
const val SIMPLIFY_HOMEPAGE_SIDEBAR = "simplify_homepage_sidebar"
Expand Down Expand Up @@ -47,6 +49,8 @@ object QwQSetting {
OPTIMIZE_AT_SORT to Setting<Boolean>(OPTIMIZE_AT_SORT, SettingType.BOOLEAN),
DISABLE_FLASH_PICTURE to Setting<Boolean>(DISABLE_FLASH_PICTURE, SettingType.BOOLEAN),
ALLOW_GROUP_FLASH_PIC to Setting<Boolean>(ALLOW_GROUP_FLASH_PIC, SettingType.BOOLEAN),
MESSAGE_TAIL to Setting(MESSAGE_TAIL, SettingType.STRING, ""),
MESSAGE_ENCRYPT to Setting(MESSAGE_ENCRYPT, SettingType.STRING, ""), // 消息加密密钥
)

val settingUrl: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.tencent.qqnt.kernel.nativeinterface;

public final class AVRecordElement {
Integer extraType;
boolean hasRead;
int mainType;
String text;
long time;
int type;

public AVRecordElement() {
this.text = "";
}

public Integer getExtraType() {
return this.extraType;
}

public boolean getHasRead() {
return this.hasRead;
}

public int getMainType() {
return this.mainType;
}

public String getText() {
return this.text;
}

public long getTime() {
return this.time;
}

public int getType() {
return this.type;
}

public String toString() {
return "AVRecordElement{type=" + this.type + ",time=" + this.time + ",text=" + this.text + ",mainType=" + this.mainType + ",hasRead=" + this.hasRead + ",extraType=" + this.extraType + ",}";
}

public AVRecordElement(int i2, long j2, String str, int i3, boolean z, Integer num) {
this.text = "";
this.type = i2;
this.time = j2;
this.text = str;
this.mainType = i3;
this.hasRead = z;
this.extraType = num;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.tencent.qqnt.kernel.nativeinterface;

public final class ArkElement {
String bytesData;
LinkInfo linkInfo;
Integer subElementType;

public ArkElement() {
this.bytesData = "";
}

public String getBytesData() {
return this.bytesData;
}

public LinkInfo getLinkInfo() {
return this.linkInfo;
}

public Integer getSubElementType() {
return this.subElementType;
}

public String toString() {
return "ArkElement{bytesData=" + this.bytesData + ",linkInfo=" + this.linkInfo + ",subElementType=" + this.subElementType + ",}";
}

public ArkElement(String data, LinkInfo linkInfo, Integer num) {
this.bytesData = data;
this.linkInfo = linkInfo;
this.subElementType = num;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.tencent.qqnt.kernel.nativeinterface;

import java.io.Serializable;

public final class CalendarElement implements Serializable {
long expireTimeMs;

/* renamed from: msg reason: collision with root package name */
String msg;
String schema;
int schemaType;
long serialVersionUID;
String summary;

public CalendarElement() {
this.serialVersionUID = 1L;
this.summary = "";
this.msg = "";
this.schema = "";
}

public long getExpireTimeMs() {
return this.expireTimeMs;
}

public String getMsg() {
return this.msg;
}

public String getSchema() {
return this.schema;
}

public int getSchemaType() {
return this.schemaType;
}

public String getSummary() {
return this.summary;
}

public String toString() {
return "CalendarElement{summary=" + this.summary + ",msg=" + this.msg + ",expireTimeMs=" + this.expireTimeMs + ",schemaType=" + this.schemaType + ",schema=" + this.schema + ",}";
}

public CalendarElement(String str, String str2, long j2, int i2, String str3) {
this.serialVersionUID = 1L;
this.summary = str;
this.msg = str2;
this.expireTimeMs = j2;
this.schemaType = i2;
this.schema = str3;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.tencent.qqnt.kernel.nativeinterface;


public final class EmojiAD {
String desc;
String url;

public EmojiAD() {
this.url = "";
this.desc = "";
}

public String getDesc() {
return this.desc;
}

public String getUrl() {
return this.url;
}

public String toString() {
return "EmojiAD{url=" + this.url + ",desc=" + this.desc + ",}";
}

public EmojiAD(String str, String str2) {
this.url = "";
this.desc = "";
this.url = str;
this.desc = str2;
}
}
Loading

0 comments on commit 7e31a9a

Please sign in to comment.