Reverse wx send pictures
development tools
tool name | tool type | illustrate |
---|---|---|
AndroidStuduo | editing tools | development tools |
jadx | java tool | Unpack the apk into a java project |
xposed | plug-in tool | plug-in |
wx | Version 8.0.28 |
start
First decompile the apk to source code through jadx, then build it, and open it in android studio for easy analysis.
Points to analyze the source code:
cgi /cgi-bin/micromsg-bin/uploadmsgimg to send pictures
Send the id of the picture
constructorId = 14
Finally found a realistic way
build cgi
send cgi
get localId
Enter the m129689XH method, see where imgDataMap gets the value from, and enter the method
Generate localId
Analysis process
- Get localId through local storage
- build cgi
- send cgi
- get callback
accomplish
public void sendImg(String toUser, String imagePath) throws Exception {
//获取class
Class ConfigStorageLogic = mHookClassLoader.loadClass("com.tencent.mm.model.aa");
Class DownloadImgService = mHookClassLoader.loadClass("com.tencent.mm.modelimage.t");
Class SendImgSpeeder = mHookClassLoader.loadClass("com.tencent.mm.modelimage.s");
Class NetSceneUploadMsgImg = mHookClassLoader.loadClass("com.tencent.mm.modelimage.q");
Class IOnSceneProgressEnd = mHookClassLoader.loadClass("com.tencent.mm.aw.j");
Class RunCgi = mHookClassLoader.loadClass("com.tencent.mm.aw.ab");
Class IDispatcher = mHookClassLoader.loadClass("com.tencent.mm.network.g");
Class ISceneEnd = mHookClassLoader.loadClass("com.tencent.mm.aw.i");
//构建参数
int chat_img_template = 2131231548;
Object sendImgSpeeder = ReflectionUtil.invokeStaticMethod(SendImgSpeeder, "bTU");
//数据库操作-生成localId
ArrayList arr = new ArrayList();
arr.add(imagePath);
ReflectionUtil.invokeMethod(sendImgSpeeder, "a",
ArrayList.class, boolean.class, int.class, int.class, String.class, int.class,
arr, true, 0, 0, toUser, chat_img_template);
//获取localId
ArrayList<Integer> GalleryUI_ImgIdList = ReflectionUtil.invokeMethod(sendImgSpeeder, "XH", String.class, toUser);
if(GalleryUI_ImgIdList == null || GalleryUI_ImgIdList.size() == 0){
DLog.log("图片错误选择为空");
return;
}
Integer num = GalleryUI_ImgIdList.get(0);
long localId = num.intValue();
DLog.log("localId = " + localId);
if(localId < 0){
DLog.log("图片错误");
return;
}
//构建cgi
String selfUserName = ReflectionUtil.invokeStaticMethod(ConfigStorageLogic, "bMk");
Object ImgService = ReflectionUtil.invokeStaticMethod(DownloadImgService, "bUb");
Object netSceneUploadMsgImg = ReflectionUtil.newInstance(NetSceneUploadMsgImg,
long.class, int.class, String.class, String.class, String.class, int.class, IOnSceneProgressEnd, int.class, String.class, String.class, boolean.class, int.class, boolean.class,
localId, 3, selfUserName, toUser, imagePath, 0, ImgService, 0, null, "", true, chat_img_template, true);
//发送cgi
Object rQt = ReflectionUtil.getStaticFieldValue(RunCgi, "rQt");
Object NetSceneQueue = ReflectionUtil.invokeMethod(rQt, "brh");
Object dispatcher = ReflectionUtil.getFieldValue(NetSceneQueue, "rPy");
ReflectionUtil.invokeMethod(netSceneUploadMsgImg, "doScene",
IDispatcher, ISceneEnd,
dispatcher, getCallback());
DLog.log("执行成功 等待结果");
}
//动态代理 回调结果, 当然你通过hook也行
public Object getCallback() throws Exception {
Class ISceneEnd = mHookClassLoader.loadClass("com.tencent.mm.aw.i");
return Proxy.newProxyInstance(classLoader, new Class[]{ISceneEnd},
(proxy, method, args) -> {
switch (method.getName()) {
case "onSceneEnd":
DLog.log("onSceneEnd");
Object result = args;
DLog.log("结果 " + gsonUtil.tojson(result));
break;
}
return null;
})
}
For reference only