fix: sticker panel save pic

This commit is contained in:
Hicores
2024-04-26 23:40:39 +08:00
parent b7ddb05d36
commit 669ce7c12e
4 changed files with 191 additions and 2 deletions

View File

@@ -238,6 +238,7 @@ dependencies {
implementation(libs.byte.buddy)
implementation(libs.dalvik.dx)
ksp(libs.sealedEnum.ksp)
implementation(libs.google.protobuf)
}
val adb: String = androidComponents.sdkComponents.adb.get().asFile.absolutePath

View File

@@ -0,0 +1,141 @@
package cc.hicore.Utils;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import io.github.qauxv.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
public class FunProtoData {
private final HashMap<Integer, List<Object>> values = new HashMap<>();
public void fromJSON(JSONObject json){
try {
Iterator<String> key_it = json.keys();
while (key_it.hasNext()){
String key = key_it.next();
int k = Integer.parseInt(key);
Object value = json.get(key);
if (value instanceof JSONObject){
FunProtoData newProto = new FunProtoData();
newProto.fromJSON((JSONObject) value);
putValue(k, newProto);
}else if (value instanceof JSONArray){
JSONArray arr = (JSONArray) value;
for (int i=0;i < arr.length(); i++){
Object arr_obj = arr.get(i);
if (arr_obj instanceof JSONObject){
FunProtoData newProto = new FunProtoData();
newProto.fromJSON((JSONObject) arr_obj);
putValue(k, newProto);
}else {
putValue(k, arr_obj);
}
}
}else {
putValue(k, value);
}
}
}catch (Exception ignored){ }
}
private void putValue(int key, Object value){
List<Object> list = values.computeIfAbsent(key, k -> new ArrayList<>());
list.add(value);
}
public void fromBytes(byte[] b) throws IOException {
CodedInputStream in = CodedInputStream.newInstance(b);
while (in.getBytesUntilLimit() > 0){
int tag = in.readTag();
int fieldNumber = tag >>> 3;
int wireType = tag & 7;
if (wireType == 4 || wireType == 3 || wireType > 5) throw new IOException("Unexpected wireType: "+wireType);
switch (wireType){
case 0:
putValue(fieldNumber, in.readInt64());
break;
case 1:
putValue(fieldNumber, in.readRawVarint64());
break;
case 2:
byte[] subBytes = in.readByteArray();
try {
FunProtoData sub_data = new FunProtoData();
sub_data.fromBytes(subBytes);
putValue(fieldNumber, sub_data);
}catch (Exception e){
putValue(fieldNumber, new String(subBytes));
}
break;
case 5:
putValue(fieldNumber, in.readFixed32());
break;
default:
putValue(fieldNumber,"Unknown wireType: "+wireType);
break;
}
}
}
public JSONObject toJSON()throws Exception{
JSONObject obj = new JSONObject();
for (Integer k_index : values.keySet()){
List<?> list = values.get(k_index);
if (list.size() > 1){
JSONArray arr = new JSONArray();
for (Object o : list){
arr.put(valueToText(o));
}
obj.put(String.valueOf(k_index), arr);
}else {
for (Object o : list){
obj.put(String.valueOf(k_index), valueToText(o));
}
}
}
return obj;
}
private Object valueToText(Object value) throws Exception {
if (value instanceof FunProtoData){
FunProtoData data = (FunProtoData) value;
return data.toJSON();
}else {
return value;
}
}
public byte[] toBytes(){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CodedOutputStream out = CodedOutputStream.newInstance(bos);
try {
for (Integer k_index : values.keySet()){
List<?> list = values.get(k_index);
for (Object o : list){
if (o instanceof Long){
long l = (long) o;
out.writeInt64(k_index , l);
}else if (o instanceof String){
String s = (String) o;
out.writeByteArray(k_index , s.getBytes());
}else if (o instanceof FunProtoData){
FunProtoData data = (FunProtoData) o;
byte[] subBytes = data.toBytes();
out.writeByteArray(k_index , subBytes);
}else if (o instanceof Integer){
int i = (int) o;
out.writeInt32(k_index, i);
}else {
Log.w("FunProtoData.toBytes "+ "Unknown type: " + o.getClass().getName());
}
}
}
out.flush();
return bos.toByteArray();
}catch (Exception e){
XLog.e("FunProtoData", "toBytes", e);
return new byte[0];
}
}
}

View File

@@ -29,8 +29,10 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import cc.hicore.QApp.QAppUtils;
import cc.hicore.ReflectUtil.MRes;
import cc.hicore.ReflectUtil.XField;
import cc.hicore.ReflectUtil.XMethod;
import cc.hicore.Utils.FunConf;
import cc.hicore.Utils.FunProtoData;
import cc.hicore.Utils.XLog;
import cc.hicore.hook.stickerPanel.ICreator;
import cc.hicore.hook.stickerPanel.PanelUtils;
@@ -38,6 +40,8 @@ import cc.hicore.message.chat.SessionHooker;
import cc.hicore.message.chat.SessionUtils;
import cc.ioctl.util.HookUtils;
import cc.ioctl.util.Reflex;
import com.tencent.qphone.base.remote.FromServiceMsg;
import com.tencent.qphone.base.remote.ToServiceMsg;
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgService;
import com.tencent.qqnt.kernel.nativeinterface.MsgElement;
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord;
@@ -63,8 +67,10 @@ import io.github.qauxv.util.dexkit.Guild_Emo_Btn_Create_QQNT;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import kotlin.Unit;
import org.json.JSONObject;
@FunctionHookEntry
@UiItemAgentEntry
@@ -78,6 +84,8 @@ public class StickerPanelEntryHooker extends CommonSwitchFunctionHook implements
Guild_Emo_Btn_Create_QQNT.INSTANCE
});
}
public static String rkey_group;
public static String rkey_private;
@NonNull
@Override
@@ -193,9 +201,9 @@ public class StickerPanelEntryHooker extends CommonSwitchFunctionHook implements
}else {
if (originUrl.startsWith("/download")){
if (originUrl.contains("appid=1406")){
urls.add("https://multimedia.nt.qq.com.cn" + originUrl + "&rkey=CAQSKDOc_jvbthUjAatuFPQIo-x9wwcDhDGd8SOEu5FyJWNxNMabJTTRpO8");
urls.add("https://multimedia.nt.qq.com.cn" + originUrl + rkey_group);
}else {
urls.add("https://multimedia.nt.qq.com.cn" + originUrl + "&rkey=CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64");
urls.add("https://multimedia.nt.qq.com.cn" + originUrl + rkey_private);
}
}else {
urls.add("https://gchat.qpic.cn"+picElement.getOriginImageUrl());
@@ -261,9 +269,47 @@ public class StickerPanelEntryHooker extends CommonSwitchFunctionHook implements
}
);
//Hook for rkey
HookUtils.hookBeforeIfEnabled(this, XMethod.clz("mqq.app.msghandle.MsgRespHandler").name("dispatchRespMsg").ignoreParam().get(), param -> {
ToServiceMsg serviceMsg = XField.obj(param.args[1]).name("toServiceMsg").get();
FromServiceMsg fromServiceMsg = XField.obj(param.args[1]).name("fromServiceMsg").get();
if ("OidbSvcTrpcTcp.0x9067_202".equals(fromServiceMsg.getServiceCmd())){
FunProtoData data = new FunProtoData();
data.fromBytes(getUnpPackage(fromServiceMsg.getWupBuffer()));
JSONObject obj = data.toJSON();
rkey_group = obj.getJSONObject("4")
.getJSONObject("4")
.getJSONArray("1")
.getJSONObject(0).getString("1");
rkey_private = obj.getJSONObject("4")
.getJSONObject("4")
.getJSONArray("1")
.getJSONObject(1).getString("1");
}
});
return true;
}
private static byte[] getUnpPackage(byte[] b){
if (b == null){
return null;
}
if (b.length < 4){
return b;
}
if (b[0] == 0){
return Arrays.copyOfRange(b, 4, b.length);
}else {
return b;
}
}
@NonNull
@Override
public String getName() {

View File

@@ -43,6 +43,7 @@ byte-buddy = { module = "net.bytebuddy:byte-buddy", version = "1.14.14" }
dalvik-dx = { module = "com.jakewharton.android.repackaged:dalvik-dx", version = "14.0.0_r21" }
flatbuffers-java = { module = "com.google.flatbuffers:flatbuffers-java", version = "23.5.26" }
davemorrissey-subsampling-scale-image-view = { module = "com.davemorrissey.labs:subsampling-scale-image-view-androidx", version = "3.10.0" }
google-protobuf = { module = "com.google.protobuf:protobuf-java", version = "4.26.1" }
[plugins]
changelog = { id = "org.jetbrains.changelog", version = "2.2.0" }