Compare commits
17
Commits
tool
..
3.9.2.26-v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
581aacb8ce | ||
|
|
dccc997067 | ||
|
|
0b52a49155 | ||
|
|
4027c4afe6 | ||
|
|
dcbde9203b | ||
|
|
76dc8affe9 | ||
|
|
fd3e6f4a70 | ||
|
|
18e34cd11b | ||
|
|
83d779c072 | ||
|
|
8fa942c741 | ||
|
|
c0b55da015 | ||
|
|
34eb14edb2 | ||
|
|
f9a7924658 | ||
|
|
6105789fcc | ||
|
|
dffdbfb9d7 | ||
|
|
8279303614 | ||
|
|
5ba4f72d5c |
@@ -1,38 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
+2
-2
@@ -30,6 +30,6 @@
|
||||
#*.exe
|
||||
*.out
|
||||
*.app
|
||||
/out
|
||||
CMakePresets.json
|
||||
.vscode
|
||||
out
|
||||
.vscode
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "spdlog"]
|
||||
path = spdlog
|
||||
url = https://github.com/gabime/spdlog
|
||||
+11
-5
@@ -1,25 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
# include(ExternalProject)
|
||||
project(wxhelper VERSION 1.0.0)
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D '_UNICODE' /D 'UNICODE'")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D '_UNICODE' /D 'UNICODE' ")
|
||||
|
||||
file(GLOB CPP_FILES ${PROJECT_SOURCE_DIR}/src/*.cc ${PROJECT_SOURCE_DIR}/src/*.cpp)
|
||||
|
||||
|
||||
|
||||
include_directories(c:/soft/vcpkg/installed/x86-windows/include)
|
||||
include_directories(${VCPKG_INSTALLED_DIR}/x86-windows/include ${PROJECT_SOURCE_DIR}/spdlog/include)
|
||||
|
||||
# add_subdirectory(3rd)
|
||||
|
||||
|
||||
add_subdirectory(spdlog)
|
||||
# add_subdirectory(source)
|
||||
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(unofficial-mongoose CONFIG REQUIRED)
|
||||
# find_package(spdlog CONFIG REQUIRED)
|
||||
# find_package(minhook CONFIG REQUIRED)
|
||||
|
||||
|
||||
|
||||
add_library(wxhelper SHARED ${CPP_FILES} )
|
||||
@@ -29,7 +34,8 @@ add_library(wxhelper SHARED ${CPP_FILES} )
|
||||
|
||||
target_link_libraries(wxhelper PRIVATE nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(wxhelper PRIVATE unofficial::mongoose::mongoose)
|
||||
# target_link_libraries(wxhelper PRIVATE spdlog::spdlog spdlog::spdlog_header_only)
|
||||
target_link_libraries(wxhelper PRIVATE spdlog::spdlog spdlog::spdlog_header_only)
|
||||
|
||||
# target_link_libraries(wxhelper PRIVATE minhook::minhook)
|
||||
|
||||
SET_TARGET_PROPERTIES(wxhelper PROPERTIES LINKER_LANGUAGE C
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 ttttupup
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+2
-1
@@ -635,6 +635,7 @@
|
||||
|---|---|---|---|
|
||||
|v3 |true |string| 添加好友消息内容里的encryptusername|
|
||||
|v4 |true |string| 添加好友消息内容里的ticket|
|
||||
|permission |true |number| 好友权限,0.全部 8.仅聊天。(好友超过5000人后,会验证权限,传8即可)|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
@@ -1626,4 +1627,4 @@ https://github.com/ljc545w/ComWeChatRobot
|
||||
|
||||
https://github.com/NationalSecurityAgency/ghidra
|
||||
|
||||
https://github.com/x64dbg/x64dbg
|
||||
https://github.com/x64dbg/x64dbg
|
||||
@@ -0,0 +1,36 @@
|
||||
## 3.9.2.26版本,预览功能没有的接口,不能使用,文档仅供参考。
|
||||
#### 功能预览:
|
||||
0.检查是否登录
|
||||
1.获取登录微信信息
|
||||
2.发送文本
|
||||
3.发送@文本
|
||||
5.发送图片
|
||||
6.发送文件
|
||||
9.hook消息
|
||||
10.取消hook消息
|
||||
19.通过手机或qq查找微信
|
||||
20.通过wxid添加好友
|
||||
23.通过好友申请
|
||||
25.获取群成员
|
||||
26.获取群成员昵称
|
||||
27.删除群成员
|
||||
28.增加群成员
|
||||
31.修改群昵称
|
||||
32.获取数据库句柄
|
||||
34.查询数据库
|
||||
35.hook日志
|
||||
36.关闭hook日志
|
||||
40.转发消息
|
||||
44.退出登录
|
||||
46.联系人列表
|
||||
47.获取群详情
|
||||
48.获取解密图片
|
||||
49.图片提取文字ocr
|
||||
50.拍一拍
|
||||
51.群消息置顶消息
|
||||
52.群消息取消置顶
|
||||
53.朋友圈首页
|
||||
54.朋友圈下一页
|
||||
55.获取联系人或者群名称
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
57.获取消息语音文件
|
||||
@@ -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()
|
||||
@@ -771,6 +771,128 @@ error:
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDllAndStartHttpByPid(unsigned int pid, wchar_t* szDllPath, DWORD port)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread = NULL;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr = NULL;
|
||||
HINSTANCE__* hKernelModule = NULL;
|
||||
LPVOID lpRemoteDllBase = NULL;
|
||||
HANDLE hProcess;
|
||||
size_t ulDllLength;
|
||||
wchar_t* dllName = (wchar_t*)L"wxhelper.dll";
|
||||
size_t dllNameLen = wcslen(dllName) * 2 + 2;
|
||||
char* funcName = (char* )"http_start";
|
||||
size_t funcNameLen = strlen(funcName) + 1;
|
||||
|
||||
HANDLE hStartHttp = NULL;
|
||||
LPVOID portAddr = NULL;
|
||||
HANDLE getProcThread = NULL;
|
||||
|
||||
LPVOID paramsAddr = NULL;
|
||||
LPVOID param1Addr = NULL;
|
||||
LPVOID param2Addr = NULL;
|
||||
LPVOID GetProcFuncAddr = NULL;
|
||||
|
||||
DWORD params[2] = { 0 };
|
||||
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
if (!hProcess) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
GetProcFuncAddr = FillAsmCode(hProcess);
|
||||
param1Addr = VirtualAllocEx(hProcess, NULL, dllNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param1Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param1Addr, dllName, dllNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
param2Addr = VirtualAllocEx(hProcess, NULL, funcNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param2Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param2Addr, funcName, funcNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
params[0] = (DWORD)param1Addr;
|
||||
params[1] = (DWORD)param2Addr;
|
||||
|
||||
paramsAddr = VirtualAllocEx(hProcess, NULL, sizeof(params), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (paramsAddr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)paramsAddr, ¶ms[0], sizeof(params), &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwRet = 0;
|
||||
getProcThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcFuncAddr, paramsAddr, 0, NULL);
|
||||
|
||||
if (getProcThread)
|
||||
{
|
||||
WaitForSingleObject(getProcThread, INFINITE);
|
||||
GetExitCodeThread(getProcThread, &dwRet);
|
||||
if (dwRet) {
|
||||
hStartHttp = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)dwRet, (LPVOID)port, 0, NULL);
|
||||
WaitForSingleObject(hStartHttp, INFINITE);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
if (hRemoteThread) {
|
||||
CloseHandle(hRemoteThread);
|
||||
}
|
||||
if (getProcThread) {
|
||||
CloseHandle(getProcThread);
|
||||
}
|
||||
if (hStartHttp) {
|
||||
CloseHandle(hStartHttp);
|
||||
}
|
||||
|
||||
if (lpRemoteDllBase) {
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
if (param1Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, dllNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (param2Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, funcNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (paramsAddr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, sizeof(params), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (GetProcFuncAddr) {
|
||||
VirtualFreeEx(hProcess, GetProcFuncAddr, sizeof(GetProcAddressAsmCode), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
@@ -825,6 +947,58 @@ int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDllByPid(unsigned int pid, wchar_t* szDllPath)
|
||||
{
|
||||
if(!EnableDebugPrivilege()){
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr;
|
||||
HINSTANCE__* hKernelModule;
|
||||
LPVOID lpRemoteDllBase;
|
||||
HANDLE hProcess;
|
||||
size_t ulDllLength;
|
||||
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||||
if (!hProcess) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hRemoteThread);
|
||||
CloseHandle(hProcess);
|
||||
OutputDebugStringA("[DBG] dll inject success");
|
||||
printf("dll inject success");
|
||||
printf("dll path : %s ", szDllPath);
|
||||
printf("pid : %d ", pid);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int UnInjectDll(wchar_t* szPName, wchar_t* szDName)
|
||||
{
|
||||
HMODULE hDll;
|
||||
@@ -878,8 +1052,9 @@ int main(int argc, char** argv)
|
||||
int port = 0;
|
||||
|
||||
ULONG pid = 0;
|
||||
unsigned int injectPid =0;
|
||||
|
||||
while ((param = getopt(argc, argv, "i:p:u:d:m:P:h")) != -1)
|
||||
while ((param = getopt(argc, argv, "i:p:u:d:m:P:I:h")) != -1)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
@@ -916,6 +1091,9 @@ int main(int argc, char** argv)
|
||||
case 'P':
|
||||
port = std::atoi(optarg);
|
||||
break;
|
||||
case 'I':
|
||||
injectPid = std::atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
@@ -925,6 +1103,24 @@ int main(int argc, char** argv)
|
||||
if (pid) {
|
||||
FindHandles(pid, (LPSTR)"_WeChat_App_Instance_Identity_Mutex_Name", TRUE, TRUE);
|
||||
}
|
||||
if (injectPid != 0 && cDllPath[0] != 0)
|
||||
{
|
||||
if(cDllPath[0] != '\0')
|
||||
{
|
||||
if (port == 0) {
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDllByPid(injectPid, (wchar_t*)wsPath.c_str());
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDllAndStartHttpByPid(injectPid, (wchar_t*)wsPath.c_str(), port);
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cInjectprogram[0] != 0 && cDllPath[0] != 0)
|
||||
{
|
||||
|
||||
@@ -1,956 +0,0 @@
|
||||
// ConsoleApplication.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
// https://github.com/yihleego/handle-tools
|
||||
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include "getopt.h"
|
||||
#include <string>
|
||||
|
||||
#include "ntstatus.h"
|
||||
|
||||
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
|
||||
bool endsWith(const std::string& str, const std::string suffix) {
|
||||
if (suffix.length() > str.length()) { return false; }
|
||||
return (str.rfind(suffix) == (str.length() - suffix.length()));
|
||||
}
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, * PUNICODE_STRING;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE {
|
||||
PVOID Object;
|
||||
HANDLE UniqueProcessId;
|
||||
HANDLE HandleValue;
|
||||
ULONG GrantedAccess;
|
||||
USHORT CreatorBackTraceIndex;
|
||||
USHORT ObjectTypeIndex;
|
||||
ULONG HandleAttributes;
|
||||
ULONG Reserved;
|
||||
} SYSTEM_HANDLE, * PSYSTEM_HANDLE;
|
||||
|
||||
typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
|
||||
ULONG_PTR HandleCount;
|
||||
ULONG_PTR Reserved;
|
||||
SYSTEM_HANDLE Handles[1];
|
||||
} SYSTEM_HANDLE_INFORMATION_EX, * PSYSTEM_HANDLE_INFORMATION_EX;
|
||||
|
||||
typedef struct _OBJECT_BASIC_INFORMATION {
|
||||
ULONG Attributes;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
ULONG HandleCount;
|
||||
ULONG PointerCount;
|
||||
ULONG PagedPoolCharge;
|
||||
ULONG NonPagedPoolCharge;
|
||||
ULONG Reserved[3];
|
||||
ULONG NameInfoSize;
|
||||
ULONG TypeInfoSize;
|
||||
ULONG SecurityDescriptorSize;
|
||||
LARGE_INTEGER CreationTime;
|
||||
} OBJECT_BASIC_INFORMATION, * POBJECT_BASIC_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_NAME_INFORMATION {
|
||||
UNICODE_STRING Name;
|
||||
} OBJECT_NAME_INFORMATION, * POBJECT_NAME_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_TYPE_INFORMATION {
|
||||
UNICODE_STRING TypeName;
|
||||
ULONG Reserved[22]; // reserved for internal use
|
||||
} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION;
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION
|
||||
SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
|
||||
SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION
|
||||
SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION
|
||||
SystemPathInformation, // not implemented
|
||||
SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
|
||||
SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION
|
||||
SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION
|
||||
SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
|
||||
SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION
|
||||
SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10
|
||||
SystemModuleInformation, // q: RTL_PROCESS_MODULES
|
||||
SystemLocksInformation, // q: RTL_PROCESS_LOCKS
|
||||
SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES
|
||||
SystemPagedPoolInformation, // not implemented
|
||||
SystemNonPagedPoolInformation, // not implemented
|
||||
SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION
|
||||
SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION
|
||||
SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION
|
||||
SystemVdmInstemulInformation, // q: SYSTEM_VDM_INSTEMUL_INFO
|
||||
SystemVdmBopInformation, // not implemented // 20
|
||||
SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache)
|
||||
SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION
|
||||
SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION
|
||||
SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege)
|
||||
SystemFullMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION
|
||||
SystemLoadGdiDriverInformation, // s (kernel-mode only)
|
||||
SystemUnloadGdiDriverInformation, // s (kernel-mode only)
|
||||
SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege)
|
||||
SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION
|
||||
SystemMirrorMemoryInformation, // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30
|
||||
SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS)
|
||||
SystemObsolete0, // not implemented
|
||||
SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION
|
||||
SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege)
|
||||
SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION
|
||||
SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION
|
||||
SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege)
|
||||
SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only
|
||||
SystemPrioritySeperation, // s (requires SeTcbPrivilege)
|
||||
SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40
|
||||
SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege)
|
||||
SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION
|
||||
SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION
|
||||
SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION
|
||||
SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION
|
||||
SystemTimeSlipNotification, // s: HANDLE (NtCreateEvent) (requires SeSystemtimePrivilege)
|
||||
SystemSessionCreate, // not implemented
|
||||
SystemSessionDetach, // not implemented
|
||||
SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION)
|
||||
SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50
|
||||
SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege)
|
||||
SystemVerifierThunkExtend, // s (kernel-mode only)
|
||||
SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION
|
||||
SystemLoadGdiDriverInSystemSpace, // s: SYSTEM_GDI_DRIVER_INFORMATION (kernel-mode only) (same as SystemLoadGdiDriverInformation)
|
||||
SystemNumaProcessorMap, // q: SYSTEM_NUMA_INFORMATION
|
||||
SystemPrefetcherInformation, // q; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation
|
||||
SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION
|
||||
SystemRecommendedSharedDataAlignment, // q: ULONG // KeGetRecommendedSharedDataAlignment
|
||||
SystemComPlusPackage, // q; s: ULONG
|
||||
SystemNumaAvailableMemory, // q: SYSTEM_NUMA_INFORMATION // 60
|
||||
SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION
|
||||
SystemEmulationBasicInformation, // q: SYSTEM_BASIC_INFORMATION
|
||||
SystemEmulationProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION
|
||||
SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX
|
||||
SystemLostDelayedWriteInformation, // q: ULONG
|
||||
SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION
|
||||
SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION
|
||||
SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
|
||||
SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION
|
||||
SystemObjectSecurityMode, // q: ULONG // 70
|
||||
SystemWatchdogTimerHandler, // s: SYSTEM_WATCHDOG_HANDLER_INFORMATION // (kernel-mode only)
|
||||
SystemWatchdogTimerInformation, // q: SYSTEM_WATCHDOG_TIMER_INFORMATION // (kernel-mode only)
|
||||
SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION
|
||||
SystemWow64SharedInformationObsolete, // not implemented
|
||||
SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only)
|
||||
SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION
|
||||
SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX
|
||||
SystemVerifierTriageInformation, // not implemented
|
||||
SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation
|
||||
SystemMemoryListInformation, // q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80
|
||||
SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation)
|
||||
SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege)
|
||||
SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[]
|
||||
SystemVerifierCancellationInformation, // SYSTEM_VERIFIER_CANCELLATION_INFORMATION // name:wow64:whNT32QuerySystemVerifierCancellationInformation
|
||||
SystemProcessorPowerInformationEx, // not implemented
|
||||
SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation
|
||||
SystemSpecialPoolInformation, // q; s: SYSTEM_SPECIAL_POOL_INFORMATION (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0
|
||||
SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION
|
||||
SystemErrorPortInformation, // s (requires SeTcbPrivilege)
|
||||
SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90
|
||||
SystemHypervisorInformation, // q: SYSTEM_HYPERVISOR_QUERY_INFORMATION
|
||||
SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX
|
||||
SystemTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege)
|
||||
SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege)
|
||||
SystemCoverageInformation, // q: COVERAGE_MODULES s: COVERAGE_MODULE_REQUEST // ExpCovQueryInformation (requires SeDebugPrivilege)
|
||||
SystemPrefetchPatchInformation, // SYSTEM_PREFETCH_PATCH_INFORMATION
|
||||
SystemVerifierFaultsInformation, // s: SYSTEM_VERIFIER_FAULTS_INFORMATION (requires SeDebugPrivilege)
|
||||
SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION
|
||||
SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION
|
||||
SystemProcessorPerformanceDistribution, // q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION // 100
|
||||
SystemNumaProximityNodeInformation, // q; s: SYSTEM_NUMA_PROXIMITY_MAP
|
||||
SystemDynamicTimeZoneInformation, // q; s: RTL_DYNAMIC_TIME_ZONE_INFORMATION (requires SeTimeZonePrivilege)
|
||||
SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation
|
||||
SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION
|
||||
SystemProcessorBrandString, // q: CHAR[] // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23
|
||||
SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation
|
||||
SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship
|
||||
SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[]
|
||||
SystemStoreInformation, // q; s: SYSTEM_STORE_INFORMATION (requires SeProfileSingleProcessPrivilege) // SmQueryStoreInformation
|
||||
SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110
|
||||
SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege)
|
||||
SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION
|
||||
SystemCpuQuotaInformation, // q; s: PS_CPU_QUOTA_QUERY_INFORMATION
|
||||
SystemNativeBasicInformation, // q: SYSTEM_BASIC_INFORMATION
|
||||
SystemErrorPortTimeouts, // SYSTEM_ERROR_PORT_TIMEOUTS
|
||||
SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION
|
||||
SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation
|
||||
SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION
|
||||
SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool)
|
||||
SystemSystemPtesInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120
|
||||
SystemNodeDistanceInformation,
|
||||
SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26
|
||||
SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation
|
||||
SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1
|
||||
SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8
|
||||
SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only)
|
||||
SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION
|
||||
SystemBadPageInformation,
|
||||
SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA
|
||||
SystemCombinePhysicalMemoryInformation, // s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130
|
||||
SystemEntropyInterruptTimingInformation, // q; s: SYSTEM_ENTROPY_TIMING_INFORMATION
|
||||
SystemConsoleInformation, // q: SYSTEM_CONSOLE_INFORMATION
|
||||
SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION (requires SeTcbPrivilege)
|
||||
SystemPolicyInformation, // q: SYSTEM_POLICY_INFORMATION
|
||||
SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION
|
||||
SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION
|
||||
SystemDeviceDataEnumerationInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION
|
||||
SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION
|
||||
SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION
|
||||
SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140
|
||||
SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE
|
||||
SystemCriticalProcessErrorLogInformation,
|
||||
SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION
|
||||
SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX
|
||||
SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION
|
||||
SystemEntropyInterruptTimingRawInformation,
|
||||
SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION
|
||||
SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin)
|
||||
SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX
|
||||
SystemBootMetadataInformation, // 150
|
||||
SystemSoftRebootInformation, // q: ULONG
|
||||
SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION
|
||||
SystemOfflineDumpConfigInformation, // q: OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2
|
||||
SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION
|
||||
SystemRegistryReconciliationInformation, // s: NULL (requires admin) (flushes registry hives)
|
||||
SystemEdidInformation, // q: SYSTEM_EDID_INFORMATION
|
||||
SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD
|
||||
SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION
|
||||
SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION
|
||||
SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160
|
||||
SystemVmGenerationCountInformation,
|
||||
SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION
|
||||
SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS
|
||||
SystemCodeIntegrityPolicyInformation, // q: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION
|
||||
SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION
|
||||
SystemHardwareSecurityTestInterfaceResultsInformation,
|
||||
SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION
|
||||
SystemAllowedCpuSetsInformation,
|
||||
SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation)
|
||||
SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170
|
||||
SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION
|
||||
SystemCodeIntegrityPolicyFullInformation,
|
||||
SystemAffinitizedInterruptProcessorInformation, // (requires SeIncreaseBasePriorityPrivilege)
|
||||
SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION
|
||||
SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2
|
||||
SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION
|
||||
SystemWin32WerStartCallout,
|
||||
SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION
|
||||
SystemCodeIntegrityPlatformManifestInformation, // q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE
|
||||
SystemInterruptSteeringInformation, // SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT // 180
|
||||
SystemSupportedProcessorArchitectures, // in: HANDLE, out: SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION[] (Max 5 structs) // NtQuerySystemInformationEx
|
||||
SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION
|
||||
SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
|
||||
SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2
|
||||
SystemControlFlowTransition,
|
||||
SystemKernelDebuggingAllowed, // s: ULONG
|
||||
SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE
|
||||
SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS
|
||||
SystemCodeIntegrityPoliciesFullInformation,
|
||||
SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190
|
||||
SystemIntegrityQuotaInformation,
|
||||
SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION
|
||||
SystemProcessorIdleMaskInformation, // q: ULONG_PTR // since REDSTONE3
|
||||
SystemSecureDumpEncryptionInformation,
|
||||
SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
|
||||
SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION
|
||||
SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4
|
||||
SystemFirmwareBootPerformanceInformation,
|
||||
SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION
|
||||
SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200
|
||||
SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above.
|
||||
SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION
|
||||
SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION
|
||||
SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5
|
||||
SystemCodeIntegrityUnlockModeInformation,
|
||||
SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION
|
||||
SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION
|
||||
SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1
|
||||
SystemCodeIntegritySyntheticCacheInformation,
|
||||
SystemFeatureConfigurationInformation, // SYSTEM_FEATURE_CONFIGURATION_INFORMATION // since 20H1 // 210
|
||||
SystemFeatureConfigurationSectionInformation, // SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION
|
||||
SystemFeatureUsageSubscriptionInformation, // SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS
|
||||
SystemSecureSpeculationControlInformation, // SECURE_SPECULATION_CONTROL_INFORMATION
|
||||
SystemSpacesBootInformation, // since 20H2
|
||||
SystemFwRamdiskInformation, // SYSTEM_FIRMWARE_RAMDISK_INFORMATION
|
||||
SystemWheaIpmiHardwareInformation,
|
||||
SystemDifSetRuleClassInformation,
|
||||
SystemDifClearRuleClassInformation,
|
||||
SystemDifApplyPluginVerificationOnDriver,
|
||||
SystemDifRemovePluginVerificationOnDriver, // 220
|
||||
SystemShadowStackInformation, // SYSTEM_SHADOW_STACK_INFORMATION
|
||||
SystemBuildVersionInformation, // SYSTEM_BUILD_VERSION_INFORMATION
|
||||
SystemPoolLimitInformation, // SYSTEM_POOL_LIMIT_INFORMATION
|
||||
SystemCodeIntegrityAddDynamicStore,
|
||||
SystemCodeIntegrityClearDynamicStores,
|
||||
SystemDifPoolTrackingInformation,
|
||||
SystemPoolZeroingInformation, // SYSTEM_POOL_ZEROING_INFORMATION
|
||||
MaxSystemInfoClass
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation = 0, // q: OBJECT_BASIC_INFORMATION
|
||||
ObjectNameInformation = 1, // q: OBJECT_NAME_INFORMATION
|
||||
ObjectTypeInformation = 2, // q: OBJECT_TYPE_INFORMATION
|
||||
ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION
|
||||
ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
|
||||
ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege)
|
||||
ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege)
|
||||
MaxObjectInfoClass
|
||||
} OBJECT_INFORMATION_CLASS;
|
||||
|
||||
typedef NTSTATUS(WINAPI* PNtQuerySystemInformation)(
|
||||
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||
_Inout_ PVOID SystemInformation,
|
||||
_In_ ULONG SystemInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
|
||||
typedef NTSTATUS(WINAPI* PNtQueryObject)(
|
||||
_In_opt_ HANDLE Handle,
|
||||
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
||||
_Out_opt_ PVOID ObjectInformation,
|
||||
_In_ ULONG ObjectInformationLength,
|
||||
_Out_opt_ PULONG ReturnLength);
|
||||
|
||||
typedef NTSTATUS(WINAPI* PNtDuplicateObject)(
|
||||
_In_ HANDLE SourceProcessHandle,
|
||||
_In_ HANDLE SourceHandle,
|
||||
_In_opt_ HANDLE TargetProcessHandle,
|
||||
_Out_opt_ PHANDLE TargetHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ ULONG HandleAttributes,
|
||||
_In_ ULONG Options
|
||||
);
|
||||
|
||||
int FindHandles(ULONG pid, LPSTR handleName, BOOL closeHandle, BOOL suffix) {
|
||||
HMODULE ntdll = GetModuleHandle(TEXT("ntdll.dll"));
|
||||
if (NULL == ntdll) {
|
||||
printf("Failed to load 'ntdll.dll'\n");
|
||||
return 0;
|
||||
}
|
||||
PNtQuerySystemInformation pQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation");
|
||||
PNtQueryObject pQueryObject = (PNtQueryObject)GetProcAddress(ntdll, "NtQueryObject");
|
||||
PNtDuplicateObject pDuplicateObject = (PNtDuplicateObject)GetProcAddress(ntdll, "NtDuplicateObject");
|
||||
if (NULL == pQuerySystemInformation || NULL == pQueryObject || NULL == pDuplicateObject) {
|
||||
printf("Failed to call 'GetProcAddress()'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG len = 0x10000;
|
||||
NTSTATUS status;
|
||||
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
|
||||
do {
|
||||
if (len > 0x4000000) {
|
||||
return 0;
|
||||
}
|
||||
len *= 2;
|
||||
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
status = pQuerySystemInformation(SystemExtendedHandleInformation, pHandleInfo, len, &len);
|
||||
} while (status == STATUS_INFO_LENGTH_MISMATCH);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
printf("Failed to call 'NtQuerySystemInformation()' with error code 0x%X\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE currentProcess = GetCurrentProcess();
|
||||
for (int i = 0; i < pHandleInfo->HandleCount; i++) {
|
||||
SYSTEM_HANDLE handle = pHandleInfo->Handles[i];
|
||||
PVOID object = handle.Object;
|
||||
HANDLE handleValue = handle.HandleValue;
|
||||
HANDLE uniqueProcessId = handle.UniqueProcessId;
|
||||
if (NULL != pid && HandleToLong(uniqueProcessId) != pid) {
|
||||
continue;
|
||||
}
|
||||
LPSTR pName = NULL;
|
||||
LPSTR pType = NULL;
|
||||
HANDLE sourceProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_DUP_HANDLE | PROCESS_SUSPEND_RESUME, FALSE, HandleToULong(uniqueProcessId));
|
||||
HANDLE targetHandle = NULL;
|
||||
NTSTATUS status = pDuplicateObject(sourceProcess, handleValue, currentProcess, &targetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
if (NT_SUCCESS(status)) {
|
||||
//printf("Failed to call 'NtDuplicateObject()' with error code 0x%X\n", status);
|
||||
POBJECT_NAME_INFORMATION pNameInfo = (POBJECT_NAME_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
POBJECT_TYPE_INFORMATION pTypeInfo = (POBJECT_TYPE_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
if (NT_SUCCESS(pQueryObject(targetHandle, ObjectNameInformation, pNameInfo, len, NULL))) {
|
||||
pName = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, pNameInfo->Name.Length);
|
||||
WideCharToMultiByte(CP_ACP, 0, pNameInfo->Name.Buffer, -1, pName, pNameInfo->Name.Length, NULL, NULL);
|
||||
}
|
||||
if (NT_SUCCESS(pQueryObject(targetHandle, ObjectTypeInformation, pTypeInfo, len, NULL))) {
|
||||
pType = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, pTypeInfo->TypeName.Length);
|
||||
WideCharToMultiByte(CP_ACP, 0, pTypeInfo->TypeName.Buffer, -1, pType, pTypeInfo->TypeName.Length, NULL, NULL);
|
||||
}
|
||||
}
|
||||
if (NULL != handleName) {
|
||||
if (suffix) {
|
||||
if (NULL == pName || !endsWith(std::string(pName), std::string(handleName))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (NULL == pName || 0 != strcmp(pName, handleName)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (TRUE == closeHandle) {
|
||||
HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, HandleToLong(uniqueProcessId));
|
||||
DuplicateHandle(hProcess, handleValue, 0, 0, 0, 0, DUPLICATE_CLOSE_SOURCE);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
}
|
||||
printf("PID: %-6d\t", uniqueProcessId);
|
||||
printf("Handle: 0x%-3x\t", handleValue);
|
||||
printf("Object: 0x%-8X\t", object);
|
||||
printf("Type: %-20s\t", NULL != pType ? pType : "<Unknown type>");
|
||||
printf("Name: %-30s\t", NULL != pName ? pName : "");
|
||||
printf("\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DisplayHandles() {
|
||||
return FindHandles(NULL, NULL, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int DisplayHandles(ULONG pid) {
|
||||
return FindHandles(pid, NULL, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int FindHandle(ULONG pid, LPSTR handleName) {
|
||||
return FindHandles(pid, handleName, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int CloseHandle(ULONG pid, LPSTR handleName) {
|
||||
return FindHandles(pid, handleName, TRUE, FALSE);
|
||||
}
|
||||
|
||||
HANDLE FindHandleByName(ULONG pid, LPSTR handleName) {
|
||||
HMODULE ntdll = GetModuleHandle(TEXT("ntdll.dll"));
|
||||
if (NULL == ntdll) {
|
||||
printf("Failed to load 'ntdll.dll'\n");
|
||||
return 0;
|
||||
}
|
||||
PNtQuerySystemInformation pQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress(ntdll, "NtQuerySystemInformation");
|
||||
PNtQueryObject pQueryObject = (PNtQueryObject)GetProcAddress(ntdll, "NtQueryObject");
|
||||
PNtDuplicateObject pDuplicateObject = (PNtDuplicateObject)GetProcAddress(ntdll, "NtDuplicateObject");
|
||||
if (NULL == pQuerySystemInformation || NULL == pQueryObject || NULL == pDuplicateObject) {
|
||||
printf("Failed to call 'GetProcAddress()'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG len = 0x10000;
|
||||
NTSTATUS status;
|
||||
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL;
|
||||
do {
|
||||
if (len > 0x4000000) {
|
||||
return 0;
|
||||
}
|
||||
len *= 2;
|
||||
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
status = pQuerySystemInformation(SystemExtendedHandleInformation, pHandleInfo, len, &len);
|
||||
} while (status == STATUS_INFO_LENGTH_MISMATCH);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
printf("Failed to call 'NtQuerySystemInformation()' with error code 0x%X\n", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE currentProcess = GetCurrentProcess();
|
||||
for (int i = 0; i < pHandleInfo->HandleCount; i++) {
|
||||
SYSTEM_HANDLE handle = pHandleInfo->Handles[i];
|
||||
PVOID object = handle.Object;
|
||||
HANDLE handleValue = handle.HandleValue;
|
||||
HANDLE uniqueProcessId = handle.UniqueProcessId;
|
||||
if (NULL != pid && HandleToLong(uniqueProcessId) != pid) {
|
||||
continue;
|
||||
}
|
||||
LPSTR pName = NULL;
|
||||
LPSTR pType = NULL;
|
||||
HANDLE sourceProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_DUP_HANDLE | PROCESS_SUSPEND_RESUME, FALSE, HandleToULong(uniqueProcessId));
|
||||
HANDLE targetHandle = NULL;
|
||||
NTSTATUS status = pDuplicateObject(sourceProcess, handleValue, currentProcess, &targetHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
if (NT_SUCCESS(status)) {
|
||||
//printf("Failed to call 'NtDuplicateObject()' with error code 0x%X\n", status);
|
||||
POBJECT_NAME_INFORMATION pNameInfo = (POBJECT_NAME_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
POBJECT_TYPE_INFORMATION pTypeInfo = (POBJECT_TYPE_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);
|
||||
if (NT_SUCCESS(pQueryObject(targetHandle, ObjectNameInformation, pNameInfo, len, NULL))) {
|
||||
pName = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, pNameInfo->Name.Length);
|
||||
WideCharToMultiByte(CP_ACP, 0, pNameInfo->Name.Buffer, -1, pName, pNameInfo->Name.Length, NULL, NULL);
|
||||
}
|
||||
if (NT_SUCCESS(pQueryObject(targetHandle, ObjectTypeInformation, pTypeInfo, len, NULL))) {
|
||||
pType = (LPSTR)GlobalAlloc(GMEM_ZEROINIT, pTypeInfo->TypeName.Length);
|
||||
WideCharToMultiByte(CP_ACP, 0, pTypeInfo->TypeName.Buffer, -1, pType, pTypeInfo->TypeName.Length, NULL, NULL);
|
||||
}
|
||||
}
|
||||
if (NULL != handleName) {
|
||||
|
||||
if (NULL == pName || 0 != strcmp(pName, handleName)) {
|
||||
continue;
|
||||
}
|
||||
return handleValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::wstring Utf8ToUnicode(const char* buffer) {
|
||||
int c_size = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0);
|
||||
if (c_size > 0) {
|
||||
wchar_t* temp = new wchar_t[c_size + 1];
|
||||
MultiByteToWideChar(CP_UTF8, 0, buffer, -1, temp, c_size);
|
||||
temp[c_size] = L'\0';
|
||||
std::wstring ret(temp);
|
||||
delete[] temp;
|
||||
temp = NULL;
|
||||
return ret;
|
||||
}
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
DWORD GetPIDForProcess(wchar_t* process)
|
||||
{
|
||||
HANDLE hSnapshot;
|
||||
DWORD dPid = 0;
|
||||
PROCESSENTRY32W pe32;
|
||||
int working;
|
||||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (!hSnapshot) {
|
||||
return 0;
|
||||
}
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
for (working = Process32FirstW(hSnapshot, &pe32); working; working = Process32NextW(hSnapshot, &pe32))
|
||||
{
|
||||
if (!wcscmp(pe32.szExeFile, process))
|
||||
{
|
||||
dPid = pe32.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CloseHandle(hSnapshot);
|
||||
return dPid;
|
||||
}
|
||||
|
||||
HMODULE GetDLLHandle(wchar_t* wDllName, DWORD dPid)
|
||||
{
|
||||
HMODULE result;
|
||||
tagMODULEENTRY32W me32;
|
||||
void* snapMod;
|
||||
|
||||
if (!dPid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
snapMod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dPid);
|
||||
me32.dwSize = sizeof(tagMODULEENTRY32W);
|
||||
if (Module32FirstW(snapMod, &me32))
|
||||
{
|
||||
while (wcscmp(wDllName, me32.szModule))
|
||||
{
|
||||
if (!Module32NextW(snapMod, &me32))
|
||||
goto error;
|
||||
}
|
||||
CloseHandle(snapMod);
|
||||
result = me32.hModule;
|
||||
}
|
||||
else
|
||||
{
|
||||
error:
|
||||
CloseHandle(snapMod);
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char GetProcAddressAsmCode[] = {
|
||||
0x55, // push ebp;
|
||||
0x8B, 0xEC, // mov ebp, esp;
|
||||
0x83, 0xEC, 0x40, // sub esp, 0x40;
|
||||
0x57, // push edi;
|
||||
0x51, // push ecx;
|
||||
0x8B, 0x7D, 0x08, // mov edi, dword ptr[ebp + 0x8];
|
||||
0x8B, 0x07, // mov eax,dword ptr[edi];
|
||||
0x50, // push eax;
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, // call GetModuleHandleW;
|
||||
0x83, 0xC4, 0x04, // add esp,0x4;
|
||||
0x83, 0xC7, 0x04, // add edi,0x4;
|
||||
0x8B, 0x0F, // mov ecx, dword ptr[edi];
|
||||
0x51, // push ecx;
|
||||
0x50, // push eax;
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, // call GetProcAddress;
|
||||
0x83, 0xC4, 0x08, // add esp, 0x8;
|
||||
0x59, // pop ecx;
|
||||
0x5F, // pop edi;
|
||||
0x8B, 0xE5, // mov esp, ebp;
|
||||
0x5D, // pop ebp;
|
||||
0xC3 // retn;
|
||||
};
|
||||
|
||||
LPVOID FillAsmCode(HANDLE handle) {
|
||||
DWORD pGetModuleHandleW = (DWORD)GetModuleHandleW;
|
||||
DWORD pGetProcAddress = (DWORD)GetProcAddress;
|
||||
PVOID fillCall1 = (PVOID)&GetProcAddressAsmCode[15];
|
||||
PVOID fillCall2 = (PVOID)&GetProcAddressAsmCode[30];
|
||||
LPVOID pAsmFuncAddr = VirtualAllocEx(handle, NULL, 1, MEM_COMMIT, PAGE_EXECUTE);
|
||||
if (!pAsmFuncAddr) {
|
||||
return 0;
|
||||
}
|
||||
*(DWORD*)fillCall1 = pGetModuleHandleW - (DWORD)pAsmFuncAddr - 14 - 5;
|
||||
*(DWORD*)fillCall2 = pGetProcAddress - (DWORD)pAsmFuncAddr - 29 - 5;
|
||||
//*(DWORD*)fillCall1 = pGetModuleHandleW ;
|
||||
//*(DWORD*)fillCall2 = pGetProcAddress;
|
||||
SIZE_T dwWriteSize;
|
||||
WriteProcessMemory(handle, pAsmFuncAddr, GetProcAddressAsmCode, sizeof(GetProcAddressAsmCode), &dwWriteSize);
|
||||
return pAsmFuncAddr;
|
||||
|
||||
}
|
||||
|
||||
BOOL RemoteLibraryFunction(HANDLE hProcess, LPCSTR lpModuleName, LPCSTR lpProcName, LPVOID lpParameters, SIZE_T dwParamSize, PVOID* ppReturn)
|
||||
{
|
||||
LPVOID lpRemoteParams = NULL;
|
||||
|
||||
LPVOID lpFunctionAddress = GetProcAddress(GetModuleHandleA(lpModuleName), lpProcName);
|
||||
if (!lpFunctionAddress) lpFunctionAddress = GetProcAddress(LoadLibraryA(lpModuleName), lpProcName);
|
||||
if (!lpFunctionAddress) goto ErrorHandler;
|
||||
|
||||
if (lpParameters)
|
||||
{
|
||||
lpRemoteParams = VirtualAllocEx(hProcess, NULL, dwParamSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!lpRemoteParams) goto ErrorHandler;
|
||||
|
||||
SIZE_T dwBytesWritten = 0;
|
||||
BOOL result = WriteProcessMemory(hProcess, lpRemoteParams, lpParameters, dwParamSize, &dwBytesWritten);
|
||||
if (!result || dwBytesWritten < 1) goto ErrorHandler;
|
||||
}
|
||||
|
||||
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpFunctionAddress, lpRemoteParams, NULL, NULL);
|
||||
if (!hThread) goto ErrorHandler;
|
||||
|
||||
DWORD dwOut = 0;
|
||||
while (GetExitCodeThread(hThread, &dwOut)) {
|
||||
if (dwOut != STILL_ACTIVE) {
|
||||
*ppReturn = (PVOID)dwOut;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
ErrorHandler:
|
||||
if (lpRemoteParams) VirtualFreeEx(hProcess, lpRemoteParams, dwParamSize, MEM_RELEASE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int InjectDllAndStartHttp(wchar_t* szPName, wchar_t* szDllPath, DWORD port)
|
||||
{
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread = NULL;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr = NULL;
|
||||
HINSTANCE__* hKernelModule = NULL;
|
||||
LPVOID lpRemoteDllBase = NULL;
|
||||
HANDLE hProcess;
|
||||
unsigned int dwPid;
|
||||
size_t ulDllLength;
|
||||
wchar_t* dllName = L"wxhelper.dll";
|
||||
size_t dllNameLen = wcslen(dllName) * 2 + 2;
|
||||
char* funcName = "http_start";
|
||||
size_t funcNameLen = strlen(funcName) + 1;
|
||||
|
||||
HANDLE hStartHttp = NULL;
|
||||
LPVOID portAddr = NULL;
|
||||
HANDLE getProcThread = NULL;
|
||||
|
||||
LPVOID paramsAddr = NULL;
|
||||
LPVOID param1Addr = NULL;
|
||||
LPVOID param2Addr = NULL;
|
||||
LPVOID GetProcFuncAddr = NULL;
|
||||
|
||||
DWORD params[2] = { 0 };
|
||||
|
||||
dwPid = GetPIDForProcess(szPName);
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwPid);
|
||||
if (!hProcess) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
GetProcFuncAddr = FillAsmCode(hProcess);
|
||||
param1Addr = VirtualAllocEx(hProcess, NULL, dllNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param1Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param1Addr, dllName, dllNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
param2Addr = VirtualAllocEx(hProcess, NULL, funcNameLen, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (param2Addr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)param2Addr, funcName, funcNameLen, &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
params[0] = (DWORD)param1Addr;
|
||||
params[1] = (DWORD)param2Addr;
|
||||
|
||||
paramsAddr = VirtualAllocEx(hProcess, NULL, sizeof(params), MEM_COMMIT, PAGE_READWRITE);
|
||||
if (paramsAddr) {
|
||||
SIZE_T dwWriteSize;
|
||||
BOOL bRet = WriteProcessMemory(hProcess, (LPVOID)paramsAddr, ¶ms[0], sizeof(params), &dwWriteSize);
|
||||
if (!bRet) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwRet = 0;
|
||||
getProcThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcFuncAddr, paramsAddr, 0, NULL);
|
||||
|
||||
if (getProcThread)
|
||||
{
|
||||
WaitForSingleObject(getProcThread, INFINITE);
|
||||
GetExitCodeThread(getProcThread, &dwRet);
|
||||
if (dwRet) {
|
||||
hStartHttp = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)dwRet, (LPVOID)port, 0, NULL);
|
||||
WaitForSingleObject(hStartHttp, INFINITE);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
if (hRemoteThread) {
|
||||
CloseHandle(hRemoteThread);
|
||||
}
|
||||
if (getProcThread) {
|
||||
CloseHandle(getProcThread);
|
||||
}
|
||||
if (hStartHttp) {
|
||||
CloseHandle(hStartHttp);
|
||||
}
|
||||
|
||||
if (lpRemoteDllBase) {
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
if (param1Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, dllNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (param2Addr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, funcNameLen, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (paramsAddr) {
|
||||
VirtualFreeEx(hProcess, param1Addr, sizeof(params), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (GetProcFuncAddr) {
|
||||
VirtualFreeEx(hProcess, GetProcFuncAddr, sizeof(GetProcAddressAsmCode), MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
||||
{
|
||||
int result = 0;
|
||||
HANDLE hRemoteThread;
|
||||
LPTHREAD_START_ROUTINE lpSysLibAddr;
|
||||
HINSTANCE__* hKernelModule;
|
||||
LPVOID lpRemoteDllBase;
|
||||
HANDLE hProcess;
|
||||
unsigned int dwPid;
|
||||
size_t ulDllLength;
|
||||
|
||||
dwPid = GetPIDForProcess(szPName);
|
||||
ulDllLength = (wcslen(szDllPath) + 1) * sizeof(wchar_t);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwPid);
|
||||
if (!hProcess) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lpRemoteDllBase = VirtualAllocEx(hProcess, NULL, ulDllLength, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lpRemoteDllBase)
|
||||
{
|
||||
if (WriteProcessMemory(hProcess, lpRemoteDllBase, szDllPath, ulDllLength, NULL)
|
||||
&& (hKernelModule = GetModuleHandleW(L"kernel32.dll")) != 0
|
||||
&& (lpSysLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernelModule, "LoadLibraryW")) != 0
|
||||
&& (hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, lpSysLibAddr, lpRemoteDllBase, 0, NULL)) != 0)
|
||||
{
|
||||
WaitForSingleObject(hRemoteThread, INFINITE);
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hRemoteThread);
|
||||
CloseHandle(hProcess);
|
||||
OutputDebugStringA("[DBG] dll inject success");
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hProcess);
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int UnInjectDll(wchar_t* szPName, wchar_t* szDName)
|
||||
{
|
||||
HMODULE hDll;
|
||||
HANDLE lpFreeLibAddr;
|
||||
HINSTANCE__* hK32;
|
||||
HANDLE hProcess;
|
||||
unsigned int dwPID;
|
||||
|
||||
dwPID = GetPIDForProcess(szPName);
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwPID);
|
||||
if (!hProcess) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hK32 = GetModuleHandleW(L"Kernel32.dll");
|
||||
if (!hK32) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
lpFreeLibAddr = GetProcAddress(hK32, "FreeLibraryAndExitThread");
|
||||
//lpFreeLibAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hK32, "FreeLibrary");
|
||||
hDll = GetDLLHandle(szDName, dwPID);
|
||||
if (hDll) {
|
||||
HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)lpFreeLibAddr, hDll, NULL, NULL);
|
||||
if (hThread == NULL) {
|
||||
int errorCode = GetLastError();
|
||||
return 0;
|
||||
}
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
CloseHandle(hThread);
|
||||
CloseHandle(hProcess);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FARPROC ShellCode(DWORD param[]) {
|
||||
return GetProcAddress(GetModuleHandleW((LPCWSTR)param[0]), (LPCSTR)param[1]);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int param;
|
||||
char cInjectprogram[MAX_PATH] = { 0 };
|
||||
char cUnInjectprogram[MAX_PATH] = { 0 };
|
||||
char cDllPath[MAX_PATH] = { 0 };
|
||||
char cDllName[MAX_PATH] = { 0 };
|
||||
int port = 0;
|
||||
|
||||
ULONG pid = 0;
|
||||
|
||||
while ((param = getopt(argc, argv, "i:p:u:d:m:P:h")) != -1)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case 'i':
|
||||
strcpy(cInjectprogram, optarg);
|
||||
break;
|
||||
case 'p':
|
||||
strcpy(cDllPath, optarg);
|
||||
break;
|
||||
case 'u':
|
||||
strcpy(cUnInjectprogram, optarg);
|
||||
case 'd':
|
||||
strcpy(cDllName, optarg);
|
||||
break;
|
||||
case 'h':
|
||||
printf("Usage: %s [-i/u] [-p/d] [-m]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -h Print this help message.\n");
|
||||
printf(" -i <program name> Name of the running program to be injected.\n");
|
||||
printf(" -u <program name> Name of the running program to be uninstalled.\n");
|
||||
printf(" -p <path> Full path of injection file.\n");
|
||||
printf(" -d <file> Name of injection file.\n");
|
||||
printf(" -m <pid> WeChat.exe pid.\n");
|
||||
printf("\n");
|
||||
printf("Examples:\n");
|
||||
printf(" window> %s -i test.exe -p c:/inject.dll \n", argv[0]);
|
||||
printf(" window> %s -u test.exe -d inject.dll \n", argv[0]);
|
||||
printf(" window> %s -m 1988 \n", argv[0]);
|
||||
exit(0);
|
||||
break;
|
||||
case 'm':
|
||||
pid = std::stol(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
port = std::atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pid) {
|
||||
FindHandles(pid, "_WeChat_App_Instance_Identity_Mutex_Name", TRUE, TRUE);
|
||||
}
|
||||
|
||||
if (cInjectprogram[0] != 0 && cDllPath[0] != 0)
|
||||
{
|
||||
if (cInjectprogram[0] != '\0' && cDllPath[0] != '\0')
|
||||
{
|
||||
if (port == 0) {
|
||||
std::wstring wsProgram = Utf8ToUnicode(cInjectprogram);
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDll((wchar_t*)wsProgram.c_str(), (wchar_t*)wsPath.c_str());
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring wsProgram = Utf8ToUnicode(cInjectprogram);
|
||||
std::wstring wsPath = Utf8ToUnicode(cDllPath);
|
||||
int ret = InjectDllAndStartHttp((wchar_t*)wsProgram.c_str(), (wchar_t*)wsPath.c_str(), port);
|
||||
printf(" 注入结果:%i \n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cUnInjectprogram[0] != 0 && cDllName[0] != 0)
|
||||
{
|
||||
if (cUnInjectprogram[0] != '\0' && cDllName[0] != '\0')
|
||||
{
|
||||
std::wstring wsUnInjectProgram = Utf8ToUnicode(cUnInjectprogram);
|
||||
std::wstring wsName = Utf8ToUnicode(cDllName);
|
||||
int ret = UnInjectDll((wchar_t*)wsUnInjectProgram.c_str(), (wchar_t*)wsName.c_str());
|
||||
printf(" 卸载结果:%i \n", ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Submodule
+1
Submodule spdlog added at ad0e89cbfb
+7
-8
@@ -1,6 +1,5 @@
|
||||
#include "pch.h"
|
||||
#include "account_mgr.h"
|
||||
#include "easylogging++.h"
|
||||
|
||||
|
||||
#include "wechat_function.h"
|
||||
@@ -129,16 +128,16 @@ int AccountMgr::GetSelfInfo(SelfInfoInner &out) {
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x304) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10) == 0) {
|
||||
if (*(DWORD *)(service_addr + 0x31C) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x31C + 0x10) == 0) {
|
||||
out.head_img = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x304 + 0x14) == 0xF) {
|
||||
out.head_img = string((char *)(service_addr + 0x304),
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10));
|
||||
if (*(DWORD *)(service_addr + 0x31C + 0x14) == 0xF) {
|
||||
out.head_img = string((char *)(service_addr + 0x31C),
|
||||
*(DWORD *)(service_addr + 0x31C + 0x10));
|
||||
} else {
|
||||
out.head_img = string(*(char **)(service_addr + 0x304),
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10));
|
||||
out.head_img = string(*(char **)(service_addr + 0x31C),
|
||||
*(DWORD *)(service_addr + 0x31C + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
#include "pch.h"
|
||||
/*
|
||||
base64.cpp and base64.h
|
||||
|
||||
base64 encoding and decoding with C++.
|
||||
More information at
|
||||
https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
|
||||
|
||||
Version: 2.rc.08 (release candidate)
|
||||
|
||||
Copyright (C) 2004-2017, 2020, 2021 Ren¨¦ Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Ren¨¦ Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
//
|
||||
// Depending on the url parameter in base64_chars, one of
|
||||
// two sets of base64 characters needs to be chosen.
|
||||
// They differ in their last two characters.
|
||||
//
|
||||
static const char *base64_chars[2] = {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"+/",
|
||||
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"-_"};
|
||||
|
||||
static unsigned int pos_of_char(const unsigned char chr)
|
||||
{
|
||||
//
|
||||
// Return the position of chr within base64_encode()
|
||||
//
|
||||
|
||||
if (chr >= 'A' && chr <= 'Z')
|
||||
return chr - 'A';
|
||||
else if (chr >= 'a' && chr <= 'z')
|
||||
return chr - 'a' + ('Z' - 'A') + 1;
|
||||
else if (chr >= '0' && chr <= '9')
|
||||
return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
|
||||
else if (chr == '+' || chr == '-')
|
||||
return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
|
||||
else if (chr == '/' || chr == '_')
|
||||
return 63; // Ditto for '/' and '_'
|
||||
else
|
||||
//
|
||||
// 2020-10-23: Throw std::exception rather than const char*
|
||||
//(Pablo Martin-Gomez, https://github.com/Bouska)
|
||||
//
|
||||
throw std::runtime_error("Input is not valid base64-encoded data.");
|
||||
}
|
||||
|
||||
static std::string insert_linebreaks(std::string str, size_t distance)
|
||||
{
|
||||
//
|
||||
// Provided by https://github.com/JomaCorpFX, adapted by me.
|
||||
//
|
||||
if (!str.length())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t pos = distance;
|
||||
|
||||
while (pos < str.size())
|
||||
{
|
||||
str.insert(pos, "\n");
|
||||
pos += distance + 1;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename String, unsigned int line_length>
|
||||
static std::string encode_with_line_breaks(String s)
|
||||
{
|
||||
return insert_linebreaks(base64_encode(s, false), line_length);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_pem(String s)
|
||||
{
|
||||
return encode_with_line_breaks<String, 64>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode_mime(String s)
|
||||
{
|
||||
return encode_with_line_breaks<String, 76>(s);
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string encode(String s, bool url)
|
||||
{
|
||||
return base64_encode(reinterpret_cast<const unsigned char *>(s.data()), s.length(), url);
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len, bool url)
|
||||
{
|
||||
|
||||
size_t len_encoded = (in_len + 2) / 3 * 4;
|
||||
|
||||
unsigned char trailing_char = url ? '.' : '=';
|
||||
|
||||
//
|
||||
// Choose set of base64 characters. They differ
|
||||
// for the last two positions, depending on the url
|
||||
// parameter.
|
||||
// A bool (as is the parameter url) is guaranteed
|
||||
// to evaluate to either 0 or 1 in C++ therefore,
|
||||
// the correct character set is chosen by subscripting
|
||||
// base64_chars with url.
|
||||
//
|
||||
const char *base64_chars_ = base64_chars[url];
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(len_encoded);
|
||||
|
||||
unsigned int pos = 0;
|
||||
|
||||
while (pos < in_len)
|
||||
{
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);
|
||||
|
||||
if (pos + 1 < in_len)
|
||||
{
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);
|
||||
|
||||
if (pos + 2 < in_len)
|
||||
{
|
||||
ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
|
||||
ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]);
|
||||
ret.push_back(trailing_char);
|
||||
ret.push_back(trailing_char);
|
||||
}
|
||||
|
||||
pos += 3;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename String>
|
||||
static std::string decode(String encoded_string, bool remove_linebreaks)
|
||||
{
|
||||
//
|
||||
// decode(¡) is templated so that it can be used with String = const std::string&
|
||||
// or std::string_view (requires at least C++17)
|
||||
//
|
||||
|
||||
if (encoded_string.empty())
|
||||
return std::string();
|
||||
|
||||
if (remove_linebreaks)
|
||||
{
|
||||
|
||||
std::string copy(encoded_string);
|
||||
|
||||
copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());
|
||||
|
||||
return base64_decode(copy, false);
|
||||
}
|
||||
|
||||
size_t length_of_string = encoded_string.length();
|
||||
size_t pos = 0;
|
||||
|
||||
//
|
||||
// The approximate length (bytes) of the decoded string might be one or
|
||||
// two bytes smaller, depending on the amount of trailing equal signs
|
||||
// in the encoded string. This approximation is needed to reserve
|
||||
// enough space in the string to be returned.
|
||||
//
|
||||
size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
|
||||
std::string ret;
|
||||
ret.reserve(approx_length_of_decoded_string);
|
||||
|
||||
while (pos < length_of_string)
|
||||
{
|
||||
//
|
||||
// Iterate over encoded input string in chunks. The size of all
|
||||
// chunks except the last one is 4 bytes.
|
||||
//
|
||||
// The last chunk might be padded with equal signs or dots
|
||||
// in order to make it 4 bytes in size as well, but this
|
||||
// is not required as per RFC 2045.
|
||||
//
|
||||
// All chunks except the last one produce three output bytes.
|
||||
//
|
||||
// The last chunk produces at least one and up to three bytes.
|
||||
//
|
||||
|
||||
size_t pos_of_char_1 = pos_of_char(encoded_string[pos + 1]);
|
||||
|
||||
//
|
||||
// Emit the first output byte that is produced in each chunk:
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char(encoded_string[pos + 0])) << 2) + ((pos_of_char_1 & 0x30) >> 4)));
|
||||
|
||||
if ((pos + 2 < length_of_string) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045)
|
||||
encoded_string[pos + 2] != '=' &&
|
||||
encoded_string[pos + 2] != '.' // accept URL-safe base 64 strings, too, so check for '.' also.
|
||||
)
|
||||
{
|
||||
//
|
||||
// Emit a chunk's second byte (which might not be produced in the last chunk).
|
||||
//
|
||||
unsigned int pos_of_char_2 = pos_of_char(encoded_string[pos + 2]);
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2)));
|
||||
|
||||
if ((pos + 3 < length_of_string) &&
|
||||
encoded_string[pos + 3] != '=' &&
|
||||
encoded_string[pos + 3] != '.')
|
||||
{
|
||||
//
|
||||
// Emit a chunk's third byte (which might not be produced in the last chunk).
|
||||
//
|
||||
ret.push_back(static_cast<std::string::value_type>(((pos_of_char_2 & 0x03) << 6) + pos_of_char(encoded_string[pos + 3])));
|
||||
}
|
||||
}
|
||||
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const &s, bool remove_linebreaks)
|
||||
{
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
std::string base64_encode(std::string const &s, bool url)
|
||||
{
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string const &s)
|
||||
{
|
||||
return encode_pem(s);
|
||||
}
|
||||
|
||||
std::string base64_encode_mime(std::string const &s)
|
||||
{
|
||||
return encode_mime(s);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
|
||||
std::string base64_encode(std::string_view s, bool url)
|
||||
{
|
||||
return encode(s, url);
|
||||
}
|
||||
|
||||
std::string base64_encode_pem(std::string_view s)
|
||||
{
|
||||
return encode_pem(s);
|
||||
}
|
||||
|
||||
std::string base64_encode_mime(std::string_view s)
|
||||
{
|
||||
return encode_mime(s);
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks)
|
||||
{
|
||||
return decode(s, remove_linebreaks);
|
||||
}
|
||||
|
||||
#endif // __cplusplus >= 201703L
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// base64 encoding and decoding with C++.
|
||||
// Version: 2.rc.08 (release candidate)
|
||||
//
|
||||
#pragma once
|
||||
#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
|
||||
|
||||
#include <string>
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
std::string base64_encode(std::string const &s, bool url = false);
|
||||
std::string base64_encode_pem(std::string const &s);
|
||||
std::string base64_encode_mime(std::string const &s);
|
||||
|
||||
std::string base64_decode(std::string const &s, bool remove_linebreaks = false);
|
||||
std::string base64_encode(unsigned char const *, size_t len, bool url = false);
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
//
|
||||
// Interface with std::string_view rather than const std::string&
|
||||
// Requires C++17
|
||||
// Provided by Yannic Bonenberger (https://github.com/Yannic)
|
||||
//
|
||||
std::string base64_encode(std::string_view s, bool url = false);
|
||||
std::string base64_encode_pem(std::string_view s);
|
||||
std::string base64_encode_mime(std::string_view s);
|
||||
|
||||
std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
|
||||
#endif // __cplusplus >= 201703L
|
||||
|
||||
#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
|
||||
@@ -108,6 +108,7 @@ int ChatRoomMgr::DelMemberFromChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL get_chat_room_mgr_addr
|
||||
SUB ESP,0x14
|
||||
MOV ESI,EAX
|
||||
@@ -120,6 +121,7 @@ int ChatRoomMgr::DelMemberFromChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
|
||||
PUSH EAX
|
||||
CALL del_member_addr
|
||||
MOV success,EAX
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
|
||||
+13
-2
@@ -1,6 +1,17 @@
|
||||
#include "config.h"
|
||||
#include "pch.h"
|
||||
#include "config.h"
|
||||
|
||||
namespace wxhelper {
|
||||
Config::Config(/* args */) {}
|
||||
|
||||
Config::~Config() {}
|
||||
} // namespace wxhelper
|
||||
|
||||
|
||||
void Config::Initialize(){
|
||||
port_ = GetPrivateProfileInt("config", "Port", 19088, "./config.ini");
|
||||
}
|
||||
int Config::GetPort(){
|
||||
return port_;
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
+13
-11
@@ -1,15 +1,17 @@
|
||||
#ifndef WXHELPER_CONFIG_H_
|
||||
#ifndef WXHELPER_CONFIG_H_
|
||||
#define WXHELPER_CONFIG_H_
|
||||
|
||||
namespace wxhelper{
|
||||
namespace wxhelper {
|
||||
|
||||
class Config
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
public:
|
||||
Config(/* args */);
|
||||
~Config();
|
||||
};
|
||||
}
|
||||
class Config {
|
||||
public:
|
||||
Config(/* args */);
|
||||
~Config();
|
||||
void Initialize();
|
||||
int GetPort();
|
||||
|
||||
private:
|
||||
int port_;
|
||||
};
|
||||
} // namespace wxhelper
|
||||
#endif
|
||||
+4
-3
@@ -126,7 +126,7 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
DWORD verify_msg_addr = base_addr_ + WX_VERIFY_MSG_OFFSET;
|
||||
DWORD set_value_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD do_verify_user_addr = base_addr_ + WX_DO_VERIFY_USER_OFFSET;
|
||||
DWORD fn1_addr = base_addr_ + 0x758720;
|
||||
DWORD fn1_addr = base_addr_ + 0x7591b0;
|
||||
WeChatString user_id(wxid);
|
||||
WeChatString w_msg(msg);
|
||||
DWORD instance =0;
|
||||
@@ -175,7 +175,7 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
return success;
|
||||
}
|
||||
|
||||
int ContactMgr::VerifyApply(wchar_t *v3, wchar_t *v4){
|
||||
int ContactMgr::VerifyApply(wchar_t *v3, wchar_t *v4,int permission){
|
||||
int success = -1;
|
||||
DWORD set_value_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD verify_addr = base_addr_ + WX_VERIFY_OK_OFFSET;
|
||||
@@ -186,12 +186,13 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
|
||||
WeChatString v3_str(v3);
|
||||
char helper_obj[0x40] = {0};
|
||||
char nullbuffer[0x3CC] = {0};
|
||||
int flag = permission < 0 ? 0:permission;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,helper_obj
|
||||
CALL new_helper_addr
|
||||
MOV ESI,0x0
|
||||
MOV ESI,flag
|
||||
MOV EDI,0x6
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ class ContactMgr : public BaseMgr {
|
||||
int DelContact(wchar_t* wxid);
|
||||
std::wstring GetContactOrChatRoomNickname(wchar_t* id);
|
||||
int AddFriendByWxid(wchar_t* wxid,wchar_t* msg);
|
||||
int VerifyApply(wchar_t *v3, wchar_t *v4);
|
||||
int VerifyApply(wchar_t *v3, wchar_t *v4,int permission);
|
||||
};
|
||||
} // namespace wxhelper
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
#include "db.h"
|
||||
|
||||
#include "base64.h"
|
||||
#include "easylogging++.h"
|
||||
|
||||
#include "wechat_function.h"
|
||||
#include "utils.h"
|
||||
using namespace std;
|
||||
|
||||
namespace wxhelper {
|
||||
@@ -117,8 +116,16 @@ int DB::Select(DWORD db_hanle, const char *sql,
|
||||
vector<string> item;
|
||||
for (size_t i = 0; i < it.size(); i++) {
|
||||
if (!it[i].is_blob) {
|
||||
string content(it[i].content);
|
||||
item.push_back(content);
|
||||
bool is_utf8 = Utils::IsTextUtf8(it[i].content, it[i].content_len);
|
||||
if (is_utf8) {
|
||||
string content(it[i].content);
|
||||
item.push_back(content);
|
||||
} else {
|
||||
string base64_str =
|
||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
||||
item.push_back(base64_str);
|
||||
}
|
||||
|
||||
} else {
|
||||
string b64_str =
|
||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
||||
@@ -453,9 +460,9 @@ std::vector<void *> DB::GetDbHandles() {
|
||||
dbs_.push_back(db_end);
|
||||
#ifdef _DEBUG
|
||||
for (unsigned int i = 0; i < dbs_.size() - 1; i++) {
|
||||
LOG(INFO) << "dbname =" << dbs_[i].db_name;
|
||||
LOG(INFO) << "handle =" << dbs_[i].handle;
|
||||
LOG(INFO) << "table_count =" << dbs_[i].tables.size();
|
||||
// LOG(INFO) << "dbname =" << dbs_[i].db_name;
|
||||
// LOG(INFO) << "handle =" << dbs_[i].handle;
|
||||
// LOG(INFO) << "table_count =" << dbs_[i].tables.size();
|
||||
}
|
||||
#endif
|
||||
vector<void *> ret_array;
|
||||
@@ -483,7 +490,7 @@ unsigned int DB::GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex) {
|
||||
swprintf_s(dbname, L"MSG%d.db", i);
|
||||
DWORD handle = GetDbHandleByDbName(dbname);
|
||||
if (handle == 0) {
|
||||
LOG(INFO) << "MSG db handle is null";
|
||||
SPDLOG_INFO("MSG db handle is null");
|
||||
return 0;
|
||||
}
|
||||
vector<vector<string>> result;
|
||||
@@ -508,7 +515,7 @@ vector<string> DB::GetChatMsgByMsgId(ULONG64 msgid) {
|
||||
swprintf_s(dbname, L"MSG%d.db", i);
|
||||
DWORD handle = GetDbHandleByDbName(dbname);
|
||||
if (handle == 0) {
|
||||
LOG(INFO) << "MSG db handle is null";
|
||||
// LOG(INFO) << "MSG db handle is null";
|
||||
return {};
|
||||
}
|
||||
vector<vector<string>> result;
|
||||
@@ -527,7 +534,7 @@ std::string DB::GetVoiceBuffByMsgId(ULONG64 msgid) {
|
||||
swprintf_s(dbname, L"MediaMSG%d.db", i);
|
||||
DWORD handle = GetDbHandleByDbName(dbname);
|
||||
if (handle == 0) {
|
||||
LOG(INFO) << "Media db handle is null";
|
||||
// LOG(INFO) << "Media db handle is null";
|
||||
return "";
|
||||
}
|
||||
vector<vector<string>> result;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
-4576
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
#ifndef FRAMEWORK_H_
|
||||
#define FRAMEWORK_H_
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "pch.h"
|
||||
#include "global_context.h"
|
||||
#include "http_server.h"
|
||||
#include "easylogging++.h"
|
||||
#include "hooks.h"
|
||||
#include "thread_pool.h"
|
||||
|
||||
|
||||
namespace wxhelper {
|
||||
@@ -11,14 +11,15 @@ void GlobalContext::initialize(HMODULE module) {
|
||||
module_ = module;
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
config.emplace();
|
||||
config->Initialize();
|
||||
log.emplace();
|
||||
log->initialize();
|
||||
log->Initialize();
|
||||
hide_module.emplace();
|
||||
#ifndef _DEBUG
|
||||
hide_module->Hide(module_);
|
||||
#endif
|
||||
|
||||
HttpServer::GetInstance().Init(19088);
|
||||
HttpServer::GetInstance().Init(config->GetPort());
|
||||
HttpServer::GetInstance().HttpStart();
|
||||
DB::GetInstance().init(base);
|
||||
contact_mgr.emplace(ContactMgr{base});
|
||||
@@ -27,6 +28,7 @@ void GlobalContext::initialize(HMODULE module) {
|
||||
account_mgr.emplace(AccountMgr{base});
|
||||
chat_room_mgr.emplace(ChatRoomMgr{base});
|
||||
sns_mgr.emplace(SNSMgr{base});
|
||||
ThreadPool::GetInstance().Create(1,512);
|
||||
}
|
||||
|
||||
void GlobalContext::finally() {
|
||||
|
||||
+166
-38
@@ -1,10 +1,9 @@
|
||||
#include <Ws2tcpip.h>
|
||||
#include "pch.h"
|
||||
#include <Ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "easylogging++.h"
|
||||
#include "pch.h"
|
||||
#include "thread_pool.h"
|
||||
#include "wechat_function.h"
|
||||
using namespace nlohmann;
|
||||
using namespace std;
|
||||
@@ -57,12 +56,12 @@ void SendSocketMessage(InnerMessageStruct *msg) {
|
||||
string jstr = j_msg.dump() + "\n";
|
||||
|
||||
if (server_port_ == 0) {
|
||||
LOG(INFO) << "http server port error :" << server_port_;
|
||||
SPDLOG_ERROR("http server port error :{}",server_port_);
|
||||
return;
|
||||
}
|
||||
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (client_socket < 0) {
|
||||
LOG(INFO) << "socket init fail";
|
||||
SPDLOG_ERROR("socket init fail");
|
||||
return;
|
||||
}
|
||||
BOOL status = false;
|
||||
@@ -73,13 +72,13 @@ void SendSocketMessage(InnerMessageStruct *msg) {
|
||||
InetPtonA(AF_INET, server_ip_, &client_addr.sin_addr.s_addr);
|
||||
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
|
||||
sizeof(sockaddr)) < 0) {
|
||||
LOG(INFO) << "socket connect fail";
|
||||
SPDLOG_ERROR("socket connect fail");
|
||||
return;
|
||||
}
|
||||
char recv_buf[1024] = {0};
|
||||
int ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
|
||||
if (ret == -1 || ret == 0) {
|
||||
LOG(INFO) << "socket send fail ,ret:" << ret;
|
||||
SPDLOG_ERROR("socket send fail ,ret::{}",ret);
|
||||
closesocket(client_socket);
|
||||
return;
|
||||
}
|
||||
@@ -87,10 +86,83 @@ void SendSocketMessage(InnerMessageStruct *msg) {
|
||||
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
|
||||
closesocket(client_socket);
|
||||
if (ret == -1 || ret == 0) {
|
||||
LOG(INFO) << "socket recv fail ,ret:" << ret;
|
||||
SPDLOG_ERROR("socket recv fail ,ret:{}",ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
||||
PTP_WORK Work) {
|
||||
InnerMessageStruct *msg = (InnerMessageStruct *)context;
|
||||
if (msg == NULL) {
|
||||
SPDLOG_INFO("add work:msg is null");
|
||||
return;
|
||||
}
|
||||
unique_ptr<InnerMessageStruct> sms(msg);
|
||||
json j_msg =
|
||||
json::parse(msg->buffer, msg->buffer + msg->length, nullptr, false);
|
||||
if (j_msg.is_discarded() == true) {
|
||||
return;
|
||||
}
|
||||
string jstr = j_msg.dump() + "\n";
|
||||
|
||||
if (server_port_ == 0) {
|
||||
SPDLOG_ERROR("http server port error :{}", server_port_);
|
||||
return;
|
||||
}
|
||||
WSADATA was_data = {0};
|
||||
int ret = WSAStartup(MAKEWORD(2, 2), &was_data);
|
||||
if (ret != 0) {
|
||||
SPDLOG_ERROR("WSAStartup failed:{}", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (client_socket < 0) {
|
||||
SPDLOG_ERROR("socket init fail");
|
||||
return;
|
||||
}
|
||||
BOOL status = false;
|
||||
sockaddr_in client_addr;
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
client_addr.sin_family = AF_INET;
|
||||
client_addr.sin_port = htons((u_short)server_port_);
|
||||
InetPtonA(AF_INET, server_ip_, &client_addr.sin_addr.s_addr);
|
||||
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
|
||||
sizeof(sockaddr)) < 0) {
|
||||
SPDLOG_ERROR("socket connect fail");
|
||||
closesocket(client_socket);
|
||||
WSACleanup();
|
||||
return ;
|
||||
}
|
||||
char recv_buf[1024] = {0};
|
||||
ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
|
||||
if (ret == -1 || ret == 0) {
|
||||
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
|
||||
closesocket(client_socket);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
ret = shutdown(client_socket, SD_SEND);
|
||||
if (ret == SOCKET_ERROR) {
|
||||
SPDLOG_ERROR("shutdown failed with erro:{}", ret);
|
||||
closesocket(client_socket);
|
||||
WSACleanup();
|
||||
return ;
|
||||
}
|
||||
|
||||
memset(recv_buf, 0, sizeof(recv_buf));
|
||||
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
|
||||
closesocket(client_socket);
|
||||
if (ret == -1 || ret == 0) {
|
||||
SPDLOG_ERROR("socket recv fail ,ret:{}", ret);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
void __cdecl OnRecvMsg(DWORD msg_addr) {
|
||||
json j_msg;
|
||||
unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30);
|
||||
@@ -138,13 +210,17 @@ void __cdecl OnRecvMsg(DWORD msg_addr) {
|
||||
inner_msg->buffer = new char[jstr.size() + 1];
|
||||
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
|
||||
inner_msg->length = jstr.size();
|
||||
HANDLE thread = CreateThread(
|
||||
NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
|
||||
if (thread) {
|
||||
CloseHandle(thread);
|
||||
}
|
||||
bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback,inner_msg);
|
||||
SPDLOG_INFO("add work:{}",add);
|
||||
// HANDLE thread = CreateThread(
|
||||
// NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
|
||||
// if (thread) {
|
||||
// CloseHandle(thread);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// @brief hook msg implement
|
||||
_declspec(naked) void HandleSyncMsg() {
|
||||
__asm {
|
||||
@@ -214,38 +290,35 @@ int HookRecvMsg(char *client_ip, int port) {
|
||||
strcpy_s(server_ip_, client_ip);
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
if (!base) {
|
||||
SPDLOG_INFO("base addr is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg_hook_flag_) {
|
||||
SPDLOG_INFO("recv msg hook already called");
|
||||
return 2;
|
||||
}
|
||||
|
||||
DWORD hook_recv_msg_addr = base + WX_RECV_MSG_HOOK_OFFSET;
|
||||
msg_next_addr_ = base + WX_RECV_MSG_HOOK_NEXT_OFFSET;
|
||||
msg_back_addr_ = hook_recv_msg_addr + 0x5;
|
||||
LOG(INFO) << "base" << base;
|
||||
LOG(INFO) << "msg_next_addr_" << msg_next_addr_;
|
||||
LOG(INFO) << "msg_back_addr_" << msg_back_addr_;
|
||||
msg_back_addr_ = hook_recv_msg_addr + 0x5;
|
||||
Utils::HookAnyAddress(hook_recv_msg_addr, (LPVOID)HandleSyncMsg,
|
||||
msg_asm_code_);
|
||||
|
||||
DWORD hook_sns_msg_addr = base + WX_SNS_HOOK_OFFSET;
|
||||
sns_next_addr_ = base + WX_SNS_HOOK_NEXT_OFFSET;
|
||||
sns_back_addr_ = hook_sns_msg_addr + 0x5;
|
||||
LOG(INFO) << "base" << base;
|
||||
LOG(INFO) << "sns_next_addr_" << sns_next_addr_;
|
||||
LOG(INFO) << "sns_back_addr_" << sns_back_addr_;
|
||||
Utils::HookAnyAddress(hook_sns_msg_addr, (LPVOID)HandleSNSMsg, sns_asm_code_);
|
||||
|
||||
msg_hook_flag_ = true;
|
||||
SPDLOG_INFO("hook recv msg success");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UnHookRecvMsg() {
|
||||
server_port_ = 0;
|
||||
if (!msg_hook_flag_) {
|
||||
LOG(INFO) << "this port already hooked";
|
||||
SPDLOG_INFO("recv msg hook already called");
|
||||
return 2;
|
||||
}
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
@@ -271,9 +344,9 @@ void PrintLog(DWORD addr) {
|
||||
char *ansi_message = new char[size + 1];
|
||||
memset(ansi_message, 0, size + 1);
|
||||
WideCharToMultiByte(CP_ACP, 0, w_msg, -1, ansi_message, size, 0, 0);
|
||||
spdlog::info("wechat log:{}", ansi_message);
|
||||
delete[] w_msg;
|
||||
w_msg = NULL;
|
||||
LOG(INFO) << ansi_message;
|
||||
delete[] ansi_message;
|
||||
ansi_message = NULL;
|
||||
}
|
||||
@@ -321,7 +394,7 @@ int UnHookLog() {
|
||||
void SetErrorCode(int code) { userinfo.error_code = code; }
|
||||
|
||||
void SetUserInfoDetail(DWORD address) {
|
||||
LOG(INFO) << "hook userinfo addr" <<&userinfo;
|
||||
SPDLOG_INFO("hook userinfo addr = {}",address);
|
||||
DWORD length = *(DWORD *)(address + 0x8);
|
||||
userinfo.keyword = new wchar_t[length + 1];
|
||||
userinfo.keyword_len = length;
|
||||
@@ -352,6 +425,36 @@ void SetUserInfoDetail(DWORD address) {
|
||||
ZeroMemory(userinfo.big_image, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
length = *(DWORD *)(address + 0x6C);
|
||||
userinfo.V3 = new wchar_t[length + 1];
|
||||
userinfo.V3_len = length;
|
||||
if (length) {
|
||||
memcpy(userinfo.V3, (wchar_t *)(*(DWORD *)(address + 0x68)),
|
||||
(length + 1) * sizeof(wchar_t));
|
||||
} else {
|
||||
ZeroMemory(userinfo.V3, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
length = *(DWORD *)(address + 0x80);
|
||||
userinfo.account = new wchar_t[length + 1];
|
||||
userinfo.account_len = length;
|
||||
if (length) {
|
||||
memcpy(userinfo.account, (wchar_t *)(*(DWORD *)(address + 0x7C)),
|
||||
(length + 1) * sizeof(wchar_t));
|
||||
} else {
|
||||
ZeroMemory(userinfo.account, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
// length = *(DWORD *)(address + 0x94);
|
||||
// userinfo.friend_name = new wchar_t[length + 1];
|
||||
// userinfo.friend_name_len = length;
|
||||
// if (length) {
|
||||
// memcpy(userinfo.friend_name, (wchar_t *)(*(DWORD *)(address + 0x90)),
|
||||
// (length + 1) * sizeof(wchar_t));
|
||||
// } else {
|
||||
// ZeroMemory(userinfo.friend_name, (length + 1) * sizeof(wchar_t));
|
||||
// }
|
||||
|
||||
length = *(DWORD *)(address + 0xC8);
|
||||
userinfo.nickname = new wchar_t[length + 1];
|
||||
userinfo.nickname_len = length;
|
||||
@@ -362,15 +465,28 @@ void SetUserInfoDetail(DWORD address) {
|
||||
ZeroMemory(userinfo.nickname, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
|
||||
length = *(DWORD *)(address + 0x108);
|
||||
userinfo.v2 = new wchar_t[length + 1];
|
||||
userinfo.v2_len = length;
|
||||
if (length) {
|
||||
memcpy(userinfo.v2, (wchar_t *)(*(DWORD *)(address + 0x104)),
|
||||
(length + 1) * sizeof(wchar_t));
|
||||
} else {
|
||||
ZeroMemory(userinfo.v2, (length + 1) * sizeof(wchar_t));
|
||||
}
|
||||
// the results of calling and UI operations are different
|
||||
//
|
||||
// length = *(DWORD *)(address + 0x108);
|
||||
// userinfo.v2 = new wchar_t[length + 1];
|
||||
// userinfo.v2_len = length;
|
||||
// if (length) {
|
||||
// memcpy(userinfo.v2, (wchar_t *)(*(DWORD *)(address + 0x104)),
|
||||
// (length + 1) * sizeof(wchar_t));
|
||||
// } else {
|
||||
// ZeroMemory(userinfo.v2, (length + 1) * sizeof(wchar_t));
|
||||
// }
|
||||
|
||||
// length = *(DWORD *)(address + 0x11C);
|
||||
// userinfo.py = new wchar_t[length + 1];
|
||||
// userinfo.py_len = length;
|
||||
// if (length) {
|
||||
// memcpy(userinfo.py, (wchar_t *)(*(DWORD *)(address + 0x118)),
|
||||
// (length + 1) * sizeof(wchar_t));
|
||||
// } else {
|
||||
// ZeroMemory(userinfo.py, (length + 1) * sizeof(wchar_t));
|
||||
// }
|
||||
|
||||
|
||||
length = *(DWORD *)(address + 0x16C);
|
||||
userinfo.small_image = new wchar_t[length + 1];
|
||||
@@ -436,9 +552,21 @@ void DeleteUserInfoCache() {
|
||||
if (userinfo.v3) {
|
||||
delete userinfo.v3;
|
||||
}
|
||||
if (userinfo.V3) {
|
||||
delete userinfo.V3;
|
||||
}
|
||||
if (userinfo.account) {
|
||||
delete userinfo.account;
|
||||
}
|
||||
if (userinfo.friend_name) {
|
||||
delete userinfo.friend_name;
|
||||
}
|
||||
if (userinfo.nickname) {
|
||||
delete userinfo.nickname;
|
||||
}
|
||||
if (userinfo.py) {
|
||||
delete userinfo.py;
|
||||
}
|
||||
if (userinfo.nation) {
|
||||
delete userinfo.nation;
|
||||
}
|
||||
@@ -497,11 +625,11 @@ int HookSearchContact() {
|
||||
if (search_contact_flag_) {
|
||||
return 2;
|
||||
}
|
||||
DWORD hook_error_code_addr = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET;
|
||||
error_code_next_addr_ = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET;
|
||||
error_code_back_addr_ = hook_error_code_addr + 0x5;
|
||||
Utils::HookAnyAddress(hook_error_code_addr, (LPVOID)HandleErrorCode,
|
||||
error_code_asm_code_);
|
||||
// DWORD hook_error_code_addr = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET;
|
||||
// error_code_next_addr_ = base + WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET;
|
||||
// error_code_back_addr_ = hook_error_code_addr + 0x5;
|
||||
// Utils::HookAnyAddress(hook_error_code_addr, (LPVOID)HandleErrorCode,
|
||||
// error_code_asm_code_);
|
||||
|
||||
DWORD hook_user_info_addr = base + WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET;
|
||||
user_info_next_addr_ = base + WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET;
|
||||
|
||||
+16
-13
@@ -9,7 +9,6 @@
|
||||
#include "chat_room_mgr.h"
|
||||
#include "contact_mgr.h"
|
||||
#include "db.h"
|
||||
#include "easylogging++.h"
|
||||
#include "hooks.h"
|
||||
#include "misc_mgr.h"
|
||||
#include "send_message_mgr.h"
|
||||
@@ -71,9 +70,9 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
if (mg_vcasecmp(&hm->method, "POST") == 0) {
|
||||
is_post = 1;
|
||||
}
|
||||
el::Logger *defaultLogger = el::Loggers::getLogger("default");
|
||||
defaultLogger->info("method: %v body: %v", hm->method.ptr, hm->body.ptr);
|
||||
LOG_IF(is_post != 1, INFO) << "request method is not post";
|
||||
// el::Logger *defaultLogger = el::Loggers::getLogger("default");
|
||||
// defaultLogger->info("method: %v body: %v", hm->method.ptr, hm->body.ptr);
|
||||
// LOG_IF(is_post != 1, INFO) << "request method is not post";
|
||||
|
||||
if (is_post == 0) {
|
||||
json ret_data = {{"result", "ERROR"}, {"msg", "not support method"}};
|
||||
@@ -131,7 +130,6 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_SEND_AT: {
|
||||
break;
|
||||
wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
vector<wstring> wxids = getArrayParam(j_param, "wxids");
|
||||
wstring msg = GetWStringParam(j_param, "msg");
|
||||
@@ -228,8 +226,12 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
{"province", Utils::WCharToUTF8(user->province)},
|
||||
{"sex", user->sex},
|
||||
{"signature", Utils::WCharToUTF8(user->signature)},
|
||||
{"v2", Utils::WCharToUTF8(user->v2)},
|
||||
// {"v2", Utils::WCharToUTF8(user->v2)},
|
||||
{"v3", Utils::WCharToUTF8(user->v3)},
|
||||
{"V3", Utils::WCharToUTF8(user->V3)},
|
||||
{"account", Utils::WCharToUTF8(user->account)},
|
||||
// {"friendName", Utils::WCharToUTF8(user->friend_name)},
|
||||
// {"py", Utils::WCharToUTF8(user->py)},
|
||||
};
|
||||
ret_data["userInfo"] = info;
|
||||
}
|
||||
@@ -253,7 +255,8 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
case WECHAT_CONTACT_VERIFY_APPLY: {
|
||||
wstring v3 = GetWStringParam(j_param, "v3");
|
||||
wstring v4 = GetWStringParam(j_param, "v4");
|
||||
int success = g_context.contact_mgr->VerifyApply(WS2LPWS(v3),WS2LPWS(v4));
|
||||
int permission = GetIntParam(j_param, "permission");
|
||||
int success = g_context.contact_mgr->VerifyApply(WS2LPWS(v3),WS2LPWS(v4),permission);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
@@ -502,11 +505,11 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_DO_OCR: {
|
||||
// wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
// string text("");
|
||||
// int success = g_context.misc_mgr->DoOCRTask(WS2LPWS(image_path), text);
|
||||
// json ret_data = {{"code", success}, {"result", "OK"}, {"text", text}};
|
||||
// ret = ret_data.dump();
|
||||
wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
string text("");
|
||||
int success = g_context.misc_mgr->DoOCRTask(WS2LPWS(image_path), text);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}, {"text", text}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_SEND_PAT_MSG: {
|
||||
@@ -589,7 +592,7 @@ void HttpHandler::HandlerRequest(struct mg_connection *c, void *ev_data) {
|
||||
ret = res.dump();
|
||||
}
|
||||
if (ret != "") {
|
||||
mg_http_reply(c, 200, "", ret.c_str(), 0, 0);
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n", ret.c_str());
|
||||
}
|
||||
} else {
|
||||
mg_http_reply(c, 500, NULL, "%s", "Invalid URI");
|
||||
|
||||
+12
-29
@@ -1,37 +1,20 @@
|
||||
#include "log.h"
|
||||
|
||||
#include "easylogging++.h"
|
||||
INITIALIZE_EASYLOGGINGPP
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
||||
namespace wxhelper {
|
||||
Log::Log(/* args */) {}
|
||||
|
||||
Log::~Log() {}
|
||||
Log::~Log() {
|
||||
|
||||
void Log::initialize() {
|
||||
}
|
||||
|
||||
el::Configurations conf;
|
||||
// 启用日志
|
||||
conf.setGlobally(el::ConfigurationType::Enabled, "true");
|
||||
// 设置日志文件目录以及文件名
|
||||
conf.setGlobally(el::ConfigurationType::Filename,
|
||||
"log\\log_%datetime{%Y%M%d %H%m%s}.log");
|
||||
// 设置日志文件最大文件大小
|
||||
conf.setGlobally(el::ConfigurationType::MaxLogFileSize, "20971520");
|
||||
// 是否写入文件
|
||||
conf.setGlobally(el::ConfigurationType::ToFile, "true");
|
||||
// 是否输出控制台
|
||||
conf.setGlobally(el::ConfigurationType::ToStandardOutput, "true");
|
||||
// 设置日志输出格式
|
||||
conf.setGlobally(el::ConfigurationType::Format,
|
||||
"[%datetime] [%thread] [%loc] [%level] : %msg");
|
||||
// 设置日志文件写入周期,如下每100条刷新到输出流中
|
||||
#ifdef _DEBUG
|
||||
conf.setGlobally(el::ConfigurationType::LogFlushThreshold, "1");
|
||||
#else
|
||||
conf.setGlobally(el::ConfigurationType::LogFlushThreshold, "100");
|
||||
#endif
|
||||
// 设置配置文件
|
||||
el::Loggers::reconfigureAllLoggers(conf);
|
||||
void Log::Initialize() {
|
||||
auto logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 23, 59);
|
||||
logger->flush_on(spdlog::level::err);
|
||||
spdlog::set_default_logger(logger);
|
||||
spdlog::flush_every(std::chrono::seconds(3));
|
||||
spdlog::set_level(spdlog::level::debug);
|
||||
spdlog::set_pattern("%Y-%m-%d %H:%M:%S [%l] [%t] - <%s>|<%#>|<%!>,%v");
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
@@ -8,7 +8,7 @@ namespace wxhelper{
|
||||
public:
|
||||
Log(/* args */);
|
||||
~Log();
|
||||
void initialize();
|
||||
void Initialize();
|
||||
};
|
||||
|
||||
|
||||
|
||||
+11
-29
@@ -5,7 +5,6 @@
|
||||
#include "base64.h"
|
||||
#include "db.h"
|
||||
#include "hooks.h"
|
||||
#include "easylogging++.h"
|
||||
#define BUFSIZE 1024
|
||||
|
||||
#define JPEG0 0xFF
|
||||
@@ -90,7 +89,7 @@ int MiscMgr::DoOCRTask(wchar_t *img_path, std::string &result) {
|
||||
for (unsigned int i = 0; i < num - 1; i++) {
|
||||
DWORD content = *(DWORD *)header;
|
||||
result += Utils::WstringToUTF8(READ_WSTRING(content, 0x14));
|
||||
|
||||
result += "\r\n";
|
||||
header = content;
|
||||
}
|
||||
}
|
||||
@@ -154,8 +153,8 @@ int MiscMgr::DoDownloadTask(ULONG64 msg_id) {
|
||||
DWORD get_current_data_path_addr = base_addr_ + WX_GET_CURRENT_DATA_PATH_OFFSET;
|
||||
DWORD free_app_msg_info_addr = base_addr_ + WX_FREE_APP_MSG_INFO_OFFSET;
|
||||
DWORD push_thumb_task_addr = base_addr_ + WX_PUSH_THUMB_TASK_OFFSET;
|
||||
DWORD video_mgr_addr = base_addr_ + WX_VIDEO_MGR_OFFSET;
|
||||
DWORD download_video_image_addr = base_addr_ + WX_VIDEO_MGR_OFFSET;
|
||||
|
||||
|
||||
|
||||
WeChatString current_data_path;
|
||||
|
||||
@@ -256,23 +255,7 @@ int MiscMgr::DoDownloadTask(ULONG64 msg_id) {
|
||||
memcpy(&chat_msg[0x19C], &w_thumb_path, sizeof(w_thumb_path));
|
||||
memcpy(&chat_msg[0x1B0], &w_save_path, sizeof(w_save_path));
|
||||
memcpy(&chat_msg[0x29C], &temp, sizeof(temp));
|
||||
// note: the image has been downloaded and will not be downloaded again
|
||||
// use low-level method
|
||||
// this function does not work, need to modify chatmsg.
|
||||
// if (type == 0x3E || type == 0x2B){
|
||||
// __asm{
|
||||
// PUSHAD
|
||||
// PUSHFD
|
||||
// CALL video_mgr_addr
|
||||
// LEA ECX,chat_msg
|
||||
// PUSH ECX
|
||||
// MOV ECX,EAX
|
||||
// CALL download_video_image_addr
|
||||
// POPFD
|
||||
// POPAD
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
@@ -402,8 +385,8 @@ int MiscMgr::GetImgByName(wchar_t* file_path,wchar_t* save_dir) {
|
||||
|
||||
int MiscMgr::SearchContactNetScene(wchar_t *keyword,UserInfo ** user) {
|
||||
int success = -1;
|
||||
hooks::HookSearchContact();
|
||||
hooks::DeleteUserInfoCache();
|
||||
hooks::HookSearchContact();
|
||||
DWORD search_contact_mgr_addr = base_addr_ + WX_SEARCH_CONTACT_MGR_OFFSET;
|
||||
DWORD search_contact_addr = base_addr_ + WX_SEARCH_CONTACT_OFFSET;
|
||||
WeChatString key(keyword);
|
||||
@@ -420,16 +403,15 @@ int MiscMgr::SearchContactNetScene(wchar_t *keyword,UserInfo ** user) {
|
||||
popad;
|
||||
}
|
||||
success = 1;
|
||||
while (hooks::userinfo.error_code == 1 && hooks::user_info_flag_) {
|
||||
Sleep(20);
|
||||
}
|
||||
if (hooks::userinfo.error_code == 0) {
|
||||
// while (hooks::userinfo.error_code == 1 && hooks::user_info_flag_) {
|
||||
// Sleep(20);
|
||||
// }
|
||||
// if (hooks::userinfo.error_code == 0) {
|
||||
while (hooks::userinfo.over == false && hooks::user_info_flag_) {
|
||||
Sleep(20);
|
||||
Sleep(2);
|
||||
}
|
||||
}
|
||||
// }
|
||||
*user= &hooks::userinfo;
|
||||
LOG(INFO)<<"user:" <<user;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
#include <fcntl.h>
|
||||
#include "Windows.h"
|
||||
#include "utils.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/rotating_file_sink.h"
|
||||
#include "spdlog/sinks/daily_file_sink.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
|
||||
|
||||
#endif // PCH_H
|
||||
|
||||
|
||||
+86
-24
@@ -1,11 +1,9 @@
|
||||
#include "pch.h"
|
||||
#include "send_message_mgr.h"
|
||||
|
||||
#include "easylogging++.h"
|
||||
|
||||
#include "wechat_function.h"
|
||||
#include "db.h"
|
||||
|
||||
#include "contact_mgr.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
namespace wxhelper {
|
||||
SendMessageMgr::SendMessageMgr(DWORD base):BaseMgr(base) {}
|
||||
SendMessageMgr::~SendMessageMgr() {}
|
||||
@@ -14,13 +12,13 @@ int SendMessageMgr::SendText(wchar_t* wxid, wchar_t* msg) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString text_msg(msg);
|
||||
wchar_t** msg_pptr = &text_msg.ptr;
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base_addr_ + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
char chat_msg[0x2D8] = {0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
@@ -36,14 +34,79 @@ int SendMessageMgr::SendText(wchar_t* wxid, wchar_t* msg) {
|
||||
ADD ESP,0x18
|
||||
LEA ECX,chat_msg
|
||||
CALL free_chat_msg_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
LOG_IF((success == -1), ERROR) << "SendText fail";
|
||||
SPDLOG_INFO("SendText code = {}",success);
|
||||
SPDLOG_INFO("global log with source info");
|
||||
return success;
|
||||
}
|
||||
int SendMessageMgr::SendAtText(wchar_t* chat_room_id, wchar_t** wxids, int len,
|
||||
wchar_t* msg) {
|
||||
int success = -1;
|
||||
WeChatString * at_users = new WeChatString[len+1];
|
||||
std::wstring at_msg = L"";
|
||||
int number =0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
std::wstring nickname;
|
||||
if (!lstrcmpiW((wchar_t *)wxids[i], (wchar_t *)L"notify@all")) {
|
||||
nickname = L"所有人";
|
||||
} else {
|
||||
ContactMgr contact{base_addr_};
|
||||
nickname = contact.GetContactOrChatRoomNickname(wxids[i]);
|
||||
}
|
||||
if (nickname.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WeChatString temp = {0};
|
||||
temp.ptr = (wchar_t *)wxids[i];
|
||||
temp.length = wcslen((wchar_t *)wxids[i]);
|
||||
temp.max_length = wcslen((wchar_t *)wxids[i]) * 2;
|
||||
memcpy(&at_users[number], &temp, sizeof(WeChatString));
|
||||
at_msg = at_msg + L"@" + nickname + L" ";
|
||||
number++;
|
||||
}
|
||||
if (number < 1){
|
||||
return success;
|
||||
}
|
||||
std::wstring origin(msg);
|
||||
at_msg += origin;
|
||||
AtInner at_list = {0};
|
||||
at_list.start = (DWORD)at_users;
|
||||
at_list.finsh = (DWORD)&at_users[number];
|
||||
at_list.end = (DWORD)&at_users[number];
|
||||
WeChatString to_user(chat_room_id);
|
||||
WeChatString text_msg((wchar_t *)at_msg.c_str());
|
||||
wchar_t **msg_pptr = &text_msg.ptr;
|
||||
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base_addr_ + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
char chat_msg[0x2D8] = {0};
|
||||
__asm{
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x1
|
||||
LEA EAX,at_list
|
||||
PUSH EAX
|
||||
MOV EAX,msg_pptr
|
||||
PUSH EAX
|
||||
LEA EDX,to_user
|
||||
LEA ECX,chat_msg
|
||||
CALL send_text_msg_addr
|
||||
MOV success,EAX
|
||||
ADD ESP,0x18
|
||||
LEA ECX,chat_msg
|
||||
CALL free_chat_msg_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
SPDLOG_INFO("SendText code = {}",success);
|
||||
return success;
|
||||
}
|
||||
int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
|
||||
@@ -51,15 +114,15 @@ int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(image_path);
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_image_msg_addr = base + WX_SEND_IMAGE_OFFSET;
|
||||
DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD send_message_mgr_addr = base_addr_ + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_image_msg_addr = base_addr_ + WX_SEND_IMAGE_OFFSET;
|
||||
DWORD free_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD temp = 0;
|
||||
WeChatString null_obj = {0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL send_message_mgr_addr
|
||||
SUB ESP,0x14
|
||||
MOV temp,EAX
|
||||
@@ -78,9 +141,10 @@ int SendMessageMgr::SendImage(wchar_t* wxid, wchar_t* image_path) {
|
||||
MOV success,EAX
|
||||
LEA ECX,chat_msg
|
||||
CALL free_msg_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
LOG_IF((success == -1), ERROR) << "SendImage fail";
|
||||
SPDLOG_INFO("SendImage code = {}",success);
|
||||
return success;
|
||||
}
|
||||
int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
|
||||
@@ -88,11 +152,10 @@ int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(file_path);
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD app_msg_mgr_addr = base + WX_APP_MSG_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_file_addr = base + WX_SEND_FILE_OFFSET;
|
||||
DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD app_msg_mgr_addr = base_addr_ + WX_APP_MSG_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD send_file_addr = base_addr_ + WX_SEND_FILE_OFFSET;
|
||||
DWORD free_msg_addr = base_addr_ + WX_FREE_CHAT_MSG_OFFSET;
|
||||
DWORD temp = 0;
|
||||
WeChatString null_obj = {0};
|
||||
__asm {
|
||||
@@ -135,10 +198,10 @@ int SendMessageMgr::SendFile(wchar_t* wxid, wchar_t* file_path) {
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
SPDLOG_INFO("SendFile code = {}",success);
|
||||
if (success == 0x31) {
|
||||
return 1;
|
||||
}
|
||||
LOG_IF((success == -1), ERROR) << "SendFile fail";
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -150,9 +213,8 @@ int SendMessageMgr::ForwardMsg(wchar_t* wxid, unsigned long long msgid) {
|
||||
|
||||
if (localid == 0) return 0;
|
||||
WeChatString to_user(wxid);
|
||||
DWORD base = Utils::GetWeChatWinBase();
|
||||
DWORD forward_msg_addr = base + WX_FORWARD_MSG_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD forward_msg_addr = base_addr_ + WX_FORWARD_MSG_OFFSET;
|
||||
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "thread_pool.h"
|
||||
|
||||
#include "Windows.h"
|
||||
|
||||
namespace wxhelper {
|
||||
ThreadPool::~ThreadPool() {
|
||||
CloseThreadpoolCleanupGroupMembers(cleanup_group_, true, NULL);
|
||||
CloseThreadpoolCleanupGroup(cleanup_group_);
|
||||
CloseThreadpool(pool_);
|
||||
}
|
||||
bool ThreadPool::Create(unsigned long min, unsigned long max) {
|
||||
InitializeThreadpoolEnvironment(&env_);
|
||||
pool_ = CreateThreadpool(NULL);
|
||||
if (NULL == pool_) {
|
||||
return false;
|
||||
}
|
||||
SetThreadpoolThreadMaximum(pool_, max);
|
||||
BOOL ret = SetThreadpoolThreadMinimum(pool_, min);
|
||||
if (FALSE == ret) {
|
||||
return false;
|
||||
}
|
||||
cleanup_group_ = CreateThreadpoolCleanupGroup();
|
||||
if (NULL == cleanup_group_) {
|
||||
return false;
|
||||
}
|
||||
SetThreadpoolCallbackPool(&env_, pool_);
|
||||
SetThreadpoolCallbackCleanupGroup(&env_, cleanup_group_, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ThreadPool::AddWork(PTP_WORK_CALLBACK callback,PVOID opt) {
|
||||
PTP_WORK work = CreateThreadpoolWork(callback, opt, &env_);
|
||||
if (NULL == work) {
|
||||
return false;
|
||||
}
|
||||
SubmitThreadpoolWork(work);
|
||||
return true;
|
||||
}
|
||||
} // namespace wxhelper
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef WXHELPER_THREAD_POOL_H_
|
||||
#define WXHELPER_THREAD_POOL_H_
|
||||
#include "Windows.h"
|
||||
#include "singleton.h"
|
||||
namespace wxhelper {
|
||||
|
||||
class ThreadPool :public Singleton<ThreadPool>{
|
||||
public:
|
||||
~ThreadPool();
|
||||
|
||||
bool Create(unsigned long min = 1, unsigned long max = 4);
|
||||
|
||||
bool AddWork(PTP_WORK_CALLBACK callback,PVOID opt);
|
||||
|
||||
private:
|
||||
void operator=(const ThreadPool&) = delete;
|
||||
void operator=(ThreadPool&&) = delete;
|
||||
|
||||
PTP_POOL pool_;
|
||||
PTP_CLEANUP_GROUP cleanup_group_;
|
||||
TP_CALLBACK_ENVIRON env_;
|
||||
};
|
||||
|
||||
} // namespace wxhelper
|
||||
|
||||
#endif
|
||||
+44
-7
@@ -1,7 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
namespace wxhelper {
|
||||
std::wstring Utils::UTF8ToWstring(const std::string &str) {
|
||||
@@ -19,7 +18,7 @@ std::wstring Utils::AnsiToWstring(const std::string &input, DWORD locale) {
|
||||
MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, &temp[0], wchar_len);
|
||||
return std::wstring(&temp[0]);
|
||||
}
|
||||
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
@@ -102,8 +101,6 @@ void Utils::Hex2Bytes(const std::string &hex, BYTE *bytes) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Utils::IsDigit(std::string str) {
|
||||
if (str.length() == 0) {
|
||||
return false;
|
||||
@@ -119,7 +116,8 @@ bool Utils::IsDigit(std::string str) {
|
||||
bool Utils::FindOrCreateDirectoryW(const wchar_t *path) {
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE hFind = ::FindFirstFileW(path, &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
if (hFind != INVALID_HANDLE_VALUE &&
|
||||
(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
@@ -174,4 +172,43 @@ std::string Utils::WCharToUTF8(wchar_t *wstr) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
bool Utils::IsTextUtf8(const char *str,int length) {
|
||||
char endian = 1;
|
||||
bool littlen_endian = (*(char *)&endian == 1);
|
||||
|
||||
size_t i;
|
||||
int bytes_num;
|
||||
unsigned char chr;
|
||||
|
||||
i = 0;
|
||||
bytes_num = 0;
|
||||
while (i < length) {
|
||||
if (littlen_endian) {
|
||||
chr = *(str + i);
|
||||
} else { // Big Endian
|
||||
chr = (*(str + i) << 8) | *(str + i + 1);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bytes_num == 0) {
|
||||
if ((chr & 0x80) != 0) {
|
||||
while ((chr & 0x80) != 0) {
|
||||
chr <<= 1;
|
||||
bytes_num++;
|
||||
}
|
||||
if ((bytes_num < 2) || (bytes_num > 6)) {
|
||||
return false;
|
||||
}
|
||||
bytes_num--;
|
||||
}
|
||||
} else {
|
||||
if ((chr & 0xC0) != 0x80) {
|
||||
return false;
|
||||
}
|
||||
bytes_num--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (bytes_num == 0);
|
||||
}
|
||||
} // namespace wxhelper
|
||||
@@ -47,6 +47,8 @@ class Utils {
|
||||
|
||||
static std::string WCharToUTF8(wchar_t *wstr);
|
||||
|
||||
static bool IsTextUtf8(const char * str,int length) ;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static std::vector<T1> split(T1 str, T2 letter) {
|
||||
std::vector<T1> arr;
|
||||
|
||||
+100
-94
@@ -4,97 +4,95 @@
|
||||
#include <string>
|
||||
|
||||
// snsDataMgr
|
||||
#define WX_SNS_DATA_MGR_OFFSET 0xc39680
|
||||
#define WX_SNS_DATA_MGR_OFFSET 0xc3a500
|
||||
// chatRoomMgr
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x78cf20
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x78d9d0
|
||||
// contactMgr
|
||||
#define WX_CONTACT_MGR_OFFSET 0x75a4a0
|
||||
#define WX_CONTACT_MGR_OFFSET 0x75af30
|
||||
// syncMgr
|
||||
#define WX_SYNC_MGR_OFFSET 0xa87fd0
|
||||
// preDownloadMgr
|
||||
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80f110
|
||||
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80fe50
|
||||
// chatMgr
|
||||
#define WX_CHAT_MGR_OFFSET 0x792700
|
||||
#define WX_CHAT_MGR_OFFSET 0x7931b0
|
||||
// videoMgr
|
||||
#define WX_VIDEO_MGR_OFFSET 0x829820
|
||||
#define WX_VIDEO_MGR_OFFSET 0x82a560
|
||||
// patMgr
|
||||
#define WX_PAT_MGR_OFFSET 0x931730
|
||||
#define WX_PAT_MGR_OFFSET 0x932470
|
||||
// searchContactMgr
|
||||
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6cb00
|
||||
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6d860
|
||||
// appMsgMgr
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x76ae20
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x76b8c0
|
||||
// sendMessageMgr
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768140
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768be0
|
||||
|
||||
|
||||
// setChatMsgValue
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xf5b3f0
|
||||
|
||||
// chatMsg
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x76f010
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
#define WX_FREE_CHAT_MSG_2_OFFSET 0x6f4ea0
|
||||
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x756e30
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x76fab0
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x7573f0
|
||||
// #define WX_FREE_CHAT_MSG_2_OFFSET 0x6f4ea0
|
||||
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x7578c0
|
||||
|
||||
|
||||
//sns
|
||||
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e2140
|
||||
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e21e0
|
||||
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e36e0
|
||||
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e3780
|
||||
|
||||
//chat room
|
||||
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbde090
|
||||
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbdef30
|
||||
// chatRoomInfo
|
||||
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe99c40
|
||||
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe99f40
|
||||
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd22a0
|
||||
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd1dc0
|
||||
|
||||
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe9abd0
|
||||
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe9aed0
|
||||
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd3140
|
||||
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd2c60
|
||||
|
||||
|
||||
// chatRoom
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xe97890
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xe97ab0
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xe98820
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xe98a40
|
||||
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbdf260
|
||||
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbd9680
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbe0100
|
||||
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbda520
|
||||
|
||||
#define WX_TOP_MSG_OFFSET 0xbe1840
|
||||
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe1620
|
||||
#define WX_TOP_MSG_OFFSET 0xbe26e0
|
||||
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe24c0
|
||||
|
||||
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbdf3f0
|
||||
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbe0290
|
||||
|
||||
#define WX_FREE_CONTACT_OFFSET 0xea7880
|
||||
#define WX_FREE_CONTACT_OFFSET 0xea8800
|
||||
|
||||
// wcpayinfo
|
||||
#define WX_NEW_WCPAYINFO_OFFSET 0x7b2e60
|
||||
#define WX_FREE_WCPAYINFO_OFFSET 0x79c250
|
||||
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e2c20
|
||||
#define WX_NEW_WCPAYINFO_OFFSET 0x7b3900
|
||||
#define WX_FREE_WCPAYINFO_OFFSET 0x79cd00
|
||||
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e41d0
|
||||
|
||||
|
||||
//contact
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xc089f0
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xc09890
|
||||
#define WX_CONTACT_DEL_OFFSET 0xb9b3b0
|
||||
|
||||
#define WX_SET_VALUE_OFFSET 0x1f80900
|
||||
#define WX_DO_DEL_CONTACT_OFFSET 0xca6480
|
||||
#define WX_GET_CONTACT_OFFSET 0xc04e00
|
||||
#define WX_DO_VERIFY_USER_OFFSET 0xc02100
|
||||
#define WX_VERIFY_MSG_OFFSET 0xf59d40
|
||||
#define WX_VERIFY_OK_OFFSET 0xa18bd0
|
||||
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa17d50
|
||||
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa17e70
|
||||
#define WX_GET_CONTACT_OFFSET 0xc05ca0
|
||||
#define WX_DO_VERIFY_USER_OFFSET 0xc02f90
|
||||
#define WX_VERIFY_MSG_OFFSET 0xf5b2f0
|
||||
#define WX_VERIFY_OK_OFFSET 0xa19940
|
||||
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa18ac0
|
||||
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa18be0
|
||||
|
||||
// pushAttachTask
|
||||
|
||||
|
||||
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82bb40
|
||||
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82c880
|
||||
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc0370
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
|
||||
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc11d0
|
||||
#define WX_APP_MSG_INFO_OFFSET 0x7b3d20
|
||||
#define WX_GET_APP_MSG_XML_OFFSET 0xe628a0
|
||||
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79d900
|
||||
#define WX_PUSH_THUMB_TASK_OFFSET 0x82ba40
|
||||
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79e3b0
|
||||
#define WX_PUSH_THUMB_TASK_OFFSET 0x82c780
|
||||
#define WX_DOWNLOAD_VIDEO_IMG_OFFSET 0xd46c30
|
||||
|
||||
|
||||
@@ -102,45 +100,45 @@
|
||||
|
||||
|
||||
// pat
|
||||
#define WX_SEND_PAT_MSG_OFFSET 0x1421940
|
||||
#define WX_RET_OFFSET 0x1D58751
|
||||
#define WX_SEND_PAT_MSG_OFFSET 0x1422f30
|
||||
#define WX_RET_OFFSET 0x1D59DB1
|
||||
|
||||
|
||||
//search hook
|
||||
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17054
|
||||
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf57a20
|
||||
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8ceb0
|
||||
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8d100
|
||||
#define WX_SEARCH_CONTACT_OFFSET 0xcd1510
|
||||
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17ed4
|
||||
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf58fd0
|
||||
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8dc00
|
||||
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8de50
|
||||
#define WX_SEARCH_CONTACT_OFFSET 0xcd2370
|
||||
|
||||
|
||||
|
||||
//login
|
||||
#define WX_LOGOUT_OFFSET 0xe58870
|
||||
#define WX_ACCOUNT_SERVICE_OFFSET 0x768c80
|
||||
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3a610
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
|
||||
#define WX_LOGOUT_OFFSET 0xe596d0
|
||||
#define WX_ACCOUNT_SERVICE_OFFSET 0x769720
|
||||
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3bbd0
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc88120
|
||||
|
||||
|
||||
//forward
|
||||
#define WX_FORWARD_MSG_OFFSET 0xce6730
|
||||
#define WX_FORWARD_MSG_OFFSET 0xce75a0
|
||||
// send file
|
||||
#define WX_SEND_FILE_OFFSET 0xb6d1f0
|
||||
#define WX_SEND_FILE_OFFSET 0xb6dfd0
|
||||
// send image
|
||||
#define WX_SEND_IMAGE_OFFSET 0xce6640
|
||||
#define WX_SEND_IMAGE_OFFSET 0xce74b0
|
||||
// send text
|
||||
#define WX_SEND_TEXT_OFFSET 0xce6c80
|
||||
#define WX_SEND_TEXT_OFFSET 0xce7af0
|
||||
|
||||
|
||||
//ocr
|
||||
#define WX_INIT_OBJ_OFFSET 0x7a98f0
|
||||
#define WX_OCR_MANAGER_OFFSET 0x7ae470
|
||||
#define WX_DO_OCR_TASK_OFFSET 0x13230c0
|
||||
#define WX_INIT_OBJ_OFFSET 0x80b540
|
||||
#define WX_OCR_MANAGER_OFFSET 0x80ffc0
|
||||
#define WX_DO_OCR_TASK_OFFSET 0x13db9a0
|
||||
|
||||
|
||||
//storage
|
||||
|
||||
#define CONTACT_G_PINSTANCE_OFFSET 0x2ffddc8
|
||||
#define CONTACT_G_PINSTANCE_OFFSET 0x2fffe08
|
||||
#define DB_MICRO_MSG_OFFSET 0x68
|
||||
#define DB_CHAT_MSG_OFFSET 0x1C0
|
||||
#define DB_MISC_OFFSET 0x3D8
|
||||
@@ -153,10 +151,10 @@
|
||||
#define STORAGE_START_OFFSET 0x13f8
|
||||
#define STORAGE_END_OFFSET 0x13fc
|
||||
|
||||
#define PUBLIC_MSG_MGR_OFFSET 0x303df74
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x30403b8
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x303fd40
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x2ffe908
|
||||
#define PUBLIC_MSG_MGR_OFFSET 0x30400a4
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x30424dc
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x3041e70
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x3000948
|
||||
|
||||
#define OP_LOG_STORAGE_VFTABLE 0x2AD3A20
|
||||
#define CHAT_MSG_STORAGE_VFTABLE 0x2AC10F0
|
||||
@@ -196,15 +194,15 @@
|
||||
|
||||
|
||||
// hook log
|
||||
#define WX_HOOK_LOG_OFFSET 0xf57d67
|
||||
#define WX_HOOK_LOG_NEXT_OFFSET 0x240ea71
|
||||
#define WX_HOOK_LOG_OFFSET 0xf59317
|
||||
#define WX_HOOK_LOG_NEXT_OFFSET 0x24102b4
|
||||
|
||||
// hook msg
|
||||
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xd19a0b
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x756960
|
||||
#define WX_SNS_HOOK_OFFSET 0x14f9e15
|
||||
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fa0a0
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xd1a89b
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x7573f0
|
||||
#define WX_SNS_HOOK_OFFSET 0x14fb3b5
|
||||
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fb640
|
||||
|
||||
|
||||
// hook voice
|
||||
@@ -350,24 +348,24 @@
|
||||
#define SQLITE_NULL 5
|
||||
#define SQLITE_TEXT 3
|
||||
|
||||
#define SQLITE3_EXEC_OFFSET 0x1e24f70
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dea900
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1e2b8c0
|
||||
#define SQLITE3_OPEN_OFFSET 0x1e598b0
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1dead00
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1deb440
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1deb450
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1deb340
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1e5a0f0
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1e58550
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1e56cd0
|
||||
#define SQLITE3_STEP_OFFSET 0x1df3770
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df3c80
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df4570
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df4410
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df3cc0
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df3da0
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1df2740
|
||||
#define SQLITE3_EXEC_OFFSET 0x1e26770
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dec100
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1E2D0C0
|
||||
#define SQLITE3_OPEN_OFFSET 0x1e5b090
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1DEC500
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DECC40
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1DECC50
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1DECB40
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1e5b8d0
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1e59d30
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1e584b0
|
||||
#define SQLITE3_STEP_OFFSET 0x1df4f70
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df5480
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df5d70
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df5c10
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df54c0
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df55a0
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1df3f40
|
||||
|
||||
typedef int (*Sqlite3_callback)(void*, int, char**, char**);
|
||||
|
||||
@@ -578,12 +576,20 @@ struct UserInfo {
|
||||
int keyword_len;
|
||||
wchar_t *v3;
|
||||
int v3_len;
|
||||
wchar_t *V3;
|
||||
int V3_len;
|
||||
wchar_t *account;
|
||||
int account_len;
|
||||
wchar_t *friend_name;
|
||||
int friend_name_len;
|
||||
wchar_t *nickname;
|
||||
int nickname_len;
|
||||
wchar_t *signature;
|
||||
int signature_len;
|
||||
wchar_t *v2;
|
||||
int v2_len;
|
||||
wchar_t *py;
|
||||
int py_len;
|
||||
wchar_t *nation;
|
||||
int nation_len;
|
||||
wchar_t *province;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
## 可以使用3.9.0.28 分支下的注入工具,或者自己编译一下 source目录下的注入程序。
|
||||
Reference in New Issue
Block a user