Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
FourTwooo authored May 21, 2024
1 parent b5757da commit 2800252
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 69 deletions.
115 changes: 94 additions & 21 deletions Hook_WeChat_FaaS.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,111 @@
function CallWX(jsapi_name, data) {
let CallWX_asyncRequestCounter = 0;
let Call_AppId = null;
let AppId = null;

function CallWX(appid, jsapi_name, data) {
Call_AppId = appid;
// CallWX_asyncRequestCounter = 0
Java.perform(function () {
let I = 1;
function dumpAllFieldValue(obj) {
if (obj === null) {
return;
}
var cls = obj.getClass();
while (cls !== null && !cls.equals(Java.use("java.lang.Object").class)) {
var fields = cls.getDeclaredFields();
if (fields === null || fields.length === 0) {
cls = cls.getSuperclass();
continue;
}
// if (!cls.equals(obj.getClass())) {
// console.log("Dump super class " + cls.getName() + " fields:");
// }

for (var i = 0; i < fields.length; i++) {
var field = fields[i];
field.setAccessible(true);
var name = field.getName();
var value = field.get(obj);
var type = field.getType();
if (name === "C") {
return value
}
// console.log(type + " " + name + "=" + value);
}

cls = cls.getSuperclass();
}
}

function getFieldValue(obj, fieldName) {
var cls = obj.getClass();
var field = cls.getDeclaredField(fieldName);
field.setAccessible(true);
var name = field.getName();
var value = field.get(obj);
// console.log("field: " + field + "\tname:" + name + "\tvalue:" + value);
return value;
}

CallWX_asyncRequestCounter++;
Java.choose('com.tencent.mm.appbrand.commonjni.AppBrandCommonBindingJni', {
onMatch: function (instance) {
// console.log(I, JSON.stringify(instance.mAppBrandDelegate))
instance.nativeInvokeHandler(jsapi_name, data, '{}', I++, true)
// instance.nativeInvokeHandler('login', '{"requestInQueue":false}', '{}', I++, true)
// CallWX_asyncRequestCounter++;
// console.log(CallWX_asyncRequestCounter, instance.mNativeHandle.value, JSON.stringify(instance.mAppBrandDelegate))
try {
let mAppBrandDelegate = getFieldValue(instance, 'mAppBrandDelegate')
let g = getFieldValue(mAppBrandDelegate, 'g')
dumpAllFieldValue(g)
let C = dumpAllFieldValue(g)
if (C.toString() !== '{__APP__=true}') {
return;
}
} catch {
return;
}


instance.nativeInvokeHandler(jsapi_name, data, '{}', CallWX_asyncRequestCounter, true)

},
onComplete: function () {
}
})
})
// Call_AppId = null
return `${Call_AppId}${CallWX_asyncRequestCounter}`;
}

function Main() {

Java.perform(function () {
Java.perform(function () {

let AppBrandCommonBindingJni = Java.use("com.tencent.mm.appbrand.commonjni.AppBrandCommonBindingJni");
AppBrandCommonBindingJni["nativeInvokeHandler"].implementation = function (jsapi_name, data, str3, asyncRequestCounter, z15) {
console.log(`[${asyncRequestCounter}] == \x1b[36m[requests]\x1b[0m: jsapi_name=${jsapi_name}, data=${data}, str3=${str3}, z15=${z15}`);
return this["nativeInvokeHandler"](jsapi_name, data, str3, asyncRequestCounter, z15);
};
let v = Java.use("com.tencent.mm.plugin.appbrand.v");
v["getAppId"].implementation = function () {
AppId = this["getAppId"]();
return AppId;
};

let AppBrandJsBridgeBinding = Java.use('com.tencent.mm.appbrand.commonjni.AppBrandJsBridgeBinding');
AppBrandJsBridgeBinding['invokeCallbackHandler'].implementation = function (asyncRequestCounter, res) {
console.log(`[${asyncRequestCounter}] == \x1b[32m[response]\x1b[0m: ${res}`)
this['invokeCallbackHandler'](asyncRequestCounter, res)
}
let AppBrandCommonBindingJni = Java.use("com.tencent.mm.appbrand.commonjni.AppBrandCommonBindingJni");
AppBrandCommonBindingJni["nativeInvokeHandler"].implementation = function (jsapi_name, data, str3, asyncRequestCounter, z15) {
CallWX_asyncRequestCounter = asyncRequestCounter;
console.log(`[${AppId}] [${asyncRequestCounter}] == \x1b[36m[requests]\x1b[0m: jsapi_name=${jsapi_name}, data=${data}, str3=${str3}, z15=${z15}`);

return this["nativeInvokeHandler"](jsapi_name, data, str3, asyncRequestCounter, z15);
};

let AppBrandJsBridgeBinding = Java.use('com.tencent.mm.appbrand.commonjni.AppBrandJsBridgeBinding');
AppBrandJsBridgeBinding['invokeCallbackHandler'].implementation = function (asyncRequestCounter, res) {
console.log(`[${AppId}] [${asyncRequestCounter}] == \x1b[32m[response]\x1b[0m: ${res}`)

this['invokeCallbackHandler'](asyncRequestCounter, res)
}
)
}

setTimeout(Main, 500)
}
)


rpc.exports = {call: CallWX}
// frida -U -l Hook_WeChat_FaaS.js com.tencent.mm --no-pause

// frida -U -l Hook_WeChat_FaaS.js com.tencent.mm --no-pause
// CallWX('wx3c12cdd0ae8b1a7b', 'operateWXData', '{"data":{"api_name":"webapi_getuserinfo","data":{"lang":"en","version":"3.4.3"},"operate_directly":false,"with_credentials":true,"tid":1716198903418},"requestInQueue":true,"isImportant":true}')
// CallWX('wx3c12cdd0ae8b1a7b', 'setStorageSync', '{"key":"sensors_mp_prepare_data","data":"[]","dataType":"Array","storageId":0}')
94 changes: 46 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,46 @@
# Hook_WeChat_FaaS
frida Hook 微信云函数脚本

![](https://raw.githubusercontent.com/FourTwooo/Hook_WeChat_FaaS/main/cesi.png)

## 环境

开发测试环境. 理论来说 安卓APP应该是不限版本 通用的

- Android => 10

- frida => 14.2.18

- 微信安卓APP => 8.0.49



## 运行


在小程序界面时运行以下命令或使用进程ID去运行
```
frida -UF -l .\Hook_WeChat_FaaS.js com.tencent.mm --no-pause
```

## 目前问题

主动调用那块 我是使用Java.choose 从内存中取的实例 但在内存中的实例有很多个
所以每次主动调用 都会触发好几次. 但其实只会成功一个 其他的不会成功 这个暂时没弄清楚为什么

如果要Hook多个小程序, 会存在问题. 我自己机型来看 打开多个小程序 进程ID是完全一样的 除了包名不一样
更别谈涉及微信多开这个问题

这些问题 在上班时间 我会逐步修复. 这个项目也是因为公司业务有需求 临时开发. 开源了有自己想法的可以自己二次开发


## 参考文章

- [看雪论坛 作者ID:Sharp_Wang](https://mp.weixin.qq.com/s/7yZzf4V-2fcn-jRwm4uO-w)

## 支持

实际上并没有多少技术含量. 其实就是HOOK了 请求和响应的代码位置. 没有什么技术含量

开源不易, 可以的话支持以下
![](https://github.com/FourTwooo/Hook_WeChat_FaaS/blob/main/wx.jpg?raw=true)

QQ交流群: 1021904342
# Hook_WeChat_FaaS
frida Hook 微信云函数脚本

![](https://raw.githubusercontent.com/FourTwooo/Hook_WeChat_FaaS/main/cesi.png)

## 环境

开发测试环境. 理论来说 安卓APP应该是不限版本 通用的

- Android => 10

- frida => 14.2.18

- 微信安卓APP => 8.0.49



## 运行


在小程序界面时运行以下命令或使用进程ID去运行
```
frida -UF -l .\Hook_WeChat_FaaS.js com.tencent.mm --no-pause
```

## 目前问题

主动调用可能调用部分api会存在bug

涉及微信多开的hook 暂时未适配

这个项目也是因为公司业务有需求 临时开发. 开源了有自己想法的可以自己二次开发


## 参考文章

- [看雪论坛 作者ID:Sharp_Wang](https://mp.weixin.qq.com/s/7yZzf4V-2fcn-jRwm4uO-w)

## 支持

实际上并没有多少技术含量. 其实就是HOOK了 请求和响应的代码位置. 没有什么技术含量

开源不易, 可以的话支持以下
![](https://github.com/FourTwooo/Hook_WeChat_FaaS/blob/main/wx.jpg?raw=true)

QQ交流群: 1021904342
143 changes: 143 additions & 0 deletions frida_js/Hook_WeChat_FaaS.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
let CallWX_asyncRequestCounter = 0;
let Call_AppId = null;
let AppId = null;

function CallWX(appid, jsapi_name, data) {
Call_AppId = appid;
// CallWX_asyncRequestCounter = 0
Java.perform(function () {
function dumpAllFieldValue(obj) {
if (obj === null) {
return;
}
var cls = obj.getClass();
while (cls !== null && !cls.equals(Java.use("java.lang.Object").class)) {
var fields = cls.getDeclaredFields();
if (fields === null || fields.length === 0) {
cls = cls.getSuperclass();
continue;
}
// if (!cls.equals(obj.getClass())) {
// console.log("Dump super class " + cls.getName() + " fields:");
// }

for (var i = 0; i < fields.length; i++) {
var field = fields[i];
field.setAccessible(true);
var name = field.getName();
var value = field.get(obj);
var type = field.getType();
if (name === "C"){
return value
}
// console.log(type + " " + name + "=" + value);
}

cls = cls.getSuperclass();
}
}

function getFieldValue(obj, fieldName) {
var cls = obj.getClass();
var field = cls.getDeclaredField(fieldName);
field.setAccessible(true);
var name = field.getName();
var value = field.get(obj);
// console.log("field: " + field + "\tname:" + name + "\tvalue:" + value);
return value;
}

CallWX_asyncRequestCounter++;
Java.choose('com.tencent.mm.appbrand.commonjni.AppBrandCommonBindingJni', {
onMatch: function (instance) {
// CallWX_asyncRequestCounter++;
// console.log(CallWX_asyncRequestCounter, instance.mNativeHandle.value, JSON.stringify(instance.mAppBrandDelegate))
try {
let mAppBrandDelegate = getFieldValue(instance, 'mAppBrandDelegate')
let g = getFieldValue(mAppBrandDelegate, 'g')
dumpAllFieldValue(g)
let C = dumpAllFieldValue(g)
if (C.toString() !== '{__APP__=true}'){
return;
}
} catch {
return;
}


instance.nativeInvokeHandler(jsapi_name, data, '{}', CallWX_asyncRequestCounter, true)

},
onComplete: function () {
}
})
})
// Call_AppId = null
return `${Call_AppId}${CallWX_asyncRequestCounter}`;
}


Java.perform(function () {

let v = Java.use("com.tencent.mm.plugin.appbrand.v");
v["getAppId"].implementation = function () {
if (Call_AppId === null) {
AppId = this["getAppId"]();
} else {
AppId = Call_AppId;
}
// result = 'wx3c12cdd0ae8b1a7b';
// console.log(`v.getAppId result=${result}`);
return AppId;
};

// let o0 = Java.use("com.tencent.mm.plugin.appbrand.jsapi.auth.o0");
// o0["d"].implementation = function (rdVar) {
// console.log(`o0.d is called: rdVar=${rdVar}`);
// this["d"](rdVar);
// };

// let AppBrandRuntime = Java.use("com.tencent.mm.plugin.appbrand.AppBrandRuntime");
// AppBrandRuntime["k0"].implementation = function (appBrandInitConfig) {
// console.log(`AppBrandRuntime.k0 is called: appBrandInitConfig=${appBrandInitConfig}`);
// this["k0"](appBrandInitConfig);
// };


let AppBrandCommonBindingJni = Java.use("com.tencent.mm.appbrand.commonjni.AppBrandCommonBindingJni");
AppBrandCommonBindingJni["nativeInvokeHandler"].implementation = function (jsapi_name, data, str3, asyncRequestCounter, z15) {
CallWX_asyncRequestCounter = asyncRequestCounter;
// console.log(`[${AppId}] [${asyncRequestCounter}] == \x1b[36m[requests]\x1b[0m: jsapi_name=${jsapi_name}, data=${data}, str3=${str3}, z15=${z15}`);
send(JSON.stringify({
type: 'requests',
AppId: AppId,
asyncRequestCounter: asyncRequestCounter,
jsapi_name: jsapi_name,
data: data,
str3: str3,
z15: z15
}))
return this["nativeInvokeHandler"](jsapi_name, data, str3, asyncRequestCounter, z15);
};

let AppBrandJsBridgeBinding = Java.use('com.tencent.mm.appbrand.commonjni.AppBrandJsBridgeBinding');
AppBrandJsBridgeBinding['invokeCallbackHandler'].implementation = function (asyncRequestCounter, res) {
// console.log(`[${AppId}] [${asyncRequestCounter}] == \x1b[32m[response]\x1b[0m: ${res}`)
send(JSON.stringify({
type: 'response',
AppId: AppId,
asyncRequestCounter: asyncRequestCounter,
res: res
}))
this['invokeCallbackHandler'](asyncRequestCounter, res)
}

}
)


rpc.exports = {call: CallWX}
// frida -U -l Hook_WeChat_FaaS.js com.tencent.mm --no-pause

// CallWX('wx3c12cdd0ae8b1a7b', 'operateWXData', '{"data":{"api_name":"webapi_getuserinfo","data":{"lang":"en","version":"3.4.3"},"operate_directly":false,"with_credentials":true,"tid":1716198903418},"requestInQueue":true,"isImportant":true}')
// CallWX('wx3c12cdd0ae8b1a7b', 'setStorageSync', '{"key":"sensors_mp_prepare_data","data":"[]","dataType":"Array","storageId":0}')
Loading

0 comments on commit 2800252

Please sign in to comment.