Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf52de1560 | ||
|
|
2ed409e7b0 | ||
|
|
6f97a499b8 | ||
|
|
d33df9391e | ||
|
|
23fc28d011 | ||
|
|
e373b2f063 | ||
|
|
7e0b877d99 | ||
|
|
2ee16e36bf | ||
|
|
91bd8f5977 | ||
|
|
a9029e4a3d | ||
|
|
53a7938335 | ||
|
|
ce72262d58 | ||
|
|
bdf19fe4e4 | ||
|
|
44623e5b2e | ||
|
|
1824d6507c |
@@ -0,0 +1,3 @@
|
||||
[submodule "spdlog"]
|
||||
path = spdlog
|
||||
url = https://github.com/gabime/spdlog
|
||||
@@ -4,7 +4,7 @@ wechat hook 。PC端微信逆向学习。支持3.8.0.41,3.8.1.26, 3.9.0.28, 3.
|
||||
本仓库发布的内容,仅用于学习研究,请勿用于非法用途和商业用途!如因此产生任何法律纠纷,均与作者无关!
|
||||
|
||||
#### 项目说明:
|
||||
本项目是个人学习学习逆向的项目,参考 https://github.com/ljc545w/ComWeChatRobot ,在此基础上实现了微信的的其它版本的部分内容。
|
||||
<font color= "#dd0000">本项目是逆向练习项目,可能会造成封号等后果。请自行承担风险。仅用于学习研究,请勿于非法用途。</font>
|
||||
|
||||
#### 实现原理:
|
||||
逆向分析PC端微信客户端,定位相关功能关键Call,编写dll调用关键Call。然后将该dll文件注入到微信进程。
|
||||
@@ -19,7 +19,7 @@ dll在注入成功时,创建了一个默认端口为19088的http服务端,
|
||||
|
||||
```
|
||||
#### 使用说明:
|
||||
支持的版本3.8.0.41、3.8.1.26、3.9.0.28、3.9.2.23、3.9.2.26 。
|
||||
支持的版本3.8.0.41、3.8.1.26、3.9.0.28、3.9.2.23、3.9.2.26 、3.9.5.81。
|
||||
源码和主要实现在相应的分支内。
|
||||
src:主要的dll代码
|
||||
tool:简单的注入工具,一个是控制台,一个是图形界面。
|
||||
@@ -62,7 +62,9 @@ cmake
|
||||
|
||||
vcpkg
|
||||
#### 编译构建
|
||||
|
||||
先准备好编译环境。
|
||||
#### <font color= "#dd0000"> 以下是x86环境构建,3.9.5.81是x64环境,具体参考对应分支。</font>
|
||||
```
|
||||
cd wxhelper
|
||||
mkdir build
|
||||
@@ -179,6 +181,8 @@ port=19099
|
||||
|
||||
2023-06-05 :3.9.2.26版本更新
|
||||
|
||||
2023-07-07 :3.9.5.81版本更新
|
||||
|
||||
#### 功能预览:
|
||||
0.检查是否登录
|
||||
1.获取登录微信信息
|
||||
|
||||
+263
-1
@@ -164,7 +164,8 @@ data: 接口返回的数据
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,不为0成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
@@ -474,4 +475,265 @@ enableHttp=0时,使用ip,port的tcp服务回传消息。
|
||||
],
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 8.发送文件消息**
|
||||
###### 接口功能
|
||||
> 发送文件消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendFileMsg](/api/sendFileMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid |true |string| 接收人wxid |
|
||||
|filePath|true |string|文件绝对路径|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,不为0成功, 0失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"wxid": "filehelper",
|
||||
"filePath": "c:\\test.zip"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":345686720,"msg":"success","data":null}
|
||||
```
|
||||
|
||||
|
||||
#### 9.获取群详情**
|
||||
###### 接口功能
|
||||
> 获取群详情
|
||||
|
||||
###### 接口地址
|
||||
> [/api/getChatRoomDetailInfo](/api/getChatRoomDetailInfo)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|群详细内容|
|
||||
|  chatRoomId|string|群id|
|
||||
|  notice|string|公告通知|
|
||||
|  admin|string|群管理|
|
||||
|  xml|string|xml信息|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId": "12222@chatroom"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":345686720,"msg":"success","data":{
|
||||
"chatRoomId":"12222@chatroom",
|
||||
"notice":"test",
|
||||
"admin":"wxid_122333",
|
||||
"xml":"",
|
||||
}}
|
||||
```
|
||||
|
||||
|
||||
#### 10.添加群成员**
|
||||
###### 接口功能
|
||||
> 获取群详情
|
||||
|
||||
###### 接口地址
|
||||
> [/api/addMemberToChatRoom](/api/addMemberToChatRoom)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|memberIds |true |string| 成员id,多个用,分隔 |
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功,负数失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId":"21363231004@chatroom",
|
||||
"memberIds":"wxid_oyb662qhop4422"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"msg":"success","data":null}
|
||||
```
|
||||
|
||||
|
||||
#### 11.修改群昵称**
|
||||
###### 接口功能
|
||||
> 修改群昵称
|
||||
|
||||
###### 接口地址
|
||||
> [/api/modifyNickname](/api/modifyNickname)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|wxid |true |string| 自己的wxid |
|
||||
|nickName |true |string| 昵称 |
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"chatRoomId":"31004@chatroom",
|
||||
"wxid":"wxid_2721221512",
|
||||
"nickName":"1221"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"msg":"success","data":null}
|
||||
```
|
||||
|
||||
#### 12.删除群成员**
|
||||
###### 接口功能
|
||||
> 删除群成员
|
||||
|
||||
###### 接口地址
|
||||
> [/api/delMemberFromChatRoom](/api/delMemberFromChatRoom)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|memberIds |true |string| 成员id,用,分隔 |
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"chatRoomId":"1234@chatroom",
|
||||
"memberIds":"wxid_123"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"msg":"success","data":null}
|
||||
```
|
||||
|
||||
|
||||
#### 13.获取群成员**
|
||||
###### 接口功能
|
||||
> 获取群成员
|
||||
|
||||
###### 接口地址
|
||||
> [/api/getMemberFromChatRoom](/api/getMemberFromChatRoom)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|  chatRoomId|string|群id|
|
||||
|  members|string|成员id|
|
||||
|  memberNickname|string|成员昵称|
|
||||
|  admin|string|群管理|
|
||||
|  adminNickname|string|管理昵称|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"chatRoomId":"1234@chatroom"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {
|
||||
"admin": "wxid_2222",
|
||||
"adminNickname": "123",
|
||||
"chatRoomId": "22224@chatroom",
|
||||
"memberNickname": "^G123^G^G",
|
||||
"members": "wxid_2222^Gwxid_333"
|
||||
},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
@@ -1,51 +0,0 @@
|
||||
import ctypes
|
||||
import hashlib
|
||||
import hmac
|
||||
|
||||
# pip install pycryptodome
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
|
||||
def decrypt(password, input_file, out_file):
|
||||
password = bytes.fromhex(password.replace(' ', ''))
|
||||
with open(input_file, 'rb') as (f):
|
||||
blist = f.read()
|
||||
print(len(blist))
|
||||
salt = blist[:16]
|
||||
key = hashlib.pbkdf2_hmac('sha1', password, salt, DEFAULT_ITER, KEY_SIZE)
|
||||
first = blist[16:DEFAULT_PAGESIZE]
|
||||
mac_salt = bytes([x ^ 58 for x in salt])
|
||||
mac_key = hashlib.pbkdf2_hmac('sha1', key, mac_salt, 2, KEY_SIZE)
|
||||
hash_mac = hmac.new(mac_key, digestmod='sha1')
|
||||
hash_mac.update(first[:-32])
|
||||
hash_mac.update(bytes(ctypes.c_int(1)))
|
||||
if hash_mac.digest() == first[-32:-12]:
|
||||
print('decrypt success')
|
||||
else:
|
||||
print('password error')
|
||||
return
|
||||
blist = [blist[i:i + DEFAULT_PAGESIZE] for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)]
|
||||
with open(out_file, 'wb') as (f):
|
||||
f.write(SQLITE_FILE_HEADER)
|
||||
t = AES.new(key, AES.MODE_CBC, first[-48:-32])
|
||||
f.write(t.decrypt(first[:-48]))
|
||||
f.write(first[-48:])
|
||||
for i in blist:
|
||||
t = AES.new(key, AES.MODE_CBC, i[-48:-32])
|
||||
f.write(t.decrypt(i[:-48]))
|
||||
f.write(i[-48:])
|
||||
|
||||
|
||||
def main():
|
||||
password = '565735E30E474DA09250CB5AA047E3940FFA1C6F767C4263B13ABB512933DA49'
|
||||
input_file = 'C:/var/Applet.db'
|
||||
out_file = 'c:/var/out/Applet.db'
|
||||
decrypt(password, input_file, out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
SQLITE_FILE_HEADER = bytes('SQLite format 3', encoding='ASCII') + bytes(1)
|
||||
KEY_SIZE = 32
|
||||
DEFAULT_PAGESIZE = 4096
|
||||
DEFAULT_ITER = 64000
|
||||
main()
|
||||
@@ -0,0 +1,26 @@
|
||||
from fastapi import FastAPI, Request
|
||||
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
# pip install fastapi
|
||||
# run command :uvicorn test:app --reload
|
||||
# 127.0.0.1:8000/api
|
||||
|
||||
@app.post("/api")
|
||||
def create_item(request: Request):
|
||||
print("recv msg")
|
||||
return {"code": 0, "msg": "success"}
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def TestCustomMiddleware(request: Request, call_next):
|
||||
the_headers = request.headers
|
||||
the_body = await request.json()
|
||||
|
||||
print(the_headers)
|
||||
print(the_body)
|
||||
|
||||
response = await call_next(request)
|
||||
|
||||
return response
|
||||
@@ -0,0 +1,10 @@
|
||||
### 常用的一些工具
|
||||
|
||||
|
||||
client.py : 快速测试dll的http接口。
|
||||
|
||||
decrpt.py : 微信数据库解密工具。password 为dll个人信息里返回的dbkey。
|
||||
|
||||
http_server.py : 一个简单的http server,用来接收hook的消息。
|
||||
|
||||
tcpserver.py: 一个简单的tcp server,用来接收hook的消息。
|
||||
Submodule
+1
Submodule spdlog added at ad0e89cbfb
+1
-1
@@ -101,7 +101,7 @@ VOID CALLBACK SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
||||
return;
|
||||
}
|
||||
std::string jstr = j_msg.dump() + "\n";
|
||||
// HttpClient::GetInstance().SendRequest(jstr);
|
||||
HttpClient::GetInstance().SendRequest(jstr);
|
||||
}
|
||||
|
||||
void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
||||
|
||||
+158
-65
@@ -29,6 +29,14 @@ std::wstring GetWStringParam(nlohmann::json data, std::string key) {
|
||||
return wxhelper::Utils::UTF8ToWstring(data[key].get<std::string>());
|
||||
}
|
||||
|
||||
std::vector<std::wstring> GetArrayParam(nlohmann::json data, std::string key) {
|
||||
std::vector<std::wstring> result;
|
||||
std::wstring param = GetWStringParam(data, key);
|
||||
result = wxhelper::Utils::split(param, L',');
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void StartHttpServer(wxhelper::HttpServer *server) {
|
||||
int port = server->GetPort();
|
||||
std::string lsten_addr = "http://0.0.0.0:" + std::to_string(port);
|
||||
@@ -123,7 +131,8 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/userInfo")) {
|
||||
common::SelfInfoInner self_info;
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->GetSelfInfo(self_info);
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->GetSelfInfo(self_info);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
if (success) {
|
||||
@@ -148,39 +157,44 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
} else if (mg_http_match_uri(hm, "/api/sendTextMsg")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring msg = GetWStringParam(j_param, "msg");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendTextMsg(wxid, msg);
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->SendTextMsg(wxid, msg);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/hookSyncMsg")) {
|
||||
INT64 success = wxhelper::hooks::HookSyncMsg("127.0.0.1",19099,"",3000,false);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
INT64 success =
|
||||
wxhelper::hooks::HookSyncMsg("127.0.0.1", 19099, "", 3000, false);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendImagesMsg")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring path = GetWStringParam(j_param, "imagePath");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendImageMsg(wxid, path);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendFileMsg")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring path = GetWStringParam(j_param, "filePath");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendFileMsg(wxid, path);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getContactList")) {
|
||||
std::vector<common::ContactInner> vec;
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->GetContacts(vec);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring path = GetWStringParam(j_param, "imagePath");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->SendImageMsg(wxid, path);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendFileMsg")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring path = GetWStringParam(j_param, "filePath");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->SendFileMsg(wxid, path);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getContactList")) {
|
||||
std::vector<common::ContactInner> vec;
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->GetContacts(vec);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||
nlohmann::json item = {
|
||||
{"customAccount", vec[i].custom_account},
|
||||
{"encryptName", vec[i].encrypt_name},
|
||||
@@ -194,19 +208,19 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
{"reserved2", vec[i].reserved2},
|
||||
};
|
||||
ret_data["data"].push_back(item);
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/unhookSyncMsg")) {
|
||||
INT64 success = wxhelper::hooks::UnHookSyncMsg();
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getDBInfo")) {
|
||||
std::vector<void *> v_ptr = wxhelper::DB::GetInstance().GetDbHandles();
|
||||
nlohmann::json ret_data = {{"data", nlohmann::json::array()}};
|
||||
for (unsigned int i = 0; i < v_ptr.size(); i++) {
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/unhookSyncMsg")) {
|
||||
INT64 success = wxhelper::hooks::UnHookSyncMsg();
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getDBInfo")) {
|
||||
std::vector<void *> v_ptr = wxhelper::DB::GetInstance().GetDbHandles();
|
||||
nlohmann::json ret_data = {{"data", nlohmann::json::array()}};
|
||||
for (unsigned int i = 0; i < v_ptr.size(); i++) {
|
||||
nlohmann::json db_info;
|
||||
db_info["tables"] = nlohmann::json::array();
|
||||
common::DatabaseInfo *db =
|
||||
@@ -222,38 +236,117 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
db_info["tables"].push_back(table_info);
|
||||
}
|
||||
ret_data["data"].push_back(db_info);
|
||||
}
|
||||
ret_data["code"] = 1;
|
||||
ret_data["msg"] = "success";
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/execSql")) {
|
||||
UINT64 db_handle = GetINT64Param(j_param, "dbHandle");
|
||||
std::string sql = GetStringParam(j_param, "sql");
|
||||
std::vector<std::vector<std::string>> items;
|
||||
int success = wxhelper::DB::GetInstance().Select(db_handle, sql.c_str(), items);
|
||||
nlohmann::json ret_data = {
|
||||
{"data", nlohmann::json::array()}, {"code", success}, {"msg", "success"}};
|
||||
if (success == 0) {
|
||||
}
|
||||
ret_data["code"] = 1;
|
||||
ret_data["msg"] = "success";
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/execSql")) {
|
||||
UINT64 db_handle = GetINT64Param(j_param, "dbHandle");
|
||||
std::string sql = GetStringParam(j_param, "sql");
|
||||
std::vector<std::vector<std::string>> items;
|
||||
int success =
|
||||
wxhelper::DB::GetInstance().Select(db_handle, sql.c_str(), items);
|
||||
nlohmann::json ret_data = {{"data", nlohmann::json::array()},
|
||||
{"code", success},
|
||||
{"msg", "success"}};
|
||||
if (success == 0) {
|
||||
ret_data["msg"] = "no data";
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
||||
for (auto it : items) {
|
||||
}
|
||||
for (auto it : items) {
|
||||
nlohmann::json temp_arr = nlohmann::json::array();
|
||||
for (size_t i = 0; i < it.size(); i++) {
|
||||
temp_arr.push_back(it[i]);
|
||||
}
|
||||
ret_data["data"].push_back(temp_arr);
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else {
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "not support url"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getChatRoomDetailInfo")) {
|
||||
std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
common::ChatRoomInfoInner chat_room_detail;
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->GetChatRoomDetailInfo(
|
||||
chat_room_id, chat_room_detail);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
|
||||
nlohmann::json detail = {
|
||||
{"chatRoomId", chat_room_detail.chat_room_id},
|
||||
{"notice", chat_room_detail.notice},
|
||||
{"admin", chat_room_detail.admin},
|
||||
{"xml", chat_room_detail.xml},
|
||||
};
|
||||
ret_data["data"] = detail;
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/addMemberToChatRoom")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||
std::vector<std::wstring> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(wxids[i]);
|
||||
}
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->AddMemberToChatRoom(
|
||||
room_id, wxid_list);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/modifyNickname")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring nickName = GetWStringParam(j_param, "nickName");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->ModChatRoomMemberNickName(
|
||||
room_id, wxid, nickName);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/delMemberFromChatRoom")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||
std::vector<std::wstring> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(wxids[i]);
|
||||
}
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->DelMemberFromChatRoom(
|
||||
room_id, wxid_list);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getMemberFromChatRoom")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
common::ChatRoomMemberInner member;
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->GetMemberFromChatRoom(
|
||||
room_id, member);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
if (success >= 0) {
|
||||
nlohmann::json member_info = {
|
||||
{"admin", member.admin},
|
||||
{"chatRoomId", member.chat_room_id},
|
||||
{"members", member.member},
|
||||
{"adminNickname", member.admin_nickname},
|
||||
{"memberNickname", member.member_nickname},
|
||||
};
|
||||
ret_data["data"] = member_info;
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else {
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "not support url"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "unreachable code."}};
|
||||
ret = ret_data.dump();
|
||||
|
||||
+172
-25
@@ -10,6 +10,20 @@ namespace func = wxhelper::V3_9_5_81::function;
|
||||
|
||||
|
||||
namespace wxhelper {
|
||||
|
||||
prototype::WeChatString * BuildWechatString(const std::wstring &ws){
|
||||
prototype::WeChatString *p = Utils::WxHeapAlloc<prototype::WeChatString>(
|
||||
sizeof(prototype::WeChatString));
|
||||
wchar_t *p_chat_room_id = Utils::WxHeapAlloc<wchar_t>((ws.size() + 1) * 2);
|
||||
wmemcpy(p_chat_room_id, ws.c_str(), ws.size() + 1);
|
||||
p->ptr = p_chat_room_id;
|
||||
p->length = static_cast<DWORD>(ws.size());
|
||||
p->max_length = static_cast<DWORD>(ws.size());
|
||||
p->c_len = 0;
|
||||
p->c_ptr = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
Manager::Manager(UINT64 base) : base_addr_(base) {}
|
||||
Manager::~Manager() {}
|
||||
INT64 Manager::CheckLogin() {
|
||||
@@ -251,25 +265,25 @@ INT64 Manager::SendImageMsg(const std::wstring& wxid, const std::wstring& image_
|
||||
return success;
|
||||
}
|
||||
|
||||
// todo bug 9/10
|
||||
|
||||
INT64 Manager::SendFileMsg(const std::wstring& wxid, const std::wstring& file_path){
|
||||
INT64 success = -1;
|
||||
prototype::WeChatString* to_user= (prototype::WeChatString*)HeapAlloc(GetProcessHeap(),0,sizeof(prototype::WeChatString));
|
||||
wchar_t * ptr_wxid = (wchar_t*)HeapAlloc(GetProcessHeap(),0,wxid.length()+1);
|
||||
wchar_t * ptr_wxid = (wchar_t*)HeapAlloc(GetProcessHeap(),0,(wxid.length()+1)*2);
|
||||
wmemcpy(ptr_wxid,wxid.c_str(),wxid.length()+1);
|
||||
to_user->ptr = ptr_wxid;
|
||||
to_user->length = static_cast<DWORD>(wxid.length());
|
||||
to_user->max_length = static_cast<DWORD>(wxid.length());
|
||||
to_user->c_len=0;
|
||||
to_user->c_ptr=0;
|
||||
prototype::WeChatString* image_full_path= (prototype::WeChatString*)HeapAlloc(GetProcessHeap(),0,sizeof(prototype::WeChatString));
|
||||
wchar_t * ptr_path = (wchar_t*)HeapAlloc(GetProcessHeap(),0,file_path.length()+1);
|
||||
prototype::WeChatString* file_full_path= (prototype::WeChatString*)HeapAlloc(GetProcessHeap(),0,sizeof(prototype::WeChatString));
|
||||
wchar_t * ptr_path = (wchar_t*)HeapAlloc(GetProcessHeap(),0,(file_path.length()+1)*2);
|
||||
wmemcpy(ptr_path,file_path.c_str(),file_path.length()+1);
|
||||
image_full_path->ptr = ptr_path;
|
||||
image_full_path->length = static_cast<DWORD>(file_path.length());
|
||||
image_full_path->max_length = static_cast<DWORD>(file_path.length());
|
||||
image_full_path->c_len = 0;
|
||||
image_full_path->c_ptr = 0;
|
||||
file_full_path->ptr = ptr_path;
|
||||
file_full_path->length = static_cast<DWORD>(file_path.length());
|
||||
file_full_path->max_length = static_cast<DWORD>(file_path.length());
|
||||
file_full_path->c_len = 0;
|
||||
file_full_path->c_ptr = 0;
|
||||
|
||||
UINT64 get_app_msg_mgr_addr = base_addr_ + offset::kGetAppMsgMgr;
|
||||
UINT64 send_file_addr = base_addr_ + offset::kSendFileMsg;
|
||||
@@ -293,26 +307,15 @@ INT64 Manager::SendFileMsg(const std::wstring& wxid, const std::wstring& file_pa
|
||||
ZeroMemory(temp3,sizeof(UINT64)*4);
|
||||
ZeroMemory(temp4,sizeof(UINT64)*4);
|
||||
*temp4=0x1F;
|
||||
UINT64 temp5 = 0xC;
|
||||
|
||||
|
||||
|
||||
UINT64 app_mgr = get_app_mgr();
|
||||
// UINT64 p_chat_msg = new_chat_msg(reinterpret_cast<UINT64>(chat_msg));
|
||||
// send_file(app_mgr, p_chat_msg, reinterpret_cast<UINT64>(to_user),
|
||||
// reinterpret_cast<UINT64>(image_full_path), 1,
|
||||
// reinterpret_cast<UINT64>(temp1), 0x300,
|
||||
// reinterpret_cast<UINT64>(temp2), 0,
|
||||
// reinterpret_cast<UINT64>(temp3),
|
||||
// reinterpret_cast<UINT64>(temp4),
|
||||
// temp5);
|
||||
|
||||
send_file(app_mgr, reinterpret_cast<UINT64>(chat_msg),
|
||||
reinterpret_cast<UINT64>(to_user),
|
||||
reinterpret_cast<UINT64>(image_full_path), 1,
|
||||
reinterpret_cast<UINT64>(file_full_path), 1,
|
||||
reinterpret_cast<UINT64>(temp1), 0, reinterpret_cast<UINT64>(temp2),
|
||||
0, reinterpret_cast<UINT64>(temp3), 0, 0x0);
|
||||
0, reinterpret_cast<UINT64>(temp3), 0, 0);
|
||||
free(reinterpret_cast<UINT64>(chat_msg));
|
||||
HeapFree(GetProcessHeap(),0,to_user);
|
||||
HeapFree(GetProcessHeap(),0,file_full_path);
|
||||
HeapFree(GetProcessHeap(),0,temp1);
|
||||
HeapFree(GetProcessHeap(),0,temp2);
|
||||
HeapFree(GetProcessHeap(),0,temp3);
|
||||
@@ -353,4 +356,148 @@ INT64 Manager::GetContacts(std::vector<common::ContactInner> &vec) {
|
||||
}
|
||||
return success;
|
||||
}
|
||||
} // namespace wxhelper`
|
||||
|
||||
INT64 Manager::GetChatRoomDetailInfo(const std::wstring &room_id,
|
||||
common::ChatRoomInfoInner &room_info) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr;
|
||||
UINT64 get_chat_room_detail_addr =
|
||||
base_addr_ + offset::kGetChatRoomDetailInfo;
|
||||
UINT64 new_chat_room_info_addr = base_addr_ + offset::kNewChatRoomInfo;
|
||||
UINT64 free_chat_room_info_addr = base_addr_ + offset::kFreeChatRoomInfo;
|
||||
func::__GetChatRoomMgr get_chat_room_mgr =
|
||||
(func::__GetChatRoomMgr)get_chat_room_mgr_addr;
|
||||
func::__GetChatRoomDetailInfo get_chat_room_detail =
|
||||
(func::__GetChatRoomDetailInfo)get_chat_room_detail_addr;
|
||||
func::__NewChatRoomInfo new_chat_room_info =
|
||||
(func::__NewChatRoomInfo)new_chat_room_info_addr;
|
||||
func::__FreeChatRoomInfo free_chat_room_info =
|
||||
(func::__FreeChatRoomInfo)free_chat_room_info_addr;
|
||||
|
||||
prototype::WeChatString chat_room_id(room_id);
|
||||
char chat_room_info[0x148] = {0};
|
||||
UINT64 p_chat_room_info =
|
||||
new_chat_room_info(reinterpret_cast<UINT64>(&chat_room_info));
|
||||
UINT64 mgr = get_chat_room_mgr();
|
||||
success = get_chat_room_detail(mgr, reinterpret_cast<UINT64>(&chat_room_id),
|
||||
p_chat_room_info, 1);
|
||||
room_info.admin = Utils::ReadWstringThenConvert(p_chat_room_info + 0x48);
|
||||
room_info.chat_room_id =
|
||||
Utils::ReadWstringThenConvert(p_chat_room_info + 0x8);
|
||||
room_info.notice = Utils::ReadWstringThenConvert(p_chat_room_info + 0x28);
|
||||
room_info.xml = Utils::ReadWstringThenConvert(p_chat_room_info + 0x78);
|
||||
free_chat_room_info(p_chat_room_info);
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::AddMemberToChatRoom(const std::wstring &room_id,
|
||||
const std::vector<std::wstring> &members) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr;
|
||||
UINT64 add_members_addr = base_addr_ + offset::kDoAddMemberToChatRoom;
|
||||
func::__GetChatRoomMgr get_chat_room_mgr =
|
||||
(func::__GetChatRoomMgr)get_chat_room_mgr_addr;
|
||||
func::__DoAddMemberToChatRoom add_members =
|
||||
(func::__DoAddMemberToChatRoom)add_members_addr;
|
||||
|
||||
prototype::WeChatString *chat_room_id = (prototype::WeChatString *)HeapAlloc(
|
||||
GetProcessHeap(), 0, sizeof(prototype::WeChatString));
|
||||
wchar_t *p_chat_room_id =
|
||||
(wchar_t *)HeapAlloc(GetProcessHeap(), 0, (room_id.size() + 1) * 2);
|
||||
wmemcpy(p_chat_room_id, room_id.c_str(), room_id.size() + 1);
|
||||
chat_room_id->ptr = p_chat_room_id;
|
||||
chat_room_id->length = static_cast<DWORD>(room_id.size());
|
||||
chat_room_id->max_length = static_cast<DWORD>(room_id.size());
|
||||
chat_room_id->c_len = 0;
|
||||
chat_room_id->c_ptr = 0;
|
||||
|
||||
std::vector<prototype::WeChatString> member_list;
|
||||
UINT64 temp[2] = {0};
|
||||
common::VectorInner *list = (common::VectorInner *)&member_list;
|
||||
INT64 members_ptr = (INT64)&list->start;
|
||||
for (int i = 0; i < members.size(); i++) {
|
||||
prototype::WeChatString member(members[i]);
|
||||
member_list.push_back(member);
|
||||
}
|
||||
UINT64 mgr = get_chat_room_mgr();
|
||||
success =
|
||||
add_members(mgr, members_ptr, reinterpret_cast<UINT64>(chat_room_id),
|
||||
reinterpret_cast<UINT64>(&temp));
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT64 Manager::ModChatRoomMemberNickName(const std::wstring &room_id,
|
||||
const std::wstring &wxid,
|
||||
const std::wstring &nickname) {
|
||||
INT64 success = -1;
|
||||
UINT64 mod_addr = base_addr_ + offset::kDoModChatRoomMemberNickName;
|
||||
func::__DoModChatRoomMemberNickName modify =
|
||||
(func::__DoModChatRoomMemberNickName)mod_addr;
|
||||
const wchar_t *p = room_id.c_str();
|
||||
prototype::WeChatString *chat_room_id = BuildWechatString(room_id);
|
||||
prototype::WeChatString *self_id = BuildWechatString(wxid);
|
||||
prototype::WeChatString *name = BuildWechatString(nickname);
|
||||
success = modify(
|
||||
reinterpret_cast<UINT64>(p), reinterpret_cast<UINT64>(chat_room_id),
|
||||
reinterpret_cast<UINT64>(self_id), reinterpret_cast<UINT64>(name));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::DelMemberFromChatRoom(const std::wstring &room_id,
|
||||
const std::vector<std::wstring> &members) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr;
|
||||
UINT64 del_members_addr = base_addr_ + offset::kDelMemberFromChatRoom;
|
||||
func::__GetChatRoomMgr get_chat_room_mgr =
|
||||
(func::__GetChatRoomMgr)get_chat_room_mgr_addr;
|
||||
func::__DoDelMemberFromChatRoom del_members =
|
||||
(func::__DoDelMemberFromChatRoom)del_members_addr;
|
||||
|
||||
prototype::WeChatString *chat_room_id = BuildWechatString(room_id);
|
||||
std::vector<prototype::WeChatString> member_list;
|
||||
UINT64 temp[2] = {0};
|
||||
common::VectorInner *list = (common::VectorInner *)&member_list;
|
||||
INT64 members_ptr = (INT64)&list->start;
|
||||
for (int i = 0; i < members.size(); i++) {
|
||||
prototype::WeChatString member(members[i]);
|
||||
member_list.push_back(member);
|
||||
}
|
||||
UINT64 mgr = get_chat_room_mgr();
|
||||
success =
|
||||
del_members(mgr, members_ptr, reinterpret_cast<UINT64>(chat_room_id));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::GetMemberFromChatRoom(const std::wstring &room_id,
|
||||
common::ChatRoomMemberInner &member) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr;
|
||||
UINT64 get_members_addr = base_addr_ + offset::kGetMemberFromChatRoom;
|
||||
UINT64 new_chat_room_addr = base_addr_ + offset::kNewChatRoom;
|
||||
UINT64 free_chat_room_addr = base_addr_ + offset::kFreeChatRoom;
|
||||
func::__GetChatRoomMgr get_chat_room_mgr =
|
||||
(func::__GetChatRoomMgr)get_chat_room_mgr_addr;
|
||||
func::__GetMemberFromChatRoom get_members =
|
||||
(func::__GetMemberFromChatRoom)get_members_addr;
|
||||
func::__NewChatRoom new_chat_room = (func::__NewChatRoom)new_chat_room_addr;
|
||||
func::__FreeChatRoom free_chat_room =
|
||||
(func::__FreeChatRoom)free_chat_room_addr;
|
||||
|
||||
prototype::WeChatString chat_room_id(room_id);
|
||||
char chat_room_info[0x2E0] = {0};
|
||||
UINT64 addr = reinterpret_cast<UINT64>(&chat_room_info);
|
||||
new_chat_room(addr);
|
||||
|
||||
UINT64 mgr = get_chat_room_mgr();
|
||||
success = get_members(mgr, reinterpret_cast<UINT64>(&chat_room_id), addr);
|
||||
member.chat_room_id = Utils::ReadWstringThenConvert(addr + 0x10);
|
||||
member.admin = Utils::ReadWstringThenConvert(addr + 0x78);
|
||||
member.member_nickname = Utils::ReadWstringThenConvert(addr + 0x50);
|
||||
member.admin_nickname = Utils::ReadWstringThenConvert(addr + 0xA0);
|
||||
member.member = Utils::ReadWeChatStr(addr + 0x30);
|
||||
free_chat_room(addr);
|
||||
return success;
|
||||
}
|
||||
} // namespace wxhelper
|
||||
@@ -13,6 +13,19 @@ class Manager {
|
||||
INT64 SendImageMsg(const std::wstring& wxid, const std::wstring& image_path);
|
||||
INT64 SendFileMsg(const std::wstring& wxid, const std::wstring& file_path);
|
||||
INT64 GetContacts(std::vector<common::ContactInner> &vec);
|
||||
INT64 GetChatRoomDetailInfo(const std::wstring& room_id,
|
||||
common::ChatRoomInfoInner& room_info);
|
||||
INT64 AddMemberToChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& members);
|
||||
|
||||
INT64 ModChatRoomMemberNickName(const std::wstring& room_id,
|
||||
const std::wstring& wxid,
|
||||
const std::wstring& nickname);
|
||||
INT64 DelMemberFromChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& members);
|
||||
INT64 GetMemberFromChatRoom(const std::wstring& room_id,
|
||||
common::ChatRoomMemberInner& member);
|
||||
|
||||
private:
|
||||
UINT64 base_addr_;
|
||||
};
|
||||
|
||||
+11
-4
@@ -46,9 +46,9 @@ class Utils {
|
||||
|
||||
static std::string WCharToUTF8(wchar_t *wstr);
|
||||
|
||||
static bool IsTextUtf8(const char * str,INT64 length) ;
|
||||
static bool IsTextUtf8(const char *str, INT64 length);
|
||||
|
||||
static void Hide(HMODULE module);
|
||||
static void Hide(HMODULE module);
|
||||
|
||||
static std::string ReadSKBuiltinString(INT64 addr);
|
||||
static std::string ReadSKBuiltinBuffer(INT64 addr);
|
||||
@@ -57,8 +57,9 @@ class Utils {
|
||||
static std::string ImageXor(std::string buf);
|
||||
static std::wstring ReadWstring(INT64 addr);
|
||||
static std::string ReadWstringThenConvert(INT64 addr);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static std::vector<T1> split(T1 str, T2 letter) {
|
||||
static std::vector<T1> split(T1 str, T2 letter) {
|
||||
std::vector<T1> arr;
|
||||
size_t pos;
|
||||
while ((pos = str.find_first_of(letter)) != T1::npos) {
|
||||
@@ -71,7 +72,7 @@ class Utils {
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static T1 replace(T1 source, T2 replaced, T1 replaceto) {
|
||||
static T1 replace(T1 source, T2 replaced, T1 replaceto) {
|
||||
std::vector<T1> v_arr = split(source, replaced);
|
||||
if (v_arr.size() < 2) return source;
|
||||
T1 temp;
|
||||
@@ -82,6 +83,12 @@ class Utils {
|
||||
temp += v_arr[v_arr.size() - 1];
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T *WxHeapAlloc(size_t n) {
|
||||
return (T *)HeapAlloc(GetProcessHeap(), 0, n);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace wxhelper
|
||||
#endif
|
||||
+74
-14
@@ -161,6 +161,43 @@ struct ContactInner {
|
||||
}
|
||||
};
|
||||
|
||||
struct ChatRoomInfoInner {
|
||||
std::string chat_room_id;
|
||||
std::string notice;
|
||||
std::string admin;
|
||||
std::string xml;
|
||||
ChatRoomInfoInner(){
|
||||
chat_room_id = "";
|
||||
notice = "";
|
||||
admin = "";
|
||||
xml = "";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct VectorInner {
|
||||
#ifdef _DEBUG
|
||||
INT64 head;
|
||||
#endif
|
||||
INT64 start;
|
||||
INT64 finsh;
|
||||
INT64 end;
|
||||
};
|
||||
|
||||
struct ChatRoomMemberInner {
|
||||
std::string chat_room_id;
|
||||
std::string admin;
|
||||
std::string admin_nickname;
|
||||
std::string member_nickname;
|
||||
std::string member;
|
||||
ChatRoomMemberInner()
|
||||
: chat_room_id(""),
|
||||
admin(""),
|
||||
admin_nickname(""),
|
||||
member_nickname(""),
|
||||
member("") {}
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
namespace V3_9_5_81 {
|
||||
namespace function {
|
||||
@@ -184,6 +221,19 @@ typedef UINT64(*__Free)();
|
||||
typedef UINT64 (*__GetContactMgr)();
|
||||
typedef UINT64 (*__GetContactList)(UINT64,UINT64);
|
||||
|
||||
typedef UINT64 (*__GetChatRoomMgr)();
|
||||
typedef UINT64 (*__NewChatRoomInfo)(UINT64);
|
||||
typedef UINT64 (*__FreeChatRoomInfo)(UINT64);
|
||||
typedef UINT64 (*__GetChatRoomDetailInfo)(UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__DoAddMemberToChatRoom)(UINT64,UINT64,UINT64,UINT64);
|
||||
|
||||
typedef UINT64 (*__DoModChatRoomMemberNickName)(UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__DoDelMemberFromChatRoom)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__GetMemberFromChatRoom)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__NewChatRoom)(UINT64);
|
||||
typedef UINT64 (*__FreeChatRoom)(UINT64);
|
||||
|
||||
|
||||
} // namespace function
|
||||
namespace prototype {
|
||||
|
||||
@@ -254,21 +304,31 @@ const UINT64 k_sqlite3_column_blob = 0x24f2ba0;
|
||||
const UINT64 k_sqlite3_column_bytes = 0x24f2c90;
|
||||
const UINT64 k_sqlite3_finalize = 0x24f1400;
|
||||
|
||||
const UINT64 kGPInstance = 0x3a6f908;
|
||||
const UINT64 kMicroMsgDB= 0xb8;
|
||||
const UINT64 kChatMsgDB = 0x2c8;
|
||||
const UINT64 kMiscDB = 0x5f0;
|
||||
const UINT64 kEmotionDB = 0x838;
|
||||
const UINT64 kMediaDB = 0xef8;
|
||||
const UINT64 kBizchatMsgDB = 0x1a70;
|
||||
const UINT64 kFunctionMsgDB = 0x1b48;
|
||||
const UINT64 kDBName = 0x28;
|
||||
const UINT64 kStorageStart = 0x0;
|
||||
const UINT64 kStorageEnd= 0x0;
|
||||
const UINT64 kMultiDBMgr= 0x3acfb68;
|
||||
const UINT64 kPublicMsgMgr= 0x3acc268;
|
||||
const UINT64 kFavoriteStorageMgr= 0x3acf0d0;
|
||||
const UINT64 kGPInstance = 0x3a6f908;
|
||||
const UINT64 kMicroMsgDB = 0xb8;
|
||||
const UINT64 kChatMsgDB = 0x2c8;
|
||||
const UINT64 kMiscDB = 0x5f0;
|
||||
const UINT64 kEmotionDB = 0x838;
|
||||
const UINT64 kMediaDB = 0xef8;
|
||||
const UINT64 kBizchatMsgDB = 0x1a70;
|
||||
const UINT64 kFunctionMsgDB = 0x1b48;
|
||||
const UINT64 kDBName = 0x28;
|
||||
const UINT64 kStorageStart = 0x0;
|
||||
const UINT64 kStorageEnd = 0x0;
|
||||
const UINT64 kMultiDBMgr = 0x3acfb68;
|
||||
const UINT64 kPublicMsgMgr = 0x3acc268;
|
||||
const UINT64 kFavoriteStorageMgr = 0x3acf0d0;
|
||||
|
||||
const UINT64 kChatRoomMgr = 0x8e9d30;
|
||||
const UINT64 kGetChatRoomDetailInfo = 0xe73590;
|
||||
const UINT64 kNewChatRoomInfo = 0x12006b0;
|
||||
const UINT64 kFreeChatRoomInfo = 0x1200890;
|
||||
const UINT64 kDoAddMemberToChatRoom = 0xe63c70;
|
||||
const UINT64 kDoModChatRoomMemberNickName = 0xe6db00;
|
||||
const UINT64 kDelMemberFromChatRoom = 0xe64290;
|
||||
const UINT64 kGetMemberFromChatRoom = 0xe74de0;
|
||||
const UINT64 kNewChatRoom = 0x11fde50;
|
||||
const UINT64 kFreeChatRoom = 0x11fe030;
|
||||
} // namespace offset
|
||||
} // namespace V3_9_5_81
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1 +1,14 @@
|
||||
## 可以使用对应分支下的注入工具,或者自己编译一下 source目录下的注入程序。
|
||||
|
||||
1.ConsoleApplication.exe
|
||||
编译好的x64版本的注入器
|
||||
命令行注入工具,注入命令
|
||||
``` javascript
|
||||
//-i 注入程序名 -p 注入dll路径
|
||||
// -u 卸载程序名 -d 卸载dll名称
|
||||
//注入
|
||||
ConsoleInject.exe -i demo.exe -p E:\wxhelper.dll
|
||||
//卸载
|
||||
ConsoleInject.exe -u demo.exe -d wxhelper.dll
|
||||
|
||||
```
|
||||
Binary file not shown.
Reference in New Issue
Block a user