Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
Shamrock: fix #236
Browse files Browse the repository at this point in the history
  • Loading branch information
whitechi73 committed Feb 17, 2024
1 parent 63ce2d4 commit 3b210d7
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.tencent.mobileqq.qmmkv;

public class MMKVOptionEntity {
public String decodeString(String str, String str2) {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions qqinterface/src/main/java/epic/EIPCClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package epic;

public class EIPCClient {
}
11 changes: 11 additions & 0 deletions qqinterface/src/main/java/epic/EIPCResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package epic;

import android.os.Bundle;

public class EIPCResult {
public Bundle data;

public boolean isSuccess() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 {
/**
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -321,12 +358,4 @@ internal object RichProtoSvc: BaseSvc() {
RichProtoProc.procRichProtoReq(richProtoReq)
}
}

suspend fun getGuildPttDownUrl(
peerId: String,
md5Hex: String,
fileUUId: String
): String {
return "unsupported"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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?> {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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())
}
}*/

}
}

0 comments on commit 3b210d7

Please sign in to comment.