Skip to content
EEEEhexPublic

About

逆向调用QQ Mojo IPC与WeChat XPlugin

Resources

Stars

383 stars

Watchers

10 watching

Forks

Latest commit

 

History

33 Commits

Folders and files

Repository files navigation

项目说明

本项目通过逆向QQNT 逆向出调用QQ Mojo IPC的方法, 使用QQMojoIPC可以调用QQNT的插件并与之通信。
并在此基础上逆向出调用微信MMMojo.dll的方法, 通过调用MMMojo可以调用WeChat的插件并与之通信。

目前可以调用QQNT的如下组件:

  • QQScreenShot

目前可以调用WeChat的如下组件:

  1. WeChatOCR.exe:
  • OCR功能
  1. WeChatUtility.exe:
  • QRScan功能 (二维码扫描)
  • TextScan功能 (可能是用来判断图片上有没有文字的)
  • ResampleImage功能
  • DecodeImage功能
  1. WeChatPlayer.exe:
  • 本地视频播放功能

项目结构

├─3rdparty
├─examples
├─proto
└─src
\ \ ├─include
\ \ │ ├─mmmojo_source
\ \ │ ├─qq_mojoipc
\ \ │ └─xplugin_protobuf
\ \ ├─mmmojocall
\ \ │ └─wrapper
\ \ └─qq_mojoipc

(此版本根据微信的mmmojo源码再次重构, 逻辑更清晰)
其中3rdparty是编译好的libprotobuf库, examples里是调用方法的示例, proto里是WeChat与组件之间的Protobuf通信协议的定义文件。
src文件夹里 include中mmmojo_source是微信MMMojo的源代码中的一些定义, qq_mojoipc是实现QQMojoIPC的头文件, xplugin_protobuf是使用protoc编译后的头文件。
qq_mojoipc文件夹是实现QQMojoIPC的实现文件, mmmojocall里是实现调用微信XPlugin组件的实现文件, 其中mmmojo_call.cpp是基础的调用XPlugin的方法, wrapper里是封装了对应组件通信协议的文件。

编译说明

本项目使用cmake, 以下为cmake选项说明:

Option 说明
XPLUGIN_WRAPPER 编译封装好WeChat通信协议的实现文件 默认为ON
BUILD_QQIPC 编译QQMojoIPC的实现文件 默认为OFF
BUILD_CPPEXAMPLE 编译调用方法示例项目 默认为OFF
EXAMPLE_USE_JSON CPP示例项目的回调函数的数据使用Json格式而非protobuf 默认为ON
BUILD_PURE_C_MODE 编译纯C接口方便其他语言调用 默认为OFF

快速上手

在编译前请先解压3rdparty下的压缩文件(或者自己编译一下protobuf) 以及src/include/xplugin_protobuf下的压缩的头文件

使用如下命令行:

cmake -B build -G "Visual Studio 17 2022" -A x64 -DBUILD_CPPEXAMPLE=ON

如果需要使用其他语言调用, 需要加上(调用方法请查看examples文件夹)

-DBUILD_PURE_C_MODE=ON

然后在build文件夹里编译生成visual studio项目即可

WeChat MMMojo说明

微信通过mmmojo_64.dll启动其组件并与组件通信。
mmmojo就是对谷歌mojo ipc的一层封装, 有如下几种通信方式(具体请查看mmmojo.h) :

typedef enum {
  kMMNone = 0,
  kMMPush,
  kMMPullReq,
  kMMPullResp,
  kMMShared,
} MMMojoInfoMethod;

在与组件通信过程中,请求操作与回复都是通过发送 request_id + pb数据 + MMMojoInfoMethod
其中request_id表明了请求的操作类型(比如QRScan请求), pb数据携带操作的参数, MMMojoInfoMethod表明通信方式。
每个XPlugin组件都有自己定义的request_id(具体请查看mmmojo_call.h), 例如:
(request_id 没有逆向全, 大体就是这么多了)

//WeChatUtility组件
enum RequestIdUtility
{
	UtilityHiPush = 10001,			//是Utility启动发送的
	UtilityInitPullReq = 10002,		//初始化请求
	UtilityInitPullResp = 10003,		//回复创建的都是Shared类型的info, 但是调用了SwapMMMojoWriteInfoCallback, 所以回调的还是Pull
	UtilityResampleImagePullReq = 10010,
	UtilityResampleImagePullResp = 10011,
	UtilityDecodeImagePullReq = 10020,
	UtilityDecodeImagePullResp = 10021,
	UtilityPicQRScanPullReq = 10030,	//10030是点击OCR时(也是打开图片时)发送的请求, 参数是图片路径
	UtilityQRScanPullReq = 10031,		//10031是截图框选时发送的请求, 参数应该是某种编码后的图片数据
	UtilityQRScanPullResp = 10032,		//这两种请求的返回ID都是10032
	UtilityTextScanPushResp = 10040		//TextScan具体在扫什么不是很清楚 可能是用来判断图片上是否有文字
};

pb数据就是对应的序列化后的protobuf数据(具体请查看proto文件夹下的定义文件), 例如:

message QRScanReqMessage {
	string origin_pic = 1;		//原始图片路径 可选
	string decode_pic = 2;		//解码后的图片路径 可选
	int32 unknown_0 = 3;		//未知 可选 一般为0
	bytes encode_pic_data = 4;	//某种编码后的图片数据 可选
	int32 encode_pic_x = 5;		//编码图片长	可选
	int32 encode_pic_y = 6;		//编码图片宽 可选
	int32 unknown_1 = 7;		//未知 一般为1
	int32 text_scan_id = 8;		//可能是
	int32 unknown_3 = 9;		//未知 一般为1
}

相关项目

本人代码能力比较差,此项目写的可能不是很方便使用,以下为其他师傅对本项目代码优化后的相关项目:

  1. swigger: wechat-ocr
  2. kanadeblisst00: wechat_ocr

About

逆向调用QQ Mojo IPC与WeChat XPlugin

Resources

Stars

383 stars

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages