mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: fix #236
This commit is contained in:
parent
63ce2d40bd
commit
3b210d7ed0
@ -0,0 +1,29 @@
|
||||
package com.tencent.mobileqq.perf.block;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import epic.EIPCClient;
|
||||
import epic.EIPCResult;
|
||||
import kotlin.Metadata;
|
||||
import kotlin.jvm.JvmStatic;
|
||||
|
||||
public final class BinderMethodProxy {
|
||||
@NotNull
|
||||
public static final BinderMethodProxy INSTANCE;
|
||||
|
||||
static {
|
||||
INSTANCE = new BinderMethodProxy();
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public static EIPCResult callServer(@NotNull EIPCClient client, @Nullable String module, @Nullable String action, @Nullable Bundle bundle) {
|
||||
//MainBlockMethodMonitor.onMethodStart();
|
||||
//EIPCResult callServer = client.callServer(str, str2, bundle);
|
||||
//MainBlockMethodMonitor.onMethodEnd();
|
||||
//return callServer;
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.tencent.mobileqq.qipc;
|
||||
|
||||
import epic.EIPCClient;
|
||||
|
||||
public class QIPCClientHelper {
|
||||
public static synchronized QIPCClientHelper getInstance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public EIPCClient getClient() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.tencent.mobileqq.qmmkv;
|
||||
|
||||
public class MMKVOptionEntity {
|
||||
public String decodeString(String str, String str2) {
|
||||
return "";
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.tencent.mobileqq.qmmkv;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class QMMKV {
|
||||
public static MMKVOptionEntity from(Context context, String str) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.tencent.mobileqq.transfile.dns;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class IpData implements Parcelable {
|
||||
public int mFailedCount;
|
||||
public String mIp;
|
||||
public int mPort;
|
||||
public int mType;
|
||||
|
||||
/**
|
||||
* Describe the kinds of special objects contained in this Parcelable
|
||||
* instance's marshaled representation. For example, if the object will
|
||||
* include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},
|
||||
* the return value of this method must include the
|
||||
* {@link #CONTENTS_FILE_DESCRIPTOR} bit.
|
||||
*
|
||||
* @return a bitmask indicating the set of special object types marshaled
|
||||
* by this Parcelable object instance.
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten this object in to a Parcel.
|
||||
*
|
||||
* @param dest The Parcel in which the object should be written.
|
||||
* @param flags Additional flags about how the object should be written.
|
||||
* May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
|
||||
}
|
||||
}
|
4
qqinterface/src/main/java/epic/EIPCClient.java
Normal file
4
qqinterface/src/main/java/epic/EIPCClient.java
Normal file
@ -0,0 +1,4 @@
|
||||
package epic;
|
||||
|
||||
public class EIPCClient {
|
||||
}
|
11
qqinterface/src/main/java/epic/EIPCResult.java
Normal file
11
qqinterface/src/main/java/epic/EIPCResult.java
Normal file
@ -0,0 +1,11 @@
|
||||
package epic;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
public class EIPCResult {
|
||||
public Bundle data;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.msg.convert
|
||||
|
||||
import com.tencent.mobileqq.qmmkv.QMMKV
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||
@ -13,6 +14,8 @@ import moe.fuqiuluo.shamrock.helper.db.MessageDB
|
||||
import moe.fuqiuluo.shamrock.tools.asJsonObject
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import moe.fuqiuluo.shamrock.tools.json
|
||||
import mqq.app.MobileQQ
|
||||
import kotlin.jvm.internal.Intrinsics
|
||||
|
||||
internal sealed class MessageElemConverter: IMessageConvert {
|
||||
/**
|
||||
@ -135,14 +138,16 @@ internal sealed class MessageElemConverter: IMessageConvert {
|
||||
ImageMapping(md5.uppercase(), chatType, image.fileSize)
|
||||
)
|
||||
|
||||
//LogCenter.log(image.toString())
|
||||
|
||||
return MessageSegment(
|
||||
type = "image",
|
||||
data = hashMapOf(
|
||||
"file" to md5,
|
||||
"url" to when(chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(md5)
|
||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(md5)
|
||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(md5)
|
||||
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(image.originImageUrl, md5)
|
||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(image.originImageUrl, md5)
|
||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(image.originImageUrl, md5)
|
||||
else -> unknownChatType(chatType)
|
||||
},
|
||||
"subType" to image.picSubType,
|
||||
|
@ -1,9 +1,13 @@
|
||||
@file:OptIn(ExperimentalSerializationApi::class)
|
||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
||||
|
||||
import android.os.Bundle
|
||||
import com.tencent.mobileqq.pb.ByteStringMicro
|
||||
import com.tencent.mobileqq.perf.block.BinderMethodProxy
|
||||
import com.tencent.mobileqq.qipc.QIPCClientHelper
|
||||
import com.tencent.mobileqq.transfile.FileMsg
|
||||
import com.tencent.mobileqq.transfile.api.IProtoReqManager
|
||||
import com.tencent.mobileqq.transfile.dns.IpData
|
||||
import com.tencent.mobileqq.transfile.protohandler.RichProto
|
||||
import com.tencent.mobileqq.transfile.protohandler.RichProtoProc
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
@ -19,18 +23,35 @@ import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.tools.toHexString
|
||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
|
||||
import mqq.app.MobileQQ
|
||||
import protobuf.oidb.cmd0xfc2.Oidb0xfc2ChannelInfo
|
||||
import protobuf.oidb.cmd0xfc2.Oidb0xfc2MsgApplyDownloadReq
|
||||
import protobuf.oidb.cmd0xfc2.Oidb0xfc2ReqBody
|
||||
import protobuf.oidb.cmd0xfc2.Oidb0xfc2RspBody
|
||||
import mqq.app.MobileQQ
|
||||
import tencent.im.cs.cmd0x346.cmd0x346
|
||||
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
|
||||
import tencent.im.oidb.cmd0xe37.cmd0xe37
|
||||
import tencent.im.oidb.oidb_sso
|
||||
import java.util.ArrayList
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
private const val GPRO_PIC = "gchat.qpic.cn"
|
||||
private const val GPRO_PIC_NT = "multimedia.nt.qq.com.cn"
|
||||
private const val C2C_PIC = "c2cpicdw.qpic.cn"
|
||||
|
||||
internal object RichProtoSvc: BaseSvc() {
|
||||
/*@Deprecated("Use RichProtoSvc.getQQDns instead", ReplaceWith("getQQDns(domain)"))
|
||||
fun getQQDns(domain: String) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("domain", "xxx")
|
||||
bundle.putInt("businessType", 1)
|
||||
val result = BinderMethodProxy
|
||||
.callServer(QIPCClientHelper.getInstance().client, "InnerDnsModule", "reqDomain2IpList", bundle)
|
||||
if (result.isSuccess) {
|
||||
val ipList: ArrayList<IpData> = result.data.getParcelableArrayList("ip")!!
|
||||
}
|
||||
}*/
|
||||
|
||||
suspend fun getGuildFileDownUrl(peerId: String, channelId: String, fileId: String, bizId: Int): String {
|
||||
val buffer = sendOidbAW("OidbSvcTrpcTcp.0xfc2_0", 4034, 0, ProtoBuf.encodeToByteArray(
|
||||
Oidb0xfc2ReqBody(
|
||||
@ -142,19 +163,35 @@ internal object RichProtoSvc: BaseSvc() {
|
||||
}
|
||||
|
||||
fun getGroupPicDownUrl(
|
||||
originalUrl: String,
|
||||
md5: String
|
||||
): String {
|
||||
return "http://gchat.qpic.cn/gchatpic_new/0/0-0-${md5.uppercase()}/0?term=2"
|
||||
val domain = if (originalUrl.contains("rkey=")) GPRO_PIC_NT else GPRO_PIC
|
||||
if (originalUrl.isNotEmpty()) {
|
||||
return "https://$domain$originalUrl"
|
||||
}
|
||||
return "https://$domain/gchatpic_new/0/0-0-${md5.uppercase()}/0?term=2"
|
||||
}
|
||||
|
||||
fun getC2CPicDownUrl(
|
||||
originalUrl: String,
|
||||
md5: String
|
||||
): String {
|
||||
return "https://c2cpicdw.qpic.cn/offpic_new/0/123-0-${md5.uppercase()}/0?term=2"
|
||||
if (originalUrl.isNotEmpty()) {
|
||||
return "https://$C2C_PIC$originalUrl"
|
||||
}
|
||||
return "https://$C2C_PIC/offpic_new/0/123-0-${md5.uppercase()}/0?term=2"
|
||||
}
|
||||
|
||||
fun getGuildPicDownUrl(md5: String): String {
|
||||
return "https://gchat.qpic.cn/qmeetpic/0/0-0-${md5.uppercase()}/0?term=2"
|
||||
fun getGuildPicDownUrl(
|
||||
originalUrl: String,
|
||||
md5: String
|
||||
): String {
|
||||
val domain = if (originalUrl.contains("rkey=")) GPRO_PIC_NT else GPRO_PIC
|
||||
if (originalUrl.isNotEmpty()) {
|
||||
return "https://$domain$originalUrl"
|
||||
}
|
||||
return "https://$domain/qmeetpic/0/0-0-${md5.uppercase()}/0?term=2"
|
||||
}
|
||||
|
||||
suspend fun getC2CVideoDownUrl(
|
||||
@ -321,12 +358,4 @@ internal object RichProtoSvc: BaseSvc() {
|
||||
RichProtoProc.procRichProtoReq(richProtoReq)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getGuildPttDownUrl(
|
||||
peerId: String,
|
||||
md5Hex: String,
|
||||
fileUUId: String
|
||||
): String {
|
||||
return "unsupported"
|
||||
}
|
||||
}
|
@ -35,8 +35,8 @@ internal object GetImage: IActionHandler() {
|
||||
image.size,
|
||||
image.fileName,
|
||||
when(image.chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(fileMd5)
|
||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(fileMd5)
|
||||
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl("", fileMd5)
|
||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl("", fileMd5)
|
||||
else -> error("Not supported chat type: ${image.chatType}, convertMsgElementsToMsgSegment::Pic")
|
||||
}
|
||||
), echo = echo)
|
||||
|
@ -103,7 +103,7 @@ internal object UploadGroupFile : IActionHandler() {
|
||||
|
||||
// 根据文件大小调整超时时间
|
||||
val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEGROUP)
|
||||
val info = (withTimeoutOrNull((srcFile.length() / (300 * 1024)) * 1000 + 5000) {
|
||||
val info = (withTimeoutOrNull((srcFile.length() / (125 * 1024)) * 1000 + 5000) {
|
||||
val msgService = QRoute.api(IMsgService::class.java)
|
||||
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId)
|
||||
suspendCancellableCoroutine<FileTransNotifyInfo?> {
|
||||
|
@ -1,12 +1,42 @@
|
||||
@file:Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||
|
||||
package moe.fuqiuluo.shamrock.xposed.hooks
|
||||
|
||||
import android.content.Context
|
||||
import com.tencent.mobileqq.perf.block.BinderMethodProxy
|
||||
import com.tencent.mobileqq.qmmkv.MMKVOptionEntity
|
||||
import de.robv.android.xposed.XposedBridge
|
||||
import epic.EIPCClient
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.tools.beforeHook
|
||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||
import moe.fuqiuluo.symbols.Process
|
||||
import moe.fuqiuluo.symbols.XposedHook
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
@XposedHook(priority = -1)
|
||||
@XposedHook(priority = -1, process = Process.ALL)
|
||||
internal class HookForDebug: IAction {
|
||||
override fun invoke(ctx: Context) {
|
||||
/*
|
||||
/*val NtDnsManager = LuoClassloader.load("com.tencent.qqnt.dns.NtDnsManager")!!
|
||||
val NtDnsInternal = NtDnsManager.declaredMethods.first {
|
||||
!Modifier.isStatic(it.modifiers) && it.parameterCount == 0
|
||||
}.returnType
|
||||
XposedBridge.hookMethod(NtDnsInternal.declaredMethods.first {
|
||||
it.parameterCount == 2
|
||||
&& it.parameterTypes[0] == String::class.java
|
||||
&& it.parameterTypes[1] == Int::class.java
|
||||
&& it.returnType == ArrayList::class.java
|
||||
}, beforeHook {
|
||||
val domain = it.args[0] as String
|
||||
val type = it.args[1] as Int
|
||||
LogCenter.log("NtDnsManager: reqDomain2IpList($domain, $type)")
|
||||
LogCenter.log(Exception().stackTraceToString())
|
||||
})*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
val httpEngineService = AppRuntimeFetcher.appRuntime
|
||||
.getRuntimeService(IHttpEngineService::class.java, "all")
|
||||
httpEngineService.javaClass.hookMethod("sendReq").before {
|
||||
@ -19,7 +49,17 @@ internal class HookForDebug: IAction {
|
||||
LogCenter.log("请求地址: ${req.mReqUrl}")
|
||||
LogCenter.log("请求: ${req.toInnerValuesString(NetReq::class.java)}")
|
||||
}
|
||||
}
|
||||
BinderMethodProxy::class.java.hookMethod("callServer").before {
|
||||
val action = it.args[2] as String
|
||||
if (action == "reqDomain2IpList") {
|
||||
LogCenter.log(Exception().stackTraceToString())
|
||||
}
|
||||
}
|
||||
EIPCClient::class.java.hookMethod("callServer").before {
|
||||
val module = it.args[0] as String
|
||||
val action = it.args[1] as String
|
||||
if (action == "reqDomain2IpList" || module.contains("dns", ignoreCase = true)) {
|
||||
LogCenter.log(Exception().stackTraceToString())
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user