未验证 提交 e1afae91 编写于 作者: J Jack Li 提交者: GitHub

Merge pull request #77 from ljc545w/http_support

增加发送消息http接口
BasedOnStyle: LLVM
UseTab: Never
IndentWidth: 4
TabWidth: 4
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 0
AccessModifierOffset: -4
SortIncludes: false
NamespaceIndentation: All
FixNamespaceComments: false
......@@ -18,6 +18,7 @@
packages
mongoose.c
mongoose.h
json.hpp
# VSCode
.vscode
......
# Check the usage of pre-commit on https://pre-commit.com/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.3.5
hooks:
- id: clang-format
args:
- -i
- --style=file
- --fallback-style=none
files: |
(?x)^(
.*?\.cpp|
.*?\.c|
.*?\.h
)
\ No newline at end of file
#include "pch.h"
bool InjectDll(DWORD dwId, WCHAR* szPath)
bool InjectDll(DWORD dwId, WCHAR *szPath)
{
WeChatProcess hp(dwId);
if (!hp.m_init) return 1;
if (hp.WeChatRobotBase() != 0) return 0;
WeChatData<wchar_t*> r_dllpath(hp.GetHandle(), szPath, TEXTLENGTH(szPath));
if (!hp.m_init)
return 1;
if (hp.WeChatRobotBase() != 0)
return 0;
WeChatData<wchar_t *> r_dllpath(hp.GetHandle(), szPath, TEXTLENGTH(szPath));
if (r_dllpath.GetAddr() == 0)
return 1;
CallRemoteFunction(hp.GetHandle(), LoadLibraryW, r_dllpath.GetAddr());
return 0;
}
bool Inject(DWORD dwPid,wchar_t* workPath) {
wchar_t* dllpath = new wchar_t[MAX_PATH];
swprintf_s(dllpath, MAX_PATH, L"%ws%ws%ws", workPath, L"\\", dllname);
string name = _com_util::ConvertBSTRToString((BSTR)workPath);
if (!isFileExists_stat(name)) {
bool Inject(DWORD dwPid, wchar_t *workPath)
{
wchar_t *dllpath = new wchar_t[MAX_PATH];
swprintf_s(dllpath, MAX_PATH, L"%ws%ws%ws", workPath, L"\\", DLLNAME);
string name = _com_util::ConvertBSTRToString((BSTR)workPath);
if (!isFileExists_stat(name))
{
MessageBox(NULL, dllpath, L"ļ", MB_ICONWARNING);
delete[] dllpath;
dllpath = NULL;
......@@ -28,12 +32,15 @@ bool Inject(DWORD dwPid,wchar_t* workPath) {
return status;
}
BOOL RemoveDll(DWORD dwId) {
BOOL RemoveDll(DWORD dwId)
{
WeChatProcess hp(dwId);
if (!hp.m_init) return 1;
if (!hp.m_init)
return 1;
DWORD WeChatRobotBase = hp.WeChatRobotBase();
if (WeChatRobotBase == 0) return 0;
if (WeChatRobotBase == 0)
return 0;
CallRemoteFunction(hp.GetHandle(), FreeConsole, NULL);
CallRemoteFunction(hp.GetHandle(), FreeLibrary, WeChatRobotBase);
return 0;
......
......@@ -9,53 +9,63 @@
*/
map<DWORD, short> ServiceCount;
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
BOOL isFileExists_stat(string& name) {
BOOL isFileExists_stat(string &name)
{
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
BOOL CreateConsole() {
if (AllocConsole()) {
BOOL CreateConsole()
{
if (AllocConsole())
{
AttachConsole(GetCurrentProcessId());
FILE* retStream;
FILE *retStream;
freopen_s(&retStream, "CONOUT$", "w", stdout);
if (!retStream) throw std::runtime_error("Stdout redirection failed.");
if (!retStream)
throw std::runtime_error("Stdout redirection failed.");
freopen_s(&retStream, "CONOUT$", "w", stderr);
if (!retStream) throw std::runtime_error("Stderr redirection failed.");
if (!retStream)
throw std::runtime_error("Stderr redirection failed.");
return 0;
}
return 1;
}
DWORD GetWeChatRobotBase(DWORD pid) {
DWORD GetWeChatRobotBase(DWORD pid)
{
WeChatProcess hp(pid);
if (!hp.m_init) return 0;
WeChatData<wchar_t*> r_dllname(hp.GetHandle(), dllname, TEXTLENGTH(dllname));
if (!hp.m_init)
return 0;
WeChatData<wchar_t *> r_dllname(hp.GetHandle(), DLLNAME, TEXTLENGTH(DLLNAME));
if (r_dllname.GetAddr() == 0)
return 0;
DWORD ret = CallRemoteFunction(hp.GetHandle(), GetModuleHandleW, r_dllname.GetAddr());
return ret;
}
DWORD GetWeChatWinBase(DWORD pid) {
wchar_t* WeChatWin = L"WeChatWin.dll";
DWORD GetWeChatWinBase(DWORD pid)
{
wchar_t *WeChatWin = L"WeChatWin.dll";
WeChatProcess hp(pid);
if (!hp.m_init) return 0;
WeChatData<wchar_t*> r_dllname(hp.GetHandle(), WeChatWin, TEXTLENGTH(WeChatWin));
if (!hp.m_init)
return 0;
WeChatData<wchar_t *> r_dllname(hp.GetHandle(), WeChatWin, TEXTLENGTH(WeChatWin));
if (r_dllname.GetAddr() == 0)
return 0;
DWORD ret = CallRemoteFunction(hp.GetHandle(), GetModuleHandleW, r_dllname.GetAddr());
return ret;
}
DWORD GetWeChatPid() {
DWORD GetWeChatPid()
{
HWND hCalc = FindWindow(NULL, L"微信");
DWORD wxPid = 0;
GetWindowThreadProcessId(hCalc, &wxPid);
if (wxPid == 0) {
if (wxPid == 0)
{
hCalc = FindWindow(NULL, L"微信测试版");
GetWindowThreadProcessId(hCalc, &wxPid);
}
......@@ -71,7 +81,7 @@ DWORD StartRobotService(DWORD pid)
if (ServiceCount[pid] == 0)
{
wstring wworkPath = GetComWorkPath();
wchar_t* workPath = (wchar_t*)wworkPath.c_str();
wchar_t *workPath = (wchar_t *)wworkPath.c_str();
bool status = Inject(pid, workPath);
if (!status)
{
......@@ -96,49 +106,56 @@ DWORD StopRobotService(DWORD pid)
return 0;
}
wstring GetComWorkPath() {
wchar_t szFilePath[MAX_PATH + 1] = { 0 };
wstring GetComWorkPath()
{
wchar_t szFilePath[MAX_PATH + 1] = {0};
GetModuleFileName(NULL, szFilePath, MAX_PATH);
wstring wpath = szFilePath;
int pos = wpath.find_last_of(L"\\");
wpath = wpath.substr(0,pos);
wpath = wpath.substr(0, pos);
return wpath;
}
static BOOL GetWeChatInstallInfo(TCHAR* lpValueName, VOID* Value, DWORD lpcbData) {
static BOOL GetWeChatInstallInfo(TCHAR *lpValueName, VOID *Value, DWORD lpcbData)
{
HKEY hKey = NULL;
ZeroMemory(Value, lpcbData);
LSTATUS lRet = RegOpenKeyEx(HKEY_CURRENT_USER, _T("SOFTWARE\\Tencent\\WeChat"), 0, KEY_QUERY_VALUE, &hKey);
if (lRet != 0) {
if (lRet != 0)
{
return false;
}
lRet = RegQueryValueEx(hKey, lpValueName, NULL, NULL, (LPBYTE)Value, &lpcbData);
RegCloseKey(hKey);
if (lRet != 0) {
if (lRet != 0)
{
return false;
}
return true;
}
tstring GetWeChatInstallDir() {
TCHAR* szProductType = new TCHAR[MAX_PATH];
GetWeChatInstallInfo((TCHAR*)TEXT("InstallPath"), (void*)szProductType, MAX_PATH);
tstring GetWeChatInstallDir()
{
TCHAR *szProductType = new TCHAR[MAX_PATH];
GetWeChatInstallInfo((TCHAR *)TEXT("InstallPath"), (void *)szProductType, MAX_PATH);
tstring wxdir(szProductType);
delete[] szProductType;
szProductType = NULL;
return wxdir.length() == 0 ? TEXT("") : wxdir;
}
DWORD GetWeChatVerInt() {
DWORD GetWeChatVerInt()
{
DWORD version = 0x0;
GetWeChatInstallInfo((TCHAR*)TEXT("CrashVersion"), (void*)&version, sizeof(DWORD));
GetWeChatInstallInfo((TCHAR *)TEXT("CrashVersion"), (void *)&version, sizeof(DWORD));
return version;
}
tstring GetWeChatVerStr() {
BYTE pversion[4] = { 0 };
GetWeChatInstallInfo((TCHAR*)TEXT("CrashVersion"), (void*)pversion, sizeof(DWORD));
TCHAR* temp = new TCHAR[20];
tstring GetWeChatVerStr()
{
BYTE pversion[4] = {0};
GetWeChatInstallInfo((TCHAR *)TEXT("CrashVersion"), (void *)pversion, sizeof(DWORD));
TCHAR *temp = new TCHAR[20];
_stprintf_s(temp, 20, _T("%d.%d.%d.%d\0"), (int)(pversion[3] - 0x60), (int)pversion[2], (int)pversion[1], (int)pversion[0]);
tstring verStr(temp);
delete[] temp;
......@@ -146,9 +163,9 @@ tstring GetWeChatVerStr() {
return verStr;
}
static bool CloseAllWxProcessMutexHandle()
static bool CloseAllWxProcessMutexHandle()
{
HANDLE hsnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
HANDLE hsnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hsnapshot == INVALID_HANDLE_VALUE)
{
return false;
......@@ -188,37 +205,39 @@ DWORD StartWeChat()
if (procStruct.dwProcessId == 0)
return 0;
DWORD WeChatWinBase = 0;
while ((WeChatWinBase = GetWeChatWinBase(procStruct.dwProcessId)) == 0) {
while ((WeChatWinBase = GetWeChatWinBase(procStruct.dwProcessId)) == 0)
{
Sleep(500);
}
return procStruct.dwProcessId;
}
DWORD GetRemoteProcAddr(DWORD pid, LPWSTR modulename, LPSTR procname) {
DWORD GetRemoteProcAddr(DWORD pid, LPWSTR modulename, LPSTR procname)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
DWORD dwId = 0, dwProcAddr = 0;
unsigned char getremoteprocasmcode[] = {
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;
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;
};
DWORD pGetModuleHandleW = (DWORD)GetModuleHandleW;
DWORD pGetProcAddress = (DWORD)GetProcAddress;
......@@ -227,22 +246,23 @@ DWORD GetRemoteProcAddr(DWORD pid, LPWSTR modulename, LPSTR procname) {
LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_EXECUTE);
if (!pRemoteAddress)
return 0;
*(DWORD*)call1 = pGetModuleHandleW - (DWORD)pRemoteAddress - 14 - 5;
*(DWORD*)call2 = pGetProcAddress - (DWORD)pRemoteAddress - 29 - 5;
*(DWORD *)call1 = pGetModuleHandleW - (DWORD)pRemoteAddress - 14 - 5;
*(DWORD *)call2 = pGetProcAddress - (DWORD)pRemoteAddress - 29 - 5;
SIZE_T dwWriteSize;
WriteProcessMemory(hProcess, pRemoteAddress, getremoteprocasmcode, sizeof(getremoteprocasmcode), &dwWriteSize);
struct GetProcAddrStruct {
struct GetProcAddrStruct
{
DWORD hModuleNameAddr;
DWORD funcnameAddr;
} params;
WeChatData<wchar_t*> r_modulename(hProcess, modulename, TEXTLENGTH(modulename));
WeChatData<char*> r_procname(hProcess, procname, TEXTLENGTHA(procname));
WeChatData<wchar_t *> r_modulename(hProcess, modulename, TEXTLENGTH(modulename));
WeChatData<char *> r_procname(hProcess, procname, TEXTLENGTHA(procname));
params.funcnameAddr = (DWORD)r_procname.GetAddr();
params.hModuleNameAddr = (DWORD)r_modulename.GetAddr();
WeChatData<GetProcAddrStruct*> r_params(hProcess, &params, sizeof(params));
WeChatData<GetProcAddrStruct *> r_params(hProcess, &params, sizeof(params));
if (r_modulename.GetAddr() == 0 || r_procname.GetAddr() == 0 || r_params.GetAddr() == 0)
return 0;
DWORD ret = CallRemoteFunction(hProcess, pRemoteAddress, r_params.GetAddr());
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
return ret;
}
\ No newline at end of file
}
......@@ -28,57 +28,57 @@
#include "DelChatRoomMember.h"
#include "AddChatRoomMember.h"
#define dllname L"DWeChatRobot.dll"
#define DLLNAME L"DWeChatRobot.dll"
#define SendTextRemote "SendTextRemote"
#define SendImageRemote "SendImageRemote"
#define SendFileRemote "SendFileRemote"
#define SendArticleRemote "SendArticleRemote"
#define SendCardRemote "SendCardRemote"
#define SendAtTextRemote "SendAtTextRemote"
#define SendAppMsgRemote "SendAppMsgRemote"
#define SendTextRemote "SendTextRemote"
#define SendImageRemote "SendImageRemote"
#define SendFileRemote "SendFileRemote"
#define SendArticleRemote "SendArticleRemote"
#define SendCardRemote "SendCardRemote"
#define SendAtTextRemote "SendAtTextRemote"
#define SendAppMsgRemote "SendAppMsgRemote"
#define GetFriendListInit "GetFriendListInit"
#define GetFriendListRemote "GetFriendListRemote"
#define GetFriendListFinish "GetFriendListFinish"
#define GetFriendListInit "GetFriendListInit"
#define GetFriendListRemote "GetFriendListRemote"
#define GetFriendListFinish "GetFriendListFinish"
#define EditRemarkRemote "EditRemarkRemote"
#define GetWxUserInfoRemote "GetWxUserInfoRemote"
#define DeleteUserInfoCacheRemote "DeleteUserInfoCacheRemote"
#define EditRemarkRemote "EditRemarkRemote"
#define GetWxUserInfoRemote "GetWxUserInfoRemote"
#define DeleteUserInfoCacheRemote "DeleteUserInfoCacheRemote"
#define GetSelfInfoRemote "GetSelfInfoRemote"
#define DeleteSelfInfoCacheRemote "DeleteSelfInfoCacheRemote"
#define SearchContactByNetRemote "SearchContactByNetRemote"
#define isWxLoginRemote "isWxLogin"
#define GetSelfInfoRemote "GetSelfInfoRemote"
#define DeleteSelfInfoCacheRemote "DeleteSelfInfoCacheRemote"
#define SearchContactByNetRemote "SearchContactByNetRemote"
#define isWxLoginRemote "isWxLogin"
#define VerifyFriendApplyRemote "VerifyFriendApplyRemote"
#define VerifyFriendApplyRemote "VerifyFriendApplyRemote"
#define CheckFriendStatusRemote "CheckFriendStatusRemote"
#define CheckFriendStatusRemote "CheckFriendStatusRemote"
#define HookReceiveMessageRemote "HookReceiveMessage"
#define UnHookReceiveMessageRemote "UnHookReceiveMessage"
#define HookReceiveMessageRemote "HookReceiveMessage"
#define UnHookReceiveMessageRemote "UnHookReceiveMessage"
#define GetChatRoomMemberNicknameRemote "GetChatRoomMemberNicknameRemote"
#define GetChatRoomMembersRemote "GetChatRoomMembersRemote"
#define DelChatRoomMemberRemote "DelChatRoomMemberRemote"
#define AddChatRoomMemberRemote "AddChatRoomMemberRemote"
#define SetChatRoomAnnouncementRemote "SetChatRoomAnnouncementRemote"
#define SetChatRoomNameRemote "SetChatRoomNameRemote"
#define SetChatRoomSelfNicknameRemote "SetChatRoomSelfNicknameRemote"
#define GetChatRoomMemberNicknameRemote "GetChatRoomMemberNicknameRemote"
#define GetChatRoomMembersRemote "GetChatRoomMembersRemote"
#define DelChatRoomMemberRemote "DelChatRoomMemberRemote"
#define AddChatRoomMemberRemote "AddChatRoomMemberRemote"
#define SetChatRoomAnnouncementRemote "SetChatRoomAnnouncementRemote"
#define SetChatRoomNameRemote "SetChatRoomNameRemote"
#define SetChatRoomSelfNicknameRemote "SetChatRoomSelfNicknameRemote"
#define GetDbHandlesRemote "GetDbHandlesRemote"
#define ExecuteSQLRemote "ExecuteSQLRemote"
#define SelectDataRemote "SelectDataRemote"
#define BackupSQLiteDBRemote "BackupSQLiteDBRemote"
#define GetDbHandlesRemote "GetDbHandlesRemote"
#define ExecuteSQLRemote "ExecuteSQLRemote"
#define SelectDataRemote "SelectDataRemote"
#define BackupSQLiteDBRemote "BackupSQLiteDBRemote"
#define AddFriendByWxidRemote "AddFriendByWxidRemote"
#define AddFriendByV3Remote "AddFriendByV3Remote"
#define DeleteUserRemote "DeleteUserRemote"
#define AddBrandContactRemote "AddBrandContactRemote"
#define AddFriendByWxidRemote "AddFriendByWxidRemote"
#define AddFriendByV3Remote "AddFriendByV3Remote"
#define DeleteUserRemote "DeleteUserRemote"
#define AddBrandContactRemote "AddBrandContactRemote"
#define HookImageMsgRemote "HookImageMsgRemote"
#define UnHookImageMsgRemote "UnHookImageMsg"
#define HookVoiceMsgRemote "HookVoiceMsgRemote"
#define UnHookVoiceMsgRemote "UnHookVoiceMsg"
#define HookImageMsgRemote "HookImageMsgRemote"
#define UnHookImageMsgRemote "UnHookImageMsg"
#define HookVoiceMsgRemote "HookVoiceMsgRemote"
#define UnHookVoiceMsgRemote "UnHookVoiceMsg"
#define ChangeWeChatVerRemote "ChangeWeChatVerRemote"
\ No newline at end of file
#define ChangeWeChatVerRemote "ChangeWeChatVerRemote"
#include "pch.h"
static unsigned char GetProcAsmCode[] = {
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;
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 WeChatProcess::GetAsmFunAddr() {
LPVOID WeChatProcess::GetAsmFunAddr()
{
DWORD pGetModuleHandleW = (DWORD)GetModuleHandleW;
DWORD pGetProcAddress = (DWORD)GetProcAddress;
PVOID call1 = (PVOID)&GetProcAsmCode[15];
......@@ -32,32 +33,34 @@ LPVOID WeChatProcess::GetAsmFunAddr() {
LPVOID pAsmFuncAddr = VirtualAllocEx(handle, NULL, 1, MEM_COMMIT, PAGE_EXECUTE);
if (!pAsmFuncAddr)
return 0;
*(DWORD*)call1 = pGetModuleHandleW - (DWORD)pAsmFuncAddr - 14 - 5;
*(DWORD*)call2 = pGetProcAddress - (DWORD)pAsmFuncAddr - 29 - 5;
*(DWORD *)call1 = pGetModuleHandleW - (DWORD)pAsmFuncAddr - 14 - 5;
*(DWORD *)call2 = pGetProcAddress - (DWORD)pAsmFuncAddr - 29 - 5;
SIZE_T dwWriteSize;
WriteProcessMemory(handle, pAsmFuncAddr, GetProcAsmCode, sizeof(GetProcAsmCode), &dwWriteSize);
return pAsmFuncAddr;
}
DWORD WeChatProcess::GetProcAddr(LPSTR functionname) {
DWORD WeChatProcess::GetProcAddr(LPSTR functionname)
{
if (!AsmProcAddr || !handle)
return 0;
WeChatData<wchar_t*> r_modulename(handle, dllname, TEXTLENGTH(dllname));
WeChatData<wchar_t *> r_modulename(handle, DLLNAME, TEXTLENGTH(DLLNAME));
WeChatData<LPSTR> r_functionname(handle, functionname, TEXTLENGTHA(functionname));
DWORD params[2] = { 0 };
DWORD params[2] = {0};
params[0] = (DWORD)r_modulename.GetAddr();
params[1] = (DWORD)r_functionname.GetAddr();
WeChatData<DWORD*> r_params(handle, &params[0], sizeof(params));
WeChatData<DWORD *> r_params(handle, &params[0], sizeof(params));
DWORD dwProcAddr = CallRemoteFunction(handle, AsmProcAddr, r_params.GetAddr());
return dwProcAddr;
}
DWORD WeChatProcess::WeChatRobotBase() {
DWORD WeChatProcess::WeChatRobotBase()
{
if (!handle)
return 0;
WeChatData<wchar_t*> r_dllname(handle, dllname, TEXTLENGTH(dllname));
WeChatData<wchar_t *> r_dllname(handle, DLLNAME, TEXTLENGTH(DLLNAME));
if (r_dllname.GetAddr() == 0)
return 0;
DWORD ret = CallRemoteFunction(handle, GetModuleHandleW, r_dllname.GetAddr());
return ret;
}
\ No newline at end of file
}
#pragma once
#include<windows.h>
#include<iostream>
#include <windows.h>
#include <iostream>
template <typename T1, typename T2, typename T3>
T2 WriteWeChatMemory(T1 hProcess, T2 ptrvalue, T3 size) {
if (!hProcess)
return NULL;
DWORD dwWriteSize;
T2 addr = (T2)VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE);
if (addr)
WriteProcessMemory(hProcess, (LPVOID)addr, ptrvalue, size, &dwWriteSize);
return addr;
T2 WriteWeChatMemory(T1 hProcess, T2 ptrvalue, T3 size)
{
if (!hProcess)
return NULL;
SIZE_T dwWriteSize;
T2 addr = (T2)VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE);
if (addr)
WriteProcessMemory(hProcess, (LPVOID)addr, ptrvalue, size, &dwWriteSize);
return addr;
}
template<typename T1,typename T2,typename T3>
DWORD CallRemoteFunction(T1 hProcess,T2 FunctionAddr,T3 params)
template <typename T1, typename T2, typename T3>
DWORD CallRemoteFunction(T1 hProcess, T2 FunctionAddr, T3 params)
{
DWORD dwRet = 0;
DWORD dwThreadId = 0;
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionAddr, (LPVOID)params, 0, &dwThreadId);
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwRet);
CloseHandle(hThread);
}
else {
return 0;
}
return dwRet;
DWORD dwRet = 0;
DWORD dwThreadId = 0;
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionAddr, (LPVOID)params, 0, &dwThreadId);
if (hThread)
{
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwRet);
CloseHandle(hThread);
}
else
{
return 0;
}
return dwRet;
}
template <typename T>
class WeChatData {
class WeChatData
{
public:
WeChatData(HANDLE hProcess,T data,int size) {
this->hProcess = hProcess;
this->size = size;
if (size == 0)
this->addr = data;
else
this->addr = WriteWeChatMemory(hProcess, data, size);
}
WeChatData(HANDLE hProcess, T data, size_t size)
{
this->hProcess = hProcess;
this->size = size;
if (size == 0)
this->addr = data;
else
this->addr = WriteWeChatMemory(hProcess, data, size);
}
~WeChatData() {
if(this->size)
VirtualFreeEx(this->hProcess, this->addr, 0, MEM_RELEASE);
}
~WeChatData()
{
if (this->size)
VirtualFreeEx(this->hProcess, this->addr, 0, MEM_RELEASE);
}
T GetAddr() {
return this->addr;
}
T GetAddr()
{
return this->addr;
}
private:
T addr;
int size;
HANDLE hProcess;
T addr;
size_t size;
HANDLE hProcess;
};
class WeChatProcess {
class WeChatProcess
{
public:
WeChatProcess(DWORD pid) {
this->handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!this->handle)
m_init = FALSE;
else {
AsmProcAddr = this->GetAsmFunAddr();
m_init = AsmProcAddr != 0 ? TRUE : FALSE;
}
}
~WeChatProcess() {
if (AsmProcAddr)
VirtualFreeEx(handle, AsmProcAddr, 0, MEM_RELEASE);
if(handle)
CloseHandle(handle);
AsmProcAddr = NULL;
handle = NULL;
}
HANDLE GetHandle() {
return this->handle;
}
DWORD GetProcAddr(LPSTR functionname);
DWORD WeChatRobotBase();
BOOL m_init = FALSE;
WeChatProcess(DWORD pid)
{
this->handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!this->handle)
m_init = FALSE;
else
{
AsmProcAddr = this->GetAsmFunAddr();
m_init = AsmProcAddr != 0 ? TRUE : FALSE;
}
}
~WeChatProcess()
{
if (AsmProcAddr)
VirtualFreeEx(handle, AsmProcAddr, 0, MEM_RELEASE);
if (handle)
CloseHandle(handle);
AsmProcAddr = NULL;
handle = NULL;
}
HANDLE GetHandle()
{
return this->handle;
}
DWORD GetProcAddr(LPSTR functionname);
DWORD WeChatRobotBase();
BOOL m_init = FALSE;
private:
HANDLE handle;
LPVOID AsmProcAddr = NULL;
virtual LPVOID GetAsmFunAddr();
HANDLE handle;
LPVOID AsmProcAddr = NULL;
virtual LPVOID GetAsmFunAddr();
};
#include "pch.h"
#define AddPublicNoticeCallOffset 0x1203DB14 - 0x10000000
#define AddPublicNoticeCallOffset 0x1203DB14 - 0x10000000
#define AddPublicNoticeParamOffset 0x7A583DCC - 0x786A0000
struct AddBrandContactStruct {
DWORD handle;
WxString command;
char buffer1[0x28] = { 0 };
WxString params;
char buffer2[0x7C] = { 0 };
AddBrandContactStruct(wchar_t* param) {
command.buffer = (wchar_t*)L"quicklyAddBrandContact";
command.length = wcslen(command.buffer);
command.maxLength = command.length * 2;
params.buffer = param;
params.length = wcslen(param);
params.maxLength = wcslen(param) * 2;
}
struct AddBrandContactStruct
{
DWORD handle;
WxString command;
char buffer1[0x28] = {0};
WxString params;
char buffer2[0x7C] = {0};
AddBrandContactStruct(wchar_t *param)
{
command.buffer = (wchar_t *)L"quicklyAddBrandContact";
command.length = wcslen(command.buffer);
command.maxLength = command.length * 2;
params.buffer = param;
params.length = wcslen(param);
params.maxLength = wcslen(param) * 2;
}
};
BOOL __stdcall AddBrandContact(wchar_t* PublicId) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddPublicNoticeCall = WeChatWinBase + AddPublicNoticeCallOffset;
DWORD AddPublicNoticeParam = WeChatWinBase + AddPublicNoticeParamOffset;
wchar_t url[0x100] = { 0 };
swprintf_s(url, L"weixin://resourceid/Subscription/profile.html?userName=%ws", PublicId);
WxBaseStruct ptrurl(url);
wchar_t param[0x100] = { 0 };
swprintf_s(param, L"{\"username\":\"%ws\",\"webtype\":\"1\"}\n", PublicId);
AddBrandContactStruct ptrparam(param);
ptrparam.handle = AddPublicNoticeParam;
DWORD NoticeCallHandle[10] = { 0 };
NoticeCallHandle[0] = AddPublicNoticeCall;
BOOL isSuccess = 0x0;
__asm {
BOOL __stdcall AddBrandContact(wchar_t *PublicId)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddPublicNoticeCall = WeChatWinBase + AddPublicNoticeCallOffset;
DWORD AddPublicNoticeParam = WeChatWinBase + AddPublicNoticeParamOffset;
wchar_t url[0x100] = {0};
swprintf_s(url, L"weixin://resourceid/Subscription/profile.html?userName=%ws", PublicId);
WxString ptrurl(url);
wchar_t param[0x100] = {0};
swprintf_s(param, L"{\"username\":\"%ws\",\"webtype\":\"1\"}\n", PublicId);
AddBrandContactStruct ptrparam(param);
ptrparam.handle = AddPublicNoticeParam;
DWORD NoticeCallHandle[10] = {0};
NoticeCallHandle[0] = AddPublicNoticeCall;
BOOL isSuccess = 0x0;
__asm {
pushad;
pushfd;
lea eax, ptrparam;
......@@ -49,13 +52,14 @@ BOOL __stdcall AddBrandContact(wchar_t* PublicId) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
return isSuccess;
}
#ifndef USE_SOCKET
BOOL AddBrandContactRemote(LPVOID lpParameter) {
int isSuccess = AddBrandContact((wchar_t*)lpParameter);
return isSuccess;
BOOL AddBrandContactRemote(LPVOID lpParameter)
{
int isSuccess = AddBrandContact((wchar_t *)lpParameter);
return isSuccess;
}
#endif
\ No newline at end of file
#endif
......@@ -7,39 +7,42 @@
#ifndef USE_SOCKET
struct AddChatRoomMemberStruct
{
DWORD chatroomid;
DWORD wxidlist;
DWORD length;
DWORD chatroomid;
DWORD wxidlist;
DWORD length;
};
BOOL AddChatRoomMemberRemote(LPVOID lpParameter) {
AddChatRoomMemberStruct* rp = (AddChatRoomMemberStruct*)lpParameter;
wchar_t* wsChatRoomId = (WCHAR*)rp->chatroomid;
if (rp->length == 0)
return false;
else if(rp->length == 1)
return AddChatRoomMember(wsChatRoomId, (wchar_t**)&rp->wxidlist, rp->length);
else
return AddChatRoomMember(wsChatRoomId, (wchar_t**)rp->wxidlist, rp->length);
BOOL AddChatRoomMemberRemote(LPVOID lpParameter)
{
AddChatRoomMemberStruct *rp = (AddChatRoomMemberStruct *)lpParameter;
wchar_t *wsChatRoomId = (WCHAR *)rp->chatroomid;
if (rp->length == 0)
return false;
else if (rp->length == 1)
return AddChatRoomMember(wsChatRoomId, (wchar_t **)&rp->wxidlist, rp->length);
else
return AddChatRoomMember(wsChatRoomId, (wchar_t **)rp->wxidlist, rp->length);
}
#endif // !USE_SOCKET
BOOL AddChatRoomMember(wchar_t* chatroomid, wchar_t** wxids, int length) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddChatRoomMemeberCall1 = WeChatWinBase + AddChatRoomMemeberCall1Offset;
DWORD AddChatRoomMemeberCall2 = WeChatWinBase + AddChatRoomMemeberCall2Offset;
DWORD AddChatRoomMemeberCall3 = WeChatWinBase + AddChatRoomMemeberCall3Offset;
BOOL AddChatRoomMember(wchar_t *chatroomid, wchar_t **wxids, int length)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddChatRoomMemeberCall1 = WeChatWinBase + AddChatRoomMemeberCall1Offset;
DWORD AddChatRoomMemeberCall2 = WeChatWinBase + AddChatRoomMemeberCall2Offset;
DWORD AddChatRoomMemeberCall3 = WeChatWinBase + AddChatRoomMemeberCall3Offset;
WxBaseStruct pchatroomid(chatroomid);
vector<WxBaseStruct> members;
VectorStruct* vs = (VectorStruct*)&members;
DWORD pmembers = (DWORD)&vs->v_data;
for (int i = 0; i < length; i++) {
WxBaseStruct pwxid(wxids[i]);
members.push_back(pwxid);
}
int isSuccess = 0;
__asm {
WxString pchatroomid(chatroomid);
vector<WxString> members;
VectorStruct *vs = (VectorStruct *)&members;
DWORD pmembers = (DWORD)&vs->v_data;
for (int i = 0; i < length; i++)
{
WxString pwxid(wxids[i]);
members.push_back(pwxid);
}
int isSuccess = 0;
__asm {
pushad;
pushfd;
call AddChatRoomMemeberCall1;
......@@ -56,6 +59,6 @@ BOOL AddChatRoomMember(wchar_t* chatroomid, wchar_t** wxids, int length) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess == 1;
}
\ No newline at end of file
}
return isSuccess == 1;
}
......@@ -11,55 +11,59 @@
// 添加好友参数偏移
#define AddFriendByV3ParamOffset 0x7AA068F4 - 0x786A0000
struct AddFriendByV3ParamStruct {
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = { 0 };
struct AddFriendByV3ParamStruct
{
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = {0};
};
#ifndef USE_SOCKET
struct AddFriendByV3Struct {
wchar_t* wxid;
wchar_t* message;
int AddType;
struct AddFriendByV3Struct
{
wchar_t *wxid;
wchar_t *message;
int AddType;
};
#endif
#ifndef USE_SOCKET
BOOL AddFriendByV3Remote(LPVOID lpParameter) {
AddFriendByV3Struct* afbvs = (AddFriendByV3Struct*)lpParameter;
BOOL isSuccess = AddFriendByV3(afbvs->wxid, afbvs->message,afbvs->AddType);
return isSuccess;
BOOL AddFriendByV3Remote(LPVOID lpParameter)
{
AddFriendByV3Struct *afbvs = (AddFriendByV3Struct *)lpParameter;
BOOL isSuccess = AddFriendByV3(afbvs->wxid, afbvs->message, afbvs->AddType);
return isSuccess;
}
#endif
BOOL __stdcall AddFriendByV3(wchar_t* v3, wchar_t* message,int AddType) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddFriendByV3Call1 = WeChatWinBase + AddFriendByV3Call1Offset;
DWORD AddFriendByV3Call2 = WeChatWinBase + AddFriendByV3Call2Offset;
DWORD AddFriendByV3Call3 = WeChatWinBase + AddFriendByV3Call3Offset;
DWORD AddFriendByV3Call4 = WeChatWinBase + AddFriendByV3Call4Offset;
DWORD AddFriendByV3ParamAddr = WeChatWinBase + AddFriendByV3ParamOffset;
BOOL __stdcall AddFriendByV3(wchar_t *v3, wchar_t *message, int AddType)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddFriendByV3Call1 = WeChatWinBase + AddFriendByV3Call1Offset;
DWORD AddFriendByV3Call2 = WeChatWinBase + AddFriendByV3Call2Offset;
DWORD AddFriendByV3Call3 = WeChatWinBase + AddFriendByV3Call3Offset;
DWORD AddFriendByV3Call4 = WeChatWinBase + AddFriendByV3Call4Offset;
DWORD AddFriendByV3ParamAddr = WeChatWinBase + AddFriendByV3ParamOffset;
WxBaseStruct pv3(v3);
AddFriendByV3ParamStruct AddFriendParam;
WxString pv3(v3);
AddFriendByV3ParamStruct AddFriendParam;
char* sv3 = new char[wcslen(v3) + 1];
ZeroMemory(sv3, wcslen(v3) + 1);
WideCharToMultiByte(CP_ACP, 0, v3, -1, sv3, wcslen(v3), NULL, NULL);
pv3.fill1 = (DWORD)sv3;
pv3.fill2 = wcslen(v3);
wchar_t* pmessage = message ? message : (wchar_t*)L"";
BOOL isSuccess = 0x0;
char *sv3 = new char[wcslen(v3) + 1];
ZeroMemory(sv3, wcslen(v3) + 1);
WideCharToMultiByte(CP_ACP, 0, v3, -1, sv3, wcslen(v3), NULL, NULL);
pv3.fill1 = (DWORD)sv3;
pv3.fill2 = wcslen(v3);
wchar_t *pmessage = message ? message : (wchar_t *)L"";
BOOL isSuccess = 0x0;
__asm {
__asm {
pushad;
pushfd;
// 手机号 0xF,微信号 0x3,QQ号 0x1,wxid 0x6
// 手机号 0xF,微信号 0x3,QQ号 0x1,wxid 0x6
mov edi, [AddType];
mov esi, 0x0;
sub esp, 0x18;
......@@ -94,6 +98,6 @@ BOOL __stdcall AddFriendByV3(wchar_t* v3, wchar_t* message,int AddType) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
\ No newline at end of file
}
return isSuccess;
}
......@@ -11,51 +11,55 @@
// ӺѲƫ
#define AddFriendByWxidParamOffset 0x7AA068F4 - 0x786A0000
struct AddFriendByWxidParamStruct {
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = { 0 };
struct AddFriendByWxidParamStruct
{
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = {0};
};
#ifndef USE_SOCKET
struct AddFriendByWxidStruct {
wchar_t* wxid;
wchar_t* message;
struct AddFriendByWxidStruct
{
wchar_t *wxid;
wchar_t *message;
};
#endif
#ifndef USE_SOCKET
BOOL AddFriendByWxidRemote(LPVOID lpParameter) {
AddFriendByWxidStruct* afbws = (AddFriendByWxidStruct*)lpParameter;
BOOL isSuccess = AddFriendByWxid(afbws->wxid, afbws->message);
return isSuccess;
BOOL AddFriendByWxidRemote(LPVOID lpParameter)
{
AddFriendByWxidStruct *afbws = (AddFriendByWxidStruct *)lpParameter;
BOOL isSuccess = AddFriendByWxid(afbws->wxid, afbws->message);
return isSuccess;
}
#endif
BOOL __stdcall AddFriendByWxid(wchar_t* wxid,wchar_t* message) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddFriendByWxidCall1 = WeChatWinBase + AddFriendByWxidCall1Offset;
DWORD AddFriendByWxidCall2 = WeChatWinBase + AddFriendByWxidCall2Offset;
DWORD AddFriendByWxidCall3 = WeChatWinBase + AddFriendByWxidCall3Offset;
DWORD AddFriendByWxidCall4 = WeChatWinBase + AddFriendByWxidCall4Offset;
DWORD AddFriendByWxidParamAddr = WeChatWinBase + AddFriendByWxidParamOffset;
BOOL __stdcall AddFriendByWxid(wchar_t *wxid, wchar_t *message)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD AddFriendByWxidCall1 = WeChatWinBase + AddFriendByWxidCall1Offset;
DWORD AddFriendByWxidCall2 = WeChatWinBase + AddFriendByWxidCall2Offset;
DWORD AddFriendByWxidCall3 = WeChatWinBase + AddFriendByWxidCall3Offset;
DWORD AddFriendByWxidCall4 = WeChatWinBase + AddFriendByWxidCall4Offset;
DWORD AddFriendByWxidParamAddr = WeChatWinBase + AddFriendByWxidParamOffset;
WxBaseStruct pwxid(wxid);
AddFriendByWxidParamStruct AddFriendParam;
WxString pwxid(wxid);
AddFriendByWxidParamStruct AddFriendParam;
char* swxid = new char[wcslen(wxid) + 1];
ZeroMemory(swxid, wcslen(wxid) + 1);
WideCharToMultiByte(CP_ACP, 0, wxid, -1, swxid, wcslen(wxid), NULL, NULL);
pwxid.fill1 = (DWORD)swxid;
pwxid.fill2 = wcslen(wxid);
wchar_t* pmessage = message ? message : (wchar_t*)L"";
BOOL isSuccess = 0x0;
char *swxid = new char[wcslen(wxid) + 1];
ZeroMemory(swxid, wcslen(wxid) + 1);
WideCharToMultiByte(CP_ACP, 0, wxid, -1, swxid, wcslen(wxid), NULL, NULL);
pwxid.fill1 = (DWORD)swxid;
pwxid.fill2 = wcslen(wxid);
wchar_t *pmessage = message ? message : (wchar_t *)L"";
BOOL isSuccess = 0x0;
__asm {
__asm {
pushad;
pushfd;
mov edi, 0x6;
......@@ -92,6 +96,6 @@ BOOL __stdcall AddFriendByWxid(wchar_t* wxid,wchar_t* message) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
\ No newline at end of file
}
return isSuccess;
}
......@@ -24,7 +24,7 @@ DWORD CheckFriendStatusNextCallAddress = GetWeChatWinBase() + CheckFriendStatusN
DWORD CheckFriendStatusHookJmpBackAddress = GetWeChatWinBase() + CheckFriendStatusHookJmpBackOffset;
// 保存HOOK前的字节码,用于恢复
char OldAsmCode[5] = { 0 };
char OldAsmCode[5] = {0};
// 是否HOOK标志
BOOL CheckFriendStatusHooked = false;
// 保存好友状态码并作为调用返回
......@@ -33,14 +33,15 @@ DWORD LocalFriendStatus = 0x0;
/*
* 用于内存中平衡堆栈
*/
struct FriendStatusParamStruct {
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = { 0 };
struct FriendStatusParamStruct
{
DWORD fill0 = 0x0;
DWORD fill1 = 0x0;
DWORD fill2 = -0x1;
DWORD fill3 = 0x0;
DWORD fill4 = 0x0;
DWORD fill5 = 0xF;
char nullbuffer[0xC] = {0};
};
/*
......@@ -48,17 +49,19 @@ struct FriendStatusParamStruct {
* result:好友状态码
* return:void
*/
void dealVerifyUserResult(DWORD result) {
if (result < 0xB0 || result > 0xB5)
return;
LocalFriendStatus = result;
void dealVerifyUserResult(DWORD result)
{
if (result < 0xB0 || result > 0xB5)
return;
LocalFriendStatus = result;
}
/*
* HOOK的具体实现,记录状态码并跳转到处理函数
*/
__declspec(naked) void doHookVerifyUserResult() {
__asm {
__declspec(naked) void doHookVerifyUserResult()
{
__asm {
pushfd;
pushad;
mov eax, [esi];
......@@ -69,35 +72,37 @@ __declspec(naked) void doHookVerifyUserResult() {
popfd;
call CheckFriendStatusNextCallAddress;
jmp CheckFriendStatusHookJmpBackAddress;
}
}
}
/*
* 开始HOOK好友状态
* return:void
*/
VOID HookFriendStatusCode(){
if (CheckFriendStatusHooked)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
CheckFriendStatusNextCallAddress = WeChatWinBase + CheckFriendStatusNextCallOffset;
CheckFriendStatusHookJmpBackAddress = WeChatWinBase + CheckFriendStatusHookJmpBackOffset;
DWORD dwHookAddress = WeChatWinBase + CheckFriendStatusHookOffset;
HookAnyAddress(dwHookAddress, doHookVerifyUserResult, OldAsmCode);
CheckFriendStatusHooked = true;
VOID HookFriendStatusCode()
{
if (CheckFriendStatusHooked)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
CheckFriendStatusNextCallAddress = WeChatWinBase + CheckFriendStatusNextCallOffset;
CheckFriendStatusHookJmpBackAddress = WeChatWinBase + CheckFriendStatusHookJmpBackOffset;
DWORD dwHookAddress = WeChatWinBase + CheckFriendStatusHookOffset;
HookAnyAddress(dwHookAddress, doHookVerifyUserResult, OldAsmCode);
CheckFriendStatusHooked = true;
}
/*
* 取消HOOK好友状态
* return:void
*/
VOID UnHookFriendStatusCode() {
if (!CheckFriendStatusHooked)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD dwHookAddress = WeChatWinBase + CheckFriendStatusHookOffset;
UnHookAnyAddress(dwHookAddress,OldAsmCode);
CheckFriendStatusHooked = false;
VOID UnHookFriendStatusCode()
{
if (!CheckFriendStatusHooked)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD dwHookAddress = WeChatWinBase + CheckFriendStatusHookOffset;
UnHookAnyAddress(dwHookAddress, OldAsmCode);
CheckFriendStatusHooked = false;
}
#ifndef USE_SOCKET
......@@ -106,9 +111,10 @@ VOID UnHookFriendStatusCode() {
* lparameter:要检查的联系人wxid保存地址
* return:DWORD,好友状态码
*/
DWORD CheckFriendStatusRemote(LPVOID lparameter) {
CheckFriendStatus((wchar_t*)lparameter);
return LocalFriendStatus;
DWORD CheckFriendStatusRemote(LPVOID lparameter)
{
CheckFriendStatus((wchar_t *)lparameter);
return LocalFriendStatus;
}
#endif
......@@ -117,29 +123,30 @@ DWORD CheckFriendStatusRemote(LPVOID lparameter) {
* wxid:要检查的联系人wxid
* return:void
*/
VOID __stdcall CheckFriendStatus(wchar_t* wxid) {
if (!CheckFriendStatusHooked)
HookFriendStatusCode();
LocalFriendStatus = 0x0;
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD CheckFriendStatusCall1 = WeChatWinBase + CheckFriendStatusCall1Offset;
DWORD CheckFriendStatusCall2 = WeChatWinBase + CheckFriendStatusCall2Offset;
DWORD CheckFriendStatusCall3 = WeChatWinBase + CheckFriendStatusCall3Offset;
DWORD CheckFriendStatusCall4 = WeChatWinBase + CheckFriendStatusCall4Offset;
DWORD CheckFriendStatusParam = WeChatWinBase + CheckFriendStatusParamOffset;
VOID __stdcall CheckFriendStatus(wchar_t *wxid)
{
if (!CheckFriendStatusHooked)
HookFriendStatusCode();
LocalFriendStatus = 0x0;
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD CheckFriendStatusCall1 = WeChatWinBase + CheckFriendStatusCall1Offset;
DWORD CheckFriendStatusCall2 = WeChatWinBase + CheckFriendStatusCall2Offset;
DWORD CheckFriendStatusCall3 = WeChatWinBase + CheckFriendStatusCall3Offset;
DWORD CheckFriendStatusCall4 = WeChatWinBase + CheckFriendStatusCall4Offset;
DWORD CheckFriendStatusParam = WeChatWinBase + CheckFriendStatusParamOffset;
WxBaseStruct pwxid(wxid);
FriendStatusParamStruct FriendStatusParam;
WxString pwxid(wxid);
FriendStatusParamStruct FriendStatusParam;
char* swxid = new char[wcslen(wxid) + 1];
ZeroMemory(swxid, wcslen(wxid) + 1);
WideCharToMultiByte(CP_ACP, 0, wxid, -1, swxid, wcslen(wxid), NULL, NULL);
pwxid.fill1 = (DWORD)swxid;
pwxid.fill2 = wcslen(wxid);
char *swxid = new char[wcslen(wxid) + 1];
ZeroMemory(swxid, wcslen(wxid) + 1);
WideCharToMultiByte(CP_ACP, 0, wxid, -1, swxid, wcslen(wxid), NULL, NULL);
pwxid.fill1 = (DWORD)swxid;
pwxid.fill2 = wcslen(wxid);
wchar_t* message = (WCHAR*)L"我是";
wchar_t *message = (WCHAR *)L"我是";
__asm {
__asm {
pushad;
pushfd;
mov edi, 0x6;
......@@ -163,7 +170,7 @@ VOID __stdcall CheckFriendStatus(wchar_t* wxid) {
mov eax, edi;
push eax;
call CheckFriendStatusCall2;
// 这里改成0x2就是添加好友,0x1是请求好友状态
// 这里改成0x2就是添加好友,0x1是请求好友状态
push 0x1;
lea eax, pwxid;
sub esp, 0x14;
......@@ -176,14 +183,15 @@ VOID __stdcall CheckFriendStatus(wchar_t* wxid) {
call CheckFriendStatusCall4;
popfd;
popad;
}
while (!LocalFriendStatus && CheckFriendStatusHooked) {
Sleep(10);
}
}
while (!LocalFriendStatus && CheckFriendStatusHooked)
{
Sleep(10);
}
#ifdef _DEBUG
printf("wxid:%ws,status:0x%02X\n", wxid,LocalFriendStatus);
printf("wxid:%ws,status:0x%02X\n", wxid, LocalFriendStatus);
#endif
delete[] swxid;
swxid = NULL;
return;
}
\ No newline at end of file
delete[] swxid;
swxid = NULL;
return;
}
......@@ -9,6 +9,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SOCKET_Debug|Win32'">
<LocalDebuggerCommandArguments />
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>D:\Tencent\WeChat\WeChat.exe</LocalDebuggerCommand>
<LocalDebuggerCommand>D:\C++\ComWeChatRobot\Debug\socket\server.exe</LocalDebuggerCommand>
</PropertyGroup>
</Project>
\ No newline at end of file
#include "pch.h"
// sqlite3_callback函数指针
typedef int(*sqlite3_callback)(
void*,
int,
char**,
char**
);
typedef int (*sqlite3_callback)(
void *,
int,
char **,
char **);
// sqlite3_exec函数指针
typedef int(__cdecl* Sqlite3_exec)(
DWORD, /* The database on which the SQL executes */
const char*, /* The SQL to be executed */
sqlite3_callback, /* Invoke this callback routine */
void*, /* First argument to xCallback() */
char** /* Write error messages here */
typedef int(__cdecl *Sqlite3_exec)(
DWORD, /* The database on which the SQL executes */
const char *, /* The SQL to be executed */
sqlite3_callback, /* Invoke this callback routine */
void *, /* First argument to xCallback() */
char ** /* Write error messages here */
);
/*
......@@ -23,9 +22,10 @@ typedef int(__cdecl* Sqlite3_exec)(
* ptrSql:保存sql的地址
*/
#ifndef USE_SOCKET
struct executeParams {
DWORD ptrDb;
DWORD ptrSql;
struct executeParams
{
DWORD ptrDb;
DWORD ptrSql;
};
#endif
......@@ -34,12 +34,13 @@ struct executeParams {
* ColName:字段名;l_ColName:`ColName`字符数
* content:字段值;l_content:`content`字符数
*/
struct SQLResultStruct {
char* ColName;
DWORD l_ColName;
char* content;
DWORD l_content;
BOOL isblob;
struct SQLResultStruct
{
char *ColName;
DWORD l_ColName;
char *content;
DWORD l_content;
BOOL isblob;
};
/*
......@@ -47,128 +48,145 @@ struct SQLResultStruct {
* SQLResultAddr:`SQLResult`首成员地址
* length:查询结果条数
*/
struct executeResult {
DWORD SQLResultAddr;
DWORD length;
struct executeResult
{
DWORD SQLResultAddr;
DWORD length;
};
// 外部调用时的具体返回对象
executeResult result = { 0 };
executeResult result = {0};
// 保存查询结果的二维动态数组
vector <vector<SQLResultStruct>> SQLResult;
vector<vector<SQLResultStruct>> SQLResult;
/*
* 获取数据库信息的回调函数
*/
int GetDbInfo(void* data,int argc,char** argv,char** azColName) {
DbInfoStruct* pdata = (DbInfoStruct*)data;
TableInfoStruct tb = { 0 };
if (argv[1])
{
tb.name = new char[strlen(argv[1]) + 1];
memcpy(tb.name,argv[1],strlen(argv[1]) + 1);
}
else {
tb.name = (char*)"NULL";
}
if (argv[2])
{
tb.tbl_name = new char[strlen(argv[2]) + 1];
memcpy(tb.tbl_name, argv[2], strlen(argv[2]) + 1);
}
else {
tb.tbl_name = (char*)"NULL";
}
if (argv[3])
{
tb.rootpage = new char[strlen(argv[3]) + 1];
memcpy(tb.rootpage, argv[3], strlen(argv[3]) + 1);
}
else {
tb.rootpage = (char*)"NULL";
}
if (argv[4])
{
tb.sql = new char[strlen(argv[4]) + 1];
memcpy(tb.sql, argv[4], strlen(argv[4]) + 1);
}
else {
tb.sql = (char*)"NULL";
}
tb.l_name = strlen(tb.name);
tb.l_tbl_name = strlen(tb.tbl_name);
tb.l_sql = strlen(tb.sql);
tb.l_rootpage = strlen(tb.rootpage);
pdata->tables.push_back(tb);
pdata->count = pdata->tables.size();
return 0;
int GetDbInfo(void *data, int argc, char **argv, char **azColName)
{
DbInfoStruct *pdata = (DbInfoStruct *)data;
TableInfoStruct tb = {0};
if (argv[1])
{
tb.name = new char[strlen(argv[1]) + 1];
memcpy(tb.name, argv[1], strlen(argv[1]) + 1);
}
else
{
tb.name = (char *)"NULL";
}
if (argv[2])
{
tb.tbl_name = new char[strlen(argv[2]) + 1];
memcpy(tb.tbl_name, argv[2], strlen(argv[2]) + 1);
}
else
{
tb.tbl_name = (char *)"NULL";
}
if (argv[3])
{
tb.rootpage = new char[strlen(argv[3]) + 1];
memcpy(tb.rootpage, argv[3], strlen(argv[3]) + 1);
}
else
{
tb.rootpage = (char *)"NULL";
}
if (argv[4])
{
tb.sql = new char[strlen(argv[4]) + 1];
memcpy(tb.sql, argv[4], strlen(argv[4]) + 1);
}
else
{
tb.sql = (char *)"NULL";
}
tb.l_name = strlen(tb.name);
tb.l_tbl_name = strlen(tb.tbl_name);
tb.l_sql = strlen(tb.sql);
tb.l_rootpage = strlen(tb.rootpage);
pdata->tables.push_back(tb);
pdata->count = pdata->tables.size();
return 0;
}
/*
* DLL内部查询用的回调函数,直接显示查询结果,用处不大
*/
int query(void* data, int argc, char** argv, char** azColName) {
for (int i = 0; i < argc; i++) {
string content = argv[i] ? UTF8ToGBK(argv[i]) : "NULL";
cout << azColName[i] << " = " << content << endl;
}
printf("\n");
return 0;
int query(void *data, int argc, char **argv, char **azColName)
{
for (int i = 0; i < argc; i++)
{
string content = argv[i] ? utf8_to_gb2312(argv[i]) : "NULL";
cout << azColName[i] << " = " << content << endl;
}
printf("\n");
return 0;
}
/*
* 外部调用时使用的回调函数,将结果存入`SQLResult`中
* return:int,执行成功返回`0`,执行失败返回非0值
*/
int selectdbinfo(void* data, int argc, char** argv, char** azColName) {
executeResult* pdata = (executeResult*)data;
vector<SQLResultStruct> tempStruct;
for (int i = 0; i < argc; i++) {
SQLResultStruct temp = { 0 };
temp.ColName = new char[strlen(azColName[i]) + 1];
memcpy(temp.ColName, azColName[i], strlen(azColName[i]) + 1);
temp.l_ColName = strlen(azColName[i]);
if (argv[i]) {
temp.content = new char[strlen(argv[i]) + 1];
memcpy(temp.content, argv[i], strlen(argv[i]) + 1);
temp.l_content = strlen(argv[i]);
}
else {
temp.content = new char[2];
ZeroMemory(temp.content, 2);
temp.l_content = 0;
}
tempStruct.push_back(temp);
}
SQLResult.push_back(tempStruct);
pdata->length++;
return 0;
int selectdbinfo(void *data, int argc, char **argv, char **azColName)
{
executeResult *pdata = (executeResult *)data;
vector<SQLResultStruct> tempStruct;
for (int i = 0; i < argc; i++)
{
SQLResultStruct temp = {0};
temp.ColName = new char[strlen(azColName[i]) + 1];
memcpy(temp.ColName, azColName[i], strlen(azColName[i]) + 1);
temp.l_ColName = strlen(azColName[i]);
if (argv[i])
{
temp.content = new char[strlen(argv[i]) + 1];
memcpy(temp.content, argv[i], strlen(argv[i]) + 1);
temp.l_content = strlen(argv[i]);
}
else
{
temp.content = new char[2];
ZeroMemory(temp.content, 2);
temp.l_content = 0;
}
tempStruct.push_back(temp);
}
SQLResult.push_back(tempStruct);
pdata->length++;
return 0;
}
/*
* 清空查询结果,释放内存
* return:void
*/
void ClearResultArray() {
if (SQLResult.size() == 0)
return;
for(unsigned int i = 0; i < SQLResult.size(); i++) {
for (unsigned j = 0; j < SQLResult[i].size(); j++) {
SQLResultStruct* sr = (SQLResultStruct*)&SQLResult[i][j];
if (sr->ColName) {
delete sr->ColName;
sr->ColName = NULL;
}
if (sr->content) {
delete sr->content;
sr->content = NULL;
}
}
SQLResult[i].clear();
}
SQLResult.clear();
result.SQLResultAddr = 0;
result.length = 0;
void ClearResultArray()
{
if (SQLResult.size() == 0)
return;
for (unsigned int i = 0; i < SQLResult.size(); i++)
{
for (unsigned j = 0; j < SQLResult[i].size(); j++)
{
SQLResultStruct *sr = (SQLResultStruct *)&SQLResult[i][j];
if (sr->ColName)
{
delete sr->ColName;
sr->ColName = NULL;
}
if (sr->content)
{
delete sr->content;
sr->content = NULL;
}
}
SQLResult[i].clear();
}
SQLResult.clear();
result.SQLResultAddr = 0;
result.length = 0;
}
/*
......@@ -179,14 +197,15 @@ void ClearResultArray() {
* data:传递给回调函数的参数
* return:void*,执行成功返回数组指针,执行失败返回`0`
*/
void* ExecuteSQL(DWORD ptrDb,const char* sql,DWORD callback,void* data) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD sqlite3_execAddr = WeChatWinBase + OffsetFromIdaAddr(IDA_SQLITE3_EXEC_ADDRESS);
Sqlite3_exec p_Sqlite3_exec = (Sqlite3_exec)sqlite3_execAddr;
int status = p_Sqlite3_exec(ptrDb,sql, (sqlite3_callback)callback,data,0);
if (status != SQLITE_OK)
return NULL;
return SQLResult.data();
void *ExecuteSQL(DWORD ptrDb, const char *sql, DWORD callback, void *data)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD sqlite3_execAddr = WeChatWinBase + OffsetFromIdaAddr(IDA_SQLITE3_EXEC_ADDRESS);
Sqlite3_exec p_Sqlite3_exec = (Sqlite3_exec)sqlite3_execAddr;
int status = p_Sqlite3_exec(ptrDb, sql, (sqlite3_callback)callback, data, 0);
if (status != SQLITE_OK)
return NULL;
return SQLResult.data();
}
/*
......@@ -195,95 +214,106 @@ void* ExecuteSQL(DWORD ptrDb,const char* sql,DWORD callback,void* data) {
* return:DWORD,如果SQL执行成功,返回`SQLResult`首成员地址,否则返回0
*/
#ifndef USE_SOCKET
DWORD ExecuteSQLRemote(LPVOID lpParameter){
ClearResultArray();
executeParams* sqlparam = (executeParams*)lpParameter;
void* status = ExecuteSQL(sqlparam->ptrDb, (const char*)sqlparam->ptrSql, (DWORD)selectdbinfo, &result);
if (status != NULL) {
result.SQLResultAddr = (DWORD)SQLResult.data();
return (DWORD)&result;
}
else {
result.length = 0;
}
return 0;
DWORD ExecuteSQLRemote(LPVOID lpParameter)
{
ClearResultArray();
executeParams *sqlparam = (executeParams *)lpParameter;
void *status = ExecuteSQL(sqlparam->ptrDb, (const char *)sqlparam->ptrSql, (DWORD)selectdbinfo, &result);
if (status != NULL)
{
result.SQLResultAddr = (DWORD)SQLResult.data();
return (DWORD)&result;
}
else
{
result.length = 0;
}
return 0;
}
#endif
void* SelectData(DWORD db,const char* sql,void* data)
void *SelectData(DWORD db, const char *sql, void *data)
{
executeResult* pdata = (executeResult*)data;
DWORD wxBaseAddress = GetWeChatWinBase();
Sqlite3_prepare p_Sqlite3_prepare = (Sqlite3_prepare)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_PREPARE_ADDRESS));
Sqlite3_step p_Sqlite3_step = (Sqlite3_step)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_STEP_ADDRESS));
Sqlite3_column_count p_Sqlite3_column_count = (Sqlite3_column_count)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_COUNT_ADDRESS));
Sqlite3_column_name p_Sqlite3_column_name = (Sqlite3_column_name)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_NAME_ADDRESS));
Sqlite3_column_type p_Sqlite3_column_type = (Sqlite3_column_type)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_TYPE_ADDRESS));
Sqlite3_column_blob p_Sqlite3_column_blob = (Sqlite3_column_blob)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_BLOB_ADDRESS));
Sqlite3_column_bytes p_Sqlite3_column_bytes = (Sqlite3_column_bytes)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_BYTES_ADDRESS));
Sqlite3_finalize p_Sqlite3_finalize = (Sqlite3_finalize)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_FINALIZE_ADDRESS));
DWORD* stmt;
int rc = p_Sqlite3_prepare(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK)
return NULL;
while (p_Sqlite3_step(stmt) == SQLITE_ROW)
{
int col_count = p_Sqlite3_column_count(stmt);
vector<SQLResultStruct> tempStruct;
for (int i = 0; i < col_count; i++) {
SQLResultStruct temp = { 0 };
const char* ColName = p_Sqlite3_column_name(stmt, i);
int nType = p_Sqlite3_column_type(stmt, i);
const void* pReadBlobData = p_Sqlite3_column_blob(stmt, i);
int nLength = p_Sqlite3_column_bytes(stmt, i);
temp.ColName = new char[strlen(ColName) + 1];
memcpy(temp.ColName, ColName, strlen(ColName) + 1);
temp.l_ColName = strlen(ColName);
temp.l_content = nLength;
switch (nType)
{
case SQLITE_BLOB: {
temp.content = new char[nLength];
memcpy(temp.content, pReadBlobData, nLength);
temp.isblob = true;
break;
}
default: {
if (nLength != 0) {
temp.content = new char[nLength + 1];
memcpy(temp.content, pReadBlobData, nLength + 1);
}
else {
temp.content = new char[2];
ZeroMemory(temp.content, 2);
}
temp.isblob = false;
break;
}
}
tempStruct.push_back(temp);
}
SQLResult.push_back(tempStruct);
pdata->length++;
}
p_Sqlite3_finalize(stmt);
return SQLResult.data();
executeResult *pdata = (executeResult *)data;
DWORD wxBaseAddress = GetWeChatWinBase();
Sqlite3_prepare p_Sqlite3_prepare = (Sqlite3_prepare)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_PREPARE_ADDRESS));
Sqlite3_step p_Sqlite3_step = (Sqlite3_step)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_STEP_ADDRESS));
Sqlite3_column_count p_Sqlite3_column_count = (Sqlite3_column_count)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_COUNT_ADDRESS));
Sqlite3_column_name p_Sqlite3_column_name = (Sqlite3_column_name)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_NAME_ADDRESS));
Sqlite3_column_type p_Sqlite3_column_type = (Sqlite3_column_type)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_TYPE_ADDRESS));
Sqlite3_column_blob p_Sqlite3_column_blob = (Sqlite3_column_blob)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_BLOB_ADDRESS));
Sqlite3_column_bytes p_Sqlite3_column_bytes = (Sqlite3_column_bytes)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_COLUMN_BYTES_ADDRESS));
Sqlite3_finalize p_Sqlite3_finalize = (Sqlite3_finalize)(wxBaseAddress + OffsetFromIdaAddr(IDA_SQLITE3_FINALIZE_ADDRESS));
DWORD *stmt;
int rc = p_Sqlite3_prepare(db, sql, -1, &stmt, 0);
if (rc != SQLITE_OK)
return NULL;
while (p_Sqlite3_step(stmt) == SQLITE_ROW)
{
int col_count = p_Sqlite3_column_count(stmt);
vector<SQLResultStruct> tempStruct;
for (int i = 0; i < col_count; i++)
{
SQLResultStruct temp = {0};
const char *ColName = p_Sqlite3_column_name(stmt, i);
int nType = p_Sqlite3_column_type(stmt, i);
const void *pReadBlobData = p_Sqlite3_column_blob(stmt, i);
int nLength = p_Sqlite3_column_bytes(stmt, i);
temp.ColName = new char[strlen(ColName) + 1];
memcpy(temp.ColName, ColName, strlen(ColName) + 1);
temp.l_ColName = strlen(ColName);
temp.l_content = nLength;
switch (nType)
{
case SQLITE_BLOB:
{
temp.content = new char[nLength];
memcpy(temp.content, pReadBlobData, nLength);
temp.isblob = true;
break;
}
default:
{
if (nLength != 0)
{
temp.content = new char[nLength + 1];
memcpy(temp.content, pReadBlobData, nLength + 1);
}
else
{
temp.content = new char[2];
ZeroMemory(temp.content, 2);
}
temp.isblob = false;
break;
}
}
tempStruct.push_back(temp);
}
SQLResult.push_back(tempStruct);
pdata->length++;
}
p_Sqlite3_finalize(stmt);
return SQLResult.data();
}
#ifndef USE_SOCKET
int SelectDataRemote(LPVOID lpParameter) {
ClearResultArray();
executeParams* sqlparam = (executeParams*)lpParameter;
void* status = SelectData(sqlparam->ptrDb, (const char*)sqlparam->ptrSql, &result);
int SelectDataRemote(LPVOID lpParameter)
{
ClearResultArray();
executeParams *sqlparam = (executeParams *)lpParameter;
void *status = SelectData(sqlparam->ptrDb, (const char *)sqlparam->ptrSql, &result);
if (status != NULL) {
result.SQLResultAddr = (DWORD)SQLResult.data();
return (DWORD)&result;
}
else {
result.length = 0;
}
return 0;
if (status != NULL)
{
result.SQLResultAddr = (DWORD)SQLResult.data();
return (DWORD)&result;
}
else
{
result.length = 0;
}
return 0;
}
#endif
\ No newline at end of file
#endif
......@@ -7,39 +7,42 @@
#ifndef USE_SOCKET
struct DelChatRoomMemberStruct
{
DWORD chatroomid;
DWORD wxidlist;
DWORD length;
DWORD chatroomid;
DWORD wxidlist;
DWORD length;
};
BOOL DelChatRoomMemberRemote(LPVOID lpParameter) {
DelChatRoomMemberStruct* rp = (DelChatRoomMemberStruct*)lpParameter;
wchar_t* wsChatRoomId = (WCHAR*)rp->chatroomid;
if (rp->length == 0)
return false;
else if(rp->length == 1)
return DelChatRoomMember(wsChatRoomId, (wchar_t**)&rp->wxidlist,rp->length);
else
return DelChatRoomMember(wsChatRoomId, (wchar_t**)rp->wxidlist, rp->length);
BOOL DelChatRoomMemberRemote(LPVOID lpParameter)
{
DelChatRoomMemberStruct *rp = (DelChatRoomMemberStruct *)lpParameter;
wchar_t *wsChatRoomId = (WCHAR *)rp->chatroomid;
if (rp->length == 0)
return false;
else if (rp->length == 1)
return DelChatRoomMember(wsChatRoomId, (wchar_t **)&rp->wxidlist, rp->length);
else
return DelChatRoomMember(wsChatRoomId, (wchar_t **)rp->wxidlist, rp->length);
}
#endif // !USE_SOCKET
BOOL DelChatRoomMember(wchar_t* chatroomid,wchar_t** wxids,int length) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD DelChatRoomMemeberCall1 = WeChatWinBase + DelChatRoomMemeberCall1Offset;
DWORD DelChatRoomMemeberCall2 = WeChatWinBase + DelChatRoomMemeberCall2Offset;
DWORD DelChatRoomMemeberCall3 = WeChatWinBase + DelChatRoomMemeberCall3Offset;
BOOL DelChatRoomMember(wchar_t *chatroomid, wchar_t **wxids, int length)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD DelChatRoomMemeberCall1 = WeChatWinBase + DelChatRoomMemeberCall1Offset;
DWORD DelChatRoomMemeberCall2 = WeChatWinBase + DelChatRoomMemeberCall2Offset;
DWORD DelChatRoomMemeberCall3 = WeChatWinBase + DelChatRoomMemeberCall3Offset;
WxBaseStruct pchatroomid(chatroomid);
vector<WxBaseStruct> members;
VectorStruct* vs = (VectorStruct*)&members;
DWORD pmembers = (DWORD)&vs->v_data;
for (int i = 0; i < length; i++) {
WxBaseStruct pwxid(wxids[i]);
members.push_back(pwxid);
}
int isSuccess = 0;
__asm {
WxString pchatroomid(chatroomid);
vector<WxString> members;
VectorStruct *vs = (VectorStruct *)&members;
DWORD pmembers = (DWORD)&vs->v_data;
for (int i = 0; i < length; i++)
{
WxString pwxid(wxids[i]);
members.push_back(pwxid);
}
int isSuccess = 0;
__asm {
pushad;
pushfd;
call DelChatRoomMemeberCall1;
......@@ -56,6 +59,6 @@ BOOL DelChatRoomMember(wchar_t* chatroomid,wchar_t** wxids,int length) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess == 1;
}
\ No newline at end of file
}
return isSuccess == 1;
}
......@@ -4,16 +4,17 @@
#define DeleteUserCall2Offset 0x100BD5C0 - 0x10000000
#define DeleteUserCall3Offset 0x104685A0 - 0x10000000
BOOL __stdcall DeleteUser(wchar_t* wxid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD DeleteUserCall1 = WeChatWinBase + DeleteUserCall1Offset;
DWORD DeleteUserCall2 = WeChatWinBase + DeleteUserCall2Offset;
DWORD DeleteUserCall3 = WeChatWinBase + DeleteUserCall3Offset;
BOOL __stdcall DeleteUser(wchar_t *wxid)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD DeleteUserCall1 = WeChatWinBase + DeleteUserCall1Offset;
DWORD DeleteUserCall2 = WeChatWinBase + DeleteUserCall2Offset;
DWORD DeleteUserCall3 = WeChatWinBase + DeleteUserCall3Offset;
WxBaseStruct pwxid(wxid);
char buffer[0x70] = { 0 };
BOOL isSuccess = 0x0;
__asm {
WxString pwxid(wxid);
char buffer[0x70] = {0};
BOOL isSuccess = 0x0;
__asm {
pushad;
pushfd;
lea ecx, buffer;
......@@ -27,13 +28,14 @@ BOOL __stdcall DeleteUser(wchar_t* wxid) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
return isSuccess;
}
#ifndef USE_SOCKET
BOOL DeleteUserRemote(LPVOID lpParameter) {
BOOL isSuccess = DeleteUser((wchar_t*)lpParameter);
return isSuccess;
BOOL DeleteUserRemote(LPVOID lpParameter)
{
BOOL isSuccess = DeleteUser((wchar_t *)lpParameter);
return isSuccess;
}
#endif
\ No newline at end of file
#endif
......@@ -3,23 +3,25 @@
#define EditRemarkCallOffset 0x6806F6F0 - 0x67C10000
#ifndef USE_SOCKET
struct EditRemarkStruct {
wchar_t* wxid;
wchar_t* remark;
struct EditRemarkStruct
{
wchar_t *wxid;
wchar_t *remark;
};
BOOL EditRemarkRemote(LPVOID lpParameter) {
EditRemarkStruct* ers = (EditRemarkStruct*)lpParameter;
return EditRemark(ers->wxid,ers->remark);
BOOL EditRemarkRemote(LPVOID lpParameter)
{
EditRemarkStruct *ers = (EditRemarkStruct *)lpParameter;
return EditRemark(ers->wxid, ers->remark);
}
#endif // !USE_SOCKET
BOOL EditRemark(wchar_t* wxid, wchar_t* remark) {
DWORD EditRemarkCall = GetWeChatWinBase() + EditRemarkCallOffset;
WxBaseStruct pwxid(wxid);
WxBaseStruct premark(remark);
int isSuccess = 0;
__asm {
BOOL EditRemark(wchar_t *wxid, wchar_t *remark)
{
DWORD EditRemarkCall = GetWeChatWinBase() + EditRemarkCallOffset;
WxString pwxid(wxid);
WxString premark(remark);
int isSuccess = 0;
__asm {
pushad;
pushfd;
lea eax, premark;
......@@ -30,6 +32,6 @@ BOOL EditRemark(wchar_t* wxid, wchar_t* remark) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess == 1;
}
\ No newline at end of file
}
return isSuccess == 1;
}
......@@ -4,28 +4,31 @@
#define GetChatRoomMemberNicknameCall2Offset 0x792C89A0 - 0x78E80000
#ifndef USE_SOCKET
struct ChatRoomMemberNicknameStruct {
wchar_t* chatroomid;
wchar_t* wxid;
wchar_t* nickname;
struct ChatRoomMemberNicknameStruct
{
wchar_t *chatroomid;
wchar_t *wxid;
wchar_t *nickname;
};
BOOL GetChatRoomMemberNicknameRemote(LPVOID lpParameter) {
ChatRoomMemberNicknameStruct* crmns = (ChatRoomMemberNicknameStruct*)lpParameter;
wstring nickname = GetChatRoomMemberNickname(crmns->chatroomid, crmns->wxid);
memcpy(crmns->nickname,nickname.c_str(),nickname.length() * 2);
return nickname.length() != 0;
BOOL GetChatRoomMemberNicknameRemote(LPVOID lpParameter)
{
ChatRoomMemberNicknameStruct *crmns = (ChatRoomMemberNicknameStruct *)lpParameter;
wstring nickname = GetChatRoomMemberNickname(crmns->chatroomid, crmns->wxid);
memcpy(crmns->nickname, nickname.c_str(), nickname.length() * 2);
return nickname.length() != 0;
}
#endif // !USE_SOCKET
wstring GetChatRoomMemberNickname(wchar_t* chatroomid, wchar_t* wxid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetChatRoomMemberNicknameCall1 = WeChatWinBase + GetChatRoomMemberNicknameCall1Offset;
DWORD GetChatRoomMemberNicknameCall2 = WeChatWinBase + GetChatRoomMemberNicknameCall2Offset;
WxBaseStruct pchatroomid(chatroomid);
WxBaseStruct pwxid(wxid);
WxBaseStruct pnickname(NULL);
__asm {
wstring GetChatRoomMemberNickname(wchar_t *chatroomid, wchar_t *wxid)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetChatRoomMemberNicknameCall1 = WeChatWinBase + GetChatRoomMemberNicknameCall1Offset;
DWORD GetChatRoomMemberNicknameCall2 = WeChatWinBase + GetChatRoomMemberNicknameCall2Offset;
WxString pchatroomid(chatroomid);
WxString pwxid(wxid);
WxString pnickname(NULL);
__asm {
pushad;
pushfd;
call GetChatRoomMemberNicknameCall1;
......@@ -39,15 +42,17 @@ wstring GetChatRoomMemberNickname(wchar_t* chatroomid, wchar_t* wxid) {
call GetChatRoomMemberNicknameCall2;
popfd;
popad;
}
wstring nickname = L"";
if (pnickname.buffer) {
nickname += wstring(pnickname.buffer);
}
else {
wchar_t* buffer = GetUserNickNameByWxId(wxid);
nickname += wstring(buffer);
delete[] buffer;
}
return nickname;
}
\ No newline at end of file
}
wstring nickname = L"";
if (pnickname.buffer)
{
nickname += wstring(pnickname.buffer);
}
else
{
wchar_t *buffer = GetUserNickNameByWxId(wxid);
nickname += wstring(buffer);
delete[] buffer;
}
return nickname;
}
......@@ -14,15 +14,16 @@
* members:群成员wxid字符串,以`^`分隔
* length:members字符串长度
*/
struct ChatRoomInfoStruct {
wchar_t* members = NULL;
DWORD length = 0;
struct ChatRoomInfoStruct
{
wchar_t *members = NULL;
DWORD length = 0;
};
/*
* 外部调用时的具体返回对象
*/
ChatRoomInfoStruct chatroominfo = { 0 };
ChatRoomInfoStruct chatroominfo = {0};
/*
* 供外部调用的获取群成员列表接口
......@@ -30,23 +31,27 @@ ChatRoomInfoStruct chatroominfo = { 0 };
* return:DWORD,调用成功且群成员数量不为0,返回`chatroominfo`首地址,否则返回0
*/
#ifndef USE_SOCKET
DWORD GetChatRoomMembersRemote(LPVOID lparameter) {
wchar_t* chatroomid = (WCHAR*)lparameter;
if (chatroominfo.members != NULL) {
delete[] chatroominfo.members;
chatroominfo.members = NULL;
chatroominfo.length = 0;
}
if (GetChatRoomMembers(chatroomid)) {
DWORD GetChatRoomMembersRemote(LPVOID lparameter)
{
wchar_t *chatroomid = (WCHAR *)lparameter;
if (chatroominfo.members != NULL)
{
delete[] chatroominfo.members;
chatroominfo.members = NULL;
chatroominfo.length = 0;
}
if (GetChatRoomMembers(chatroomid))
{
#ifdef _DEBUG
wcout << chatroominfo.members << endl;
wcout << chatroominfo.members << endl;
#endif
return (DWORD)&chatroominfo.members;
}
else {
return 0;
}
return 0;
return (DWORD)&chatroominfo.members;
}
else
{
return 0;
}
return 0;
}
#endif
......@@ -55,19 +60,20 @@ DWORD GetChatRoomMembersRemote(LPVOID lparameter) {
* chatroomid:群聊ID
* return:BOOL,成功返回`1`,失败返回`0`
*/
BOOL __stdcall GetChatRoomMembers(wchar_t* chatroomid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetChatRoomMembersCall1 = WeChatWinBase + GetChatRoomMembersCall1Offset;
DWORD GetChatRoomMembersCall2 = WeChatWinBase + GetChatRoomMembersCall2Offset;
DWORD GetChatRoomMembersCall3 = WeChatWinBase + GetChatRoomMembersCall3Offset;
DWORD DeleteGetChatRoomMembersCacheCall = WeChatWinBase + DeleteGetChatRoomMembersCacheCallOffset;
BOOL __stdcall GetChatRoomMembers(wchar_t *chatroomid)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetChatRoomMembersCall1 = WeChatWinBase + GetChatRoomMembersCall1Offset;
DWORD GetChatRoomMembersCall2 = WeChatWinBase + GetChatRoomMembersCall2Offset;
DWORD GetChatRoomMembersCall3 = WeChatWinBase + GetChatRoomMembersCall3Offset;
DWORD DeleteGetChatRoomMembersCacheCall = WeChatWinBase + DeleteGetChatRoomMembersCacheCallOffset;
WxBaseStruct wsChatRoomId(chatroomid);
char buffer[0x1E0] = { 0 };
DWORD isSuccess = 0x0;
DWORD DataAddr = 0x0;
WxString wsChatRoomId(chatroomid);
char buffer[0x1E0] = {0};
DWORD isSuccess = 0x0;
DWORD DataAddr = 0x0;
__asm {
__asm {
pushad;
pushfd;
lea ecx, buffer;
......@@ -82,25 +88,26 @@ BOOL __stdcall GetChatRoomMembers(wchar_t* chatroomid) {
mov isSuccess, eax;
popfd;
popad;
}
if (isSuccess) {
char* members = (char*)(*(DWORD*)(DataAddr + 0x1C));
}
if (isSuccess)
{
char *members = (char *)(*(DWORD *)(DataAddr + 0x1C));
#ifdef _DEBUG
cout << members << endl;
cout << members << endl;
#endif
wchar_t* wmembers = new wchar_t[strlen(members) + 1];
ZeroMemory(wmembers, (strlen(members) + 1) * 2);
MultiByteToWideChar(CP_ACP,0,members,-1,wmembers, strlen(members) + 1);
chatroominfo.members = wmembers;
chatroominfo.length = wcslen(wmembers);
}
__asm {
wchar_t *wmembers = new wchar_t[strlen(members) + 1];
ZeroMemory(wmembers, (strlen(members) + 1) * 2);
MultiByteToWideChar(CP_ACP, 0, members, -1, wmembers, strlen(members) + 1);
chatroominfo.members = wmembers;
chatroominfo.length = wcslen(wmembers);
}
__asm {
pushad;
pushfd;
lea ecx, buffer;
call DeleteGetChatRoomMembersCacheCall;
popfd;
popad;
}
return isSuccess;
}
\ No newline at end of file
}
return isSuccess;
}
......@@ -2,6 +2,7 @@
#include <vector>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <map>
#pragma comment(lib, "ws2_32.lib")
......@@ -19,24 +20,28 @@ using namespace std;
// 发送消息HOOK的CALL偏移
#define SendMessageNextCallOffset 0x78AA8170 - 0x786A0000
#define READ_WSTRING(addr, offset) wstring((wchar_t *)(*(DWORD *)(addr + offset)), *(DWORD *)(addr + offset + 0x4))
static int SRVPORT = 0;
struct ScoketMsgStruct {
DWORD pid;
int messagetype;
BOOL isSendMessage;
wchar_t sender[80];
wchar_t wxid[80];
wchar_t message[0x1000B];
wchar_t filepath[MAX_PATH];
wchar_t time[30];
struct ScoketMsgStruct
{
DWORD pid;
int messagetype;
BOOL isSendMessage;
unsigned long long msgid;
wchar_t sender[80];
wchar_t wxid[80];
wchar_t message[0x1000B];
wchar_t filepath[MAX_PATH];
wchar_t time[30];
};
// 是否开启接收消息HOOK标志
BOOL ReceiveMessageHooked = false;
// 保存HOOK前的字节码,用于恢复
char OldReceiveMessageAsmCode[5] = { 0 };
char OldSendMessageAsmCode[5] = { 0 };
char OldReceiveMessageAsmCode[5] = {0};
char OldSendMessageAsmCode[5] = {0};
static DWORD WeChatWinBase = GetWeChatWinBase();
// 接收消息HOOK地址
static DWORD ReceiveMessageHookAddress = WeChatWinBase + ReceiveMessageHookOffset;
......@@ -52,163 +57,156 @@ static DWORD SendMessageNextCall = WeChatWinBase + SendMessageNextCallOffset;
static DWORD SendMessageJmpBackAddress = SendMessageHookAddress + 0x5;
// 通过socket将消息发送给服务端
BOOL SendSocketMessage(ReceiveMsgStruct* ms)
BOOL SendSocketMessage(ReceiveMsgStruct *ms)
{
if (SRVPORT == 0) {
delete ms;
return false;
}
SOCKET clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientsocket < 0)
{
shared_ptr<ReceiveMsgStruct> shared_ms(ms);
if (SRVPORT == 0)
{
return false;
}
SOCKET clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientsocket < 0)
{
#ifdef _DEBUG
cout << "create socket error," << " errno:" << errno << endl;
cout << "create socket error,"
<< " errno:" << errno << endl;
#endif
return false;
}
BOOL status = false;
sockaddr_in clientAddr;
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons((u_short)SRVPORT);
InetPtonA(AF_INET,CLTIP,&clientAddr.sin_addr.s_addr);
return false;
}
BOOL status = false;
sockaddr_in clientAddr;
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons((u_short)SRVPORT);
InetPtonA(AF_INET, CLTIP, &clientAddr.sin_addr.s_addr);
if (connect(clientsocket, reinterpret_cast<sockaddr*>(&clientAddr), sizeof(sockaddr)) < 0)
{
if (connect(clientsocket, reinterpret_cast<sockaddr *>(&clientAddr), sizeof(sockaddr)) < 0)
{
#ifdef _DEBUG
cout << "connect error,"
<< " errno:" << errno << endl;
#endif
return false;
}
char recvbuf[1024] = {0};
auto sms = std::make_shared<ScoketMsgStruct>();
ZeroMemory(sms.get(), sizeof(ScoketMsgStruct));
sms->pid = shared_ms->pid;
sms->messagetype = shared_ms->messagetype;
sms->isSendMessage = shared_ms->isSendMessage;
sms->msgid = shared_ms->msgid;
memcpy(sms->wxid, shared_ms->wxid.c_str(), shared_ms->wxid.length() * 2);
memcpy(sms->sender, shared_ms->sender.c_str(), shared_ms->sender.length() * 2);
memcpy(sms->message, shared_ms->message.c_str(), shared_ms->message.length() * 2);
memcpy(sms->filepath, shared_ms->filepath.c_str(), shared_ms->filepath.length() * 2);
memcpy(sms->time, shared_ms->time.c_str(), shared_ms->time.length() * 2);
#ifdef _DEBUG
cout << "connect error,"<< " errno:" << errno << endl;
wcout << sms->time << endl;
#endif
delete ms;
return false;
}
char recvbuf[1024] = { 0 };
ScoketMsgStruct* sms = new ScoketMsgStruct;
ZeroMemory(sms, sizeof(ScoketMsgStruct));
sms->pid = ms->pid;
sms->messagetype = ms->messagetype;
sms->isSendMessage = ms->isSendMessage;
memcpy(sms->wxid, ms->wxid, ms->l_wxid * 2);
memcpy(sms->sender, ms->sender, ms->l_sender * 2);
memcpy(sms->message, ms->message, ms->l_message * 2);
memcpy(sms->filepath, ms->filepath, ms->l_filepath * 2);
memcpy(sms->time, ms->time, ms->l_time * 2);
wcout << sms->time << endl;
int ret = send(clientsocket, (char*)sms, sizeof(ScoketMsgStruct), 0);
if (ret == -1 || ret == 0)
{
int ret = send(clientsocket, (char *)sms.get(), sizeof(ScoketMsgStruct), 0);
if (ret == -1 || ret == 0)
{
#ifdef _DEBUG
cout << "send fail," << " errno:" << errno << endl;
cout << "send fail,"
<< " errno:" << errno << endl;
#endif
delete ms;
delete sms;
closesocket(clientsocket);
return false;
}
memset(recvbuf, 0, sizeof(recvbuf));
ret = recv(clientsocket, recvbuf, sizeof(recvbuf), 0);
delete ms;
delete sms;
closesocket(clientsocket);
if (ret == -1 || ret == 0)
{
closesocket(clientsocket);
return false;
}
memset(recvbuf, 0, sizeof(recvbuf));
ret = recv(clientsocket, recvbuf, sizeof(recvbuf), 0);
closesocket(clientsocket);
if (ret == -1 || ret == 0)
{
#ifdef _DEBUG
cout << "the server close" << endl;
cout << "the server close" << endl;
#endif
return false;
}
return true;
return false;
}
return true;
}
// 创建广播消息数组
#ifndef USE_SOCKET
static SAFEARRAY* CreateMessageArray(ReceiveMsgStruct* ms) {
HRESULT hr = S_OK;
SAFEARRAY* psaValue;
vector<wstring> MessageInfoKey = {
L"pid",
L"type",
L"isSendMessage",
ms->isSendMessage ? L"sendto" : L"from",
L"wxid",
L"message",
L"filepath",
L"time"
};
SAFEARRAYBOUND rgsaBound[2] = { {MessageInfoKey.size(),0},{2,0} };
psaValue = SafeArrayCreate(VT_VARIANT, 2, rgsaBound);
long keyIndex[2] = { 0,0 };
keyIndex[0] = 0; keyIndex[1] = 0;
for (unsigned int i = 0; i < MessageInfoKey.size(); i++) {
keyIndex[0] = i; keyIndex[1] = 0;
_variant_t key = MessageInfoKey[i].c_str();
hr = SafeArrayPutElement(psaValue, keyIndex, &key);
keyIndex[0] = i; keyIndex[1] = 1;
if (i < 3) {
_variant_t value = ((DWORD*)ms)[i];
hr = SafeArrayPutElement(psaValue, keyIndex, &value);
}
else {
_variant_t value = ((wchar_t**)ms)[i * 2 - 3];
hr = SafeArrayPutElement(psaValue, keyIndex, &value);
}
}
return psaValue;
static SAFEARRAY *CreateMessageArray(map<wstring, _variant_t> msg)
{
HRESULT hr = S_OK;
SAFEARRAY *psaValue;
vector<wstring> MessageInfoKey = {
L"pid",
L"type",
L"isSendMessage",
L"msgid",
msg[L"isSendMessage"].boolVal ? L"sendto" : L"from",
L"wxid",
L"message",
L"filepath",
L"time"};
SAFEARRAYBOUND rgsaBound[2] = {{MessageInfoKey.size(), 0}, {2, 0}};
psaValue = SafeArrayCreate(VT_VARIANT, 2, rgsaBound);
long keyIndex[2] = {0, 0};
keyIndex[0] = 0;
keyIndex[1] = 0;
for (unsigned int i = 0; i < MessageInfoKey.size(); i++)
{
keyIndex[0] = i;
keyIndex[1] = 0;
_variant_t key = MessageInfoKey[i].c_str();
hr = SafeArrayPutElement(psaValue, keyIndex, &key);
keyIndex[0] = i;
keyIndex[1] = 1;
hr = SafeArrayPutElement(psaValue, keyIndex, &msg[MessageInfoKey[i]]);
}
return psaValue;
}
#endif
static void dealMessage(DWORD messageAddr) {
BOOL isSendMessage = *(BOOL*)(messageAddr + 0x3C);
ReceiveMsgStruct* message = new ReceiveMsgStruct;
ZeroMemory(message, sizeof(ReceiveMsgStruct));
message->pid = GetCurrentProcessId();
message->isSendMessage = isSendMessage;
message->time = GetTimeW(*(DWORD*)(messageAddr + 0x44));
message->l_time = wcslen(message->time);
message->messagetype = *(DWORD*)(messageAddr + 0x38);
DWORD length = *(DWORD*)(messageAddr + 0x48 + 0x4);
message->sender = new wchar_t[length + 1];
ZeroMemory(message->sender, (length + 1) * 2);
memcpy(message->sender, (wchar_t*)(*(DWORD*)(messageAddr + 0x48)), length * 2);
message->l_sender = length;
length = *(DWORD*)(messageAddr + 0x170 + 0x4);
if (length == 0) {
message->wxid = new wchar_t[message->l_sender + 1];
ZeroMemory(message->wxid, (message->l_sender + 1) * 2);
memcpy(message->wxid, (wchar_t*)(*(DWORD*)(messageAddr + 0x48)), message->l_sender * 2);
message->l_wxid = message->l_sender;
}
else {
message->wxid = new wchar_t[length + 1];
ZeroMemory(message->wxid, (length + 1) * 2);
memcpy(message->wxid, (wchar_t*)(*(DWORD*)(messageAddr + 0x170)), length * 2);
message->l_wxid = length;
}
length = *(DWORD*)(messageAddr + 0x70 + 0x4);
message->message = new wchar_t[length + 1];
ZeroMemory(message->message, (length + 1) * 2);
memcpy(message->message, (wchar_t*)(*(DWORD*)(messageAddr + 0x70)), length * 2);
message->l_message = length;
length = *(DWORD*)(messageAddr + 0x1AC + 0x4);
message->filepath = new wchar_t[length + 1];
ZeroMemory(message->filepath, (length + 1) * 2);
memcpy(message->filepath, (wchar_t*)(*(DWORD*)(messageAddr + 0x1AC)), length * 2);
message->l_filepath = length;
static void dealMessage(DWORD messageAddr)
{
BOOL isSendMessage = *(BOOL *)(messageAddr + 0x3C);
ReceiveMsgStruct *message = new ReceiveMsgStruct;
ZeroMemory(message, sizeof(ReceiveMsgStruct));
message->pid = GetCurrentProcessId();
message->isSendMessage = isSendMessage;
message->time = GetTimeW(*(DWORD *)(messageAddr + 0x44));
message->messagetype = *(DWORD *)(messageAddr + 0x38);
message->msgid = *(unsigned long long *)(messageAddr + 0x30);
message->sender = READ_WSTRING(messageAddr, 0x48);
int length = *(DWORD *)(messageAddr + 0x170 + 0x4);
if (length == 0)
{
message->wxid = message->sender;
}
else
{
message->wxid = READ_WSTRING(messageAddr, 0x170);
}
message->message = READ_WSTRING(messageAddr, 0x70);
message->filepath = READ_WSTRING(messageAddr, 0x1AC);
#ifdef USE_COM
// 通过连接点,将消息广播给客户端
SAFEARRAY* psaValue = CreateMessageArray(message);
VARIANT vsaValue;
vsaValue.vt = VT_ARRAY | VT_VARIANT;
V_ARRAY(&vsaValue) = psaValue;
PostComMessage(message->pid, WX_MESSAGE, &vsaValue);
// 通过连接点,将消息广播给客户端
map<wstring, _variant_t> msg_map;
msg_map[L"pid"] = message->pid;
msg_map[L"isSendMessage"] = isSendMessage;
msg_map[L"time"] = message->time.c_str();
msg_map[L"type"] = message->messagetype;
msg_map[L"msgid"] = message->msgid;
msg_map[L"sendto"] = message->sender.c_str();
msg_map[L"from"] = message->sender.c_str();
msg_map[L"wxid"] = message->wxid.c_str();
msg_map[L"message"] = message->message.c_str();
msg_map[L"filepath"] = message->filepath.c_str();
SAFEARRAY *psaValue = CreateMessageArray(msg_map);
VARIANT vsaValue;
vsaValue.vt = VT_ARRAY | VT_VARIANT;
V_ARRAY(&vsaValue) = psaValue;
PostComMessage(message->pid, WX_MESSAGE, &vsaValue);
#endif
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, message, NULL, 0);
if (hThread) {
CloseHandle(hThread);
}
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, message, NULL, 0);
if (hThread)
{
CloseHandle(hThread);
}
}
/*
......@@ -216,22 +214,25 @@ static void dealMessage(DWORD messageAddr) {
* messageAddr:保存消息的缓冲区地址
* return:void
*/
VOID ReceiveMessage(DWORD messagesAddr) {
// 此处用于区别是发送的还是接收的消息
DWORD* messages = (DWORD*)messagesAddr;
for (DWORD messageAddr = messages[0]; messageAddr < messages[1]; messageAddr += 0x298) {
dealMessage(messageAddr);
}
VOID ReceiveMessage(DWORD messagesAddr)
{
// 此处用于区别是发送的还是接收的消息
DWORD *messages = (DWORD *)messagesAddr;
for (DWORD messageAddr = messages[0]; messageAddr < messages[1]; messageAddr += 0x298)
{
dealMessage(messageAddr);
}
}
/*
* HOOK的具体实现,接收到消息后调用处理函数
*/
_declspec(naked) void dealReceiveMessage() {
__asm {
_declspec(naked) void dealReceiveMessage()
{
__asm {
pushad;
pushfd;
// mov eax, [edi];
// mov eax, [edi];
push edi;
call ReceiveMessage;
add esp, 0x4;
......@@ -239,14 +240,15 @@ _declspec(naked) void dealReceiveMessage() {
popad;
call ReceiveMessageNextCall;
jmp ReceiveMessageJmpBackAddress;
}
}
}
/*
* HOOK的具体实现,发送消息后调用处理函数
*/
_declspec(naked) void dealSendMessage() {
__asm {
_declspec(naked) void dealSendMessage()
{
__asm {
pushad;
pushfd;
push edi;
......@@ -256,38 +258,40 @@ _declspec(naked) void dealSendMessage() {
popad;
call SendMessageNextCall;
jmp SendMessageJmpBackAddress;
}
}
}
/*
* 开始接收消息HOOK
* return:void
*/
VOID HookReceiveMessage(int port) {
SRVPORT = port;
WeChatWinBase = GetWeChatWinBase();
if (ReceiveMessageHooked || !WeChatWinBase)
return;
ReceiveMessageHookAddress = WeChatWinBase + ReceiveMessageHookOffset;
ReceiveMessageNextCall = WeChatWinBase + ReceiveMessageNextCallOffset;
ReceiveMessageJmpBackAddress = ReceiveMessageHookAddress + 0x5;
SendMessageHookAddress = WeChatWinBase + SendMessageHookOffset;
SendMessageNextCall = WeChatWinBase + SendMessageNextCallOffset;
SendMessageJmpBackAddress = SendMessageHookAddress + 0x5;
HookAnyAddress(ReceiveMessageHookAddress,(LPVOID)dealReceiveMessage,OldReceiveMessageAsmCode);
HookAnyAddress(SendMessageHookAddress, (LPVOID)dealSendMessage, OldSendMessageAsmCode);
ReceiveMessageHooked = TRUE;
VOID HookReceiveMessage(int port)
{
SRVPORT = port;
WeChatWinBase = GetWeChatWinBase();
if (ReceiveMessageHooked || !WeChatWinBase)
return;
ReceiveMessageHookAddress = WeChatWinBase + ReceiveMessageHookOffset;
ReceiveMessageNextCall = WeChatWinBase + ReceiveMessageNextCallOffset;
ReceiveMessageJmpBackAddress = ReceiveMessageHookAddress + 0x5;
SendMessageHookAddress = WeChatWinBase + SendMessageHookOffset;
SendMessageNextCall = WeChatWinBase + SendMessageNextCallOffset;
SendMessageJmpBackAddress = SendMessageHookAddress + 0x5;
HookAnyAddress(ReceiveMessageHookAddress, (LPVOID)dealReceiveMessage, OldReceiveMessageAsmCode);
HookAnyAddress(SendMessageHookAddress, (LPVOID)dealSendMessage, OldSendMessageAsmCode);
ReceiveMessageHooked = TRUE;
}
/*
* 停止接收消息HOOK
* return:void
*/
VOID UnHookReceiveMessage() {
SRVPORT = 0;
if (!ReceiveMessageHooked)
return;
UnHookAnyAddress(ReceiveMessageHookAddress,OldReceiveMessageAsmCode);
UnHookAnyAddress(SendMessageHookAddress, OldSendMessageAsmCode);
ReceiveMessageHooked = FALSE;
}
\ No newline at end of file
VOID UnHookReceiveMessage()
{
SRVPORT = 0;
if (!ReceiveMessageHooked)
return;
UnHookAnyAddress(ReceiveMessageHookAddress, OldReceiveMessageAsmCode);
UnHookAnyAddress(SendMessageHookAddress, OldSendMessageAsmCode);
ReceiveMessageHooked = FALSE;
}
......@@ -20,9 +20,10 @@
* length:wUserInfo字符串长度
*/
#ifndef USE_SOCKET
struct GetUserInfoStruct {
DWORD message;
DWORD length;
struct GetUserInfoStruct
{
DWORD message;
DWORD length;
} ret;
#endif
......@@ -31,51 +32,53 @@ struct GetUserInfoStruct {
* address:缓冲区地址
* return:void
*/
static wstring WxUserInfo(DWORD address) {
wstring wUserInfo = L"";
vector<DWORD> InfoType{
address + 0x10,
address + 0x24,
address + 0x38,
address + 0x58,
address + 0x6C,
address + 0xFC,
address + 0x110,
address + 0x19C,
address + 0x1B0,
address + 0x1C4,
address + 0x1D8,
address + 0x27C
};
vector<wchar_t*> InfoTypeName{
(WCHAR*)L"\"wxId\"",
(WCHAR*)L"\"wxNumber\"",
(WCHAR*)L"\"wxV3\"",
(WCHAR*)L"\"wxRemark\"",
(WCHAR*)L"\"wxNickName\"",
(WCHAR*)L"\"wxBigAvatar\"",
(WCHAR*)L"\"wxSmallAvatar\"",
(WCHAR*)L"\"wxSignature\"",
(WCHAR*)L"\"wxNation\"",
(WCHAR*)L"\"wxProvince\"",
(WCHAR*)L"\"wxCity\"",
(WCHAR*)L"\"wxBackground\"",
};
wUserInfo += L"{";
for (unsigned int i = 0; i < InfoType.size(); i++) {
wchar_t* wstemp = ((*((DWORD*)InfoType[i])) != 0) ? (WCHAR*)(*((LPVOID*)InfoType[i])) : (WCHAR*)L"null";
wstring wsrtemp = wreplace(wstemp,L'\"',L"\\\"");
wUserInfo = wUserInfo + InfoTypeName[i] + L":\"" + wsrtemp + L"\"";
if (i != InfoType.size() - 1) {
wUserInfo += L",";
}
}
wUserInfo += L"}";
static wstring WxUserInfo(DWORD address)
{
wstring wUserInfo = L"";
vector<DWORD> InfoType{
address + 0x10,
address + 0x24,
address + 0x38,
address + 0x58,
address + 0x6C,
address + 0xFC,
address + 0x110,
address + 0x19C,
address + 0x1B0,
address + 0x1C4,
address + 0x1D8,
address + 0x27C};
vector<wchar_t *> InfoTypeName{
(WCHAR *)L"\"wxId\"",
(WCHAR *)L"\"wxNumber\"",
(WCHAR *)L"\"wxV3\"",
(WCHAR *)L"\"wxRemark\"",
(WCHAR *)L"\"wxNickName\"",
(WCHAR *)L"\"wxBigAvatar\"",
(WCHAR *)L"\"wxSmallAvatar\"",
(WCHAR *)L"\"wxSignature\"",
(WCHAR *)L"\"wxNation\"",
(WCHAR *)L"\"wxProvince\"",
(WCHAR *)L"\"wxCity\"",
(WCHAR *)L"\"wxBackground\"",
};
wUserInfo += L"{";
for (unsigned int i = 0; i < InfoType.size(); i++)
{
wchar_t *wstemp = ((*((DWORD *)InfoType[i])) != 0) ? (WCHAR *)(*((LPVOID *)InfoType[i])) : (WCHAR *)L"null";
wstring wsrtemp = wreplace(wstemp, L'\"', L"\\\"");
wUserInfo = wUserInfo + InfoTypeName[i] + L":\"" + wsrtemp + L"\"";
if (i != InfoType.size() - 1)
{
wUserInfo += L",";
}
}
wUserInfo += L"}";
#ifdef _DEBUG
wcout.imbue(locale("chs"));
wcout << wUserInfo.c_str() << endl;
wcout.imbue(locale("chs"));
wcout << wUserInfo.c_str() << endl;
#endif
return wUserInfo;
return wUserInfo;
}
/*
......@@ -84,17 +87,18 @@ static wstring WxUserInfo(DWORD address) {
* return:DWORD,`ret`的首地址
*/
#ifndef USE_SOCKET
DWORD GetWxUserInfoRemote(LPVOID lparamter) {
wchar_t* userwxid = (wchar_t*)lparamter;
wstring wUserInfo = GetUserInfoByWxId(userwxid);
DWORD GetWxUserInfoRemote(LPVOID lparamter)
{
wchar_t *userwxid = (wchar_t *)lparamter;
ZeroMemory(&ret, sizeof(GetUserInfoStruct));
wchar_t* message = new wchar_t[wUserInfo.length() + 1];
memcpy(message, wUserInfo.c_str(), (wUserInfo.length() + 1) * 2);
ret.message = (DWORD)message;
ret.length = wUserInfo.length();
return (DWORD)&ret;
wstring wUserInfo = GetUserInfoByWxId(userwxid);
ZeroMemory(&ret, sizeof(GetUserInfoStruct));
wchar_t *message = new wchar_t[wUserInfo.length() + 1];
memcpy(message, wUserInfo.c_str(), (wUserInfo.length() + 1) * 2);
ret.message = (DWORD)message;
ret.length = wUserInfo.length();
return (DWORD)&ret;
}
#endif
/*
......@@ -102,11 +106,13 @@ DWORD GetWxUserInfoRemote(LPVOID lparamter) {
* return:void
*/
#ifndef USE_SOCKET
VOID DeleteUserInfoCacheRemote() {
if (ret.length) {
delete[](wchar_t*)ret.message;
ZeroMemory(&ret, sizeof(GetUserInfoStruct));
}
VOID DeleteUserInfoCacheRemote()
{
if (ret.length)
{
delete[](wchar_t *) ret.message;
ZeroMemory(&ret, sizeof(GetUserInfoStruct));
}
}
#endif
......@@ -115,20 +121,21 @@ VOID DeleteUserInfoCacheRemote() {
* wxid:好友wxid
* return:wstring,成功返回好友信息,失败返回空字符串
*/
wstring __stdcall GetUserInfoByWxId(wchar_t* wxid) {
wstring wUserInfo = L"";
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
char buffer[0x3FC] = { 0 };
WxBaseStruct pWxid(wxid);
DWORD address = 0;
DWORD isSuccess = 0;
__asm
{
wstring __stdcall GetUserInfoByWxId(wchar_t *wxid)
{
wstring wUserInfo = L"";
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
char buffer[0x3FC] = {0};
WxString pWxid(wxid);
DWORD address = 0;
DWORD isSuccess = 0;
__asm
{
pushad;
call WxGetUserInfoCall1;
lea ebx, buffer;
......@@ -144,12 +151,12 @@ wstring __stdcall GetUserInfoByWxId(wchar_t* wxid) {
mov isSuccess, eax;
mov address, ebx;
popad;
}
if(isSuccess)
wUserInfo = WxUserInfo(address);
}
if (isSuccess)
wUserInfo = WxUserInfo(address);
char deletebuffer[0x410] = { 0 };
__asm {
char deletebuffer[0x410] = {0};
__asm {
pushad;
lea ecx, deletebuffer;
call DeleteUserInfoCacheCall1;
......@@ -158,8 +165,8 @@ wstring __stdcall GetUserInfoByWxId(wchar_t* wxid) {
mov ecx, ebx;
call DeleteUserInfoCacheCall2;
popad;
}
return wUserInfo;
}
return wUserInfo;
}
/*
......@@ -167,19 +174,20 @@ wstring __stdcall GetUserInfoByWxId(wchar_t* wxid) {
* wxid:联系人wxid
* return:wchar_t*,获取到的wxid
*/
wchar_t* __stdcall GetUserNickNameByWxId(wchar_t* wxid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
char buffer[0x3FC] = { 0 };
WxBaseStruct pWxid(wxid);
DWORD address = 0;
DWORD isSuccess = 0;
__asm
{
wchar_t *__stdcall GetUserNickNameByWxId(wchar_t *wxid)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
char buffer[0x3FC] = {0};
WxString pWxid(wxid);
DWORD address = 0;
DWORD isSuccess = 0;
__asm
{
pushad;
call WxGetUserInfoCall1;
lea ebx, buffer;
......@@ -195,16 +203,17 @@ wchar_t* __stdcall GetUserNickNameByWxId(wchar_t* wxid) {
mov isSuccess, eax;
mov address, ebx;
popad;
}
wchar_t* NickName = NULL;
if (isSuccess) {
DWORD length = *(DWORD*)(address + 0x6C + 0x4);
NickName = new wchar_t[length + 1];
ZeroMemory(NickName, (length + 1) * 2);
memcpy(NickName, (wchar_t*)(*(DWORD*)(address + 0x6C)), length * 2);
}
char deletebuffer[0x410] = { 0 };
__asm {
}
wchar_t *NickName = NULL;
if (isSuccess)
{
DWORD length = *(DWORD *)(address + 0x6C + 0x4);
NickName = new wchar_t[length + 1];
ZeroMemory(NickName, (length + 1) * 2);
memcpy(NickName, (wchar_t *)(*(DWORD *)(address + 0x6C)), length * 2);
}
char deletebuffer[0x410] = {0};
__asm {
pushad;
lea ecx, deletebuffer;
call DeleteUserInfoCacheCall1;
......@@ -213,6 +222,6 @@ wchar_t* __stdcall GetUserNickNameByWxId(wchar_t* wxid) {
mov ecx, ebx;
call DeleteUserInfoCacheCall2;
popad;
}
return NickName;
}
\ No newline at end of file
}
return NickName;
}
......@@ -10,8 +10,8 @@
#define HookUserInfoNextCallOffset 0x1031B770 - 0x10000000
static BOOL SearchContactHooked = false;
static char HookSearchContactErrcodeOldAsm[5] = { 0 };
static char HookUserInfoOldAsm[5] = { 0 };
static char HookSearchContactErrcodeOldAsm[5] = {0};
static char HookUserInfoOldAsm[5] = {0};
static DWORD WeChatWinBase = GetWeChatWinBase();
static UserInfo userinfo;
......@@ -24,97 +24,100 @@ DWORD HookUserInfoNextCall = WeChatWinBase + HookUserInfoNextCallOffset;
DWORD HookUserInfoAddr = WeChatWinBase + HookUserInfoAddrOffset;
DWORD HookUserInfoJmpBackAddr = HookUserInfoAddr + 0x5;
void GetNetUserInfoFromMemory(DWORD address) {
DWORD length = *(DWORD*)(address + 0x8);
userinfo.keyword = new wchar_t[length + 1];
userinfo.l_keyword = length;
if (length)
memcpy(userinfo.keyword, (wchar_t*)(*(DWORD*)(address + 0x4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.keyword, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x1C);
userinfo.v3 = new wchar_t[length + 1];
userinfo.l_v3 = length;
if (length)
memcpy(userinfo.v3, (wchar_t*)(*(DWORD*)(address + 0x18)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.v3, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x30);
userinfo.BigAvatar = new wchar_t[length + 1];
userinfo.l_BigAvatar = length;
if (length)
memcpy(userinfo.BigAvatar, (wchar_t*)(*(DWORD*)(address + 0x2C)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.BigAvatar, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0xC8);
userinfo.NickName = new wchar_t[length + 1];
userinfo.l_NickName = length;
if (length)
memcpy(userinfo.NickName, (wchar_t*)(*(DWORD*)(address + 0xC4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.NickName, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x108);
userinfo.v2 = new wchar_t[length + 1];
userinfo.l_v2 = 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 + 0x16C);
userinfo.SmallAvatar = new wchar_t[length + 1];
userinfo.l_SmallAvatar = length;
if (length)
memcpy(userinfo.SmallAvatar, (wchar_t*)(*(DWORD*)(address + 0x168)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.SmallAvatar, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x1F8);
userinfo.Signature = new wchar_t[length + 1];
userinfo.l_Signature = length;
if (length)
memcpy(userinfo.Signature, (wchar_t*)(*(DWORD*)(address + 0x1F4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Signature, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x20C);
userinfo.Nation = new wchar_t[length + 1];
userinfo.l_Nation = length;
if (length)
memcpy(userinfo.Nation, (wchar_t*)(*(DWORD*)(address + 0x208)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Nation, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x220);
userinfo.Province = new wchar_t[length + 1];
userinfo.l_Province = length;
if (length)
memcpy(userinfo.Province, (wchar_t*)(*(DWORD*)(address + 0x21C)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Province, (length + 1) * sizeof(wchar_t));
length = *(DWORD*)(address + 0x234);
userinfo.City = new wchar_t[length + 1];
userinfo.l_City = length;
if (length)
memcpy(userinfo.City, (wchar_t*)(*(DWORD*)(address + 0x230)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.City, (length + 1) * sizeof(wchar_t));
userinfo.sex = *(DWORD*)(address + 0x1BC);
userinfo.over = true;
void GetNetUserInfoFromMemory(DWORD address)
{
DWORD length = *(DWORD *)(address + 0x8);
userinfo.keyword = new wchar_t[length + 1];
userinfo.l_keyword = length;
if (length)
memcpy(userinfo.keyword, (wchar_t *)(*(DWORD *)(address + 0x4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.keyword, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x1C);
userinfo.v3 = new wchar_t[length + 1];
userinfo.l_v3 = length;
if (length)
memcpy(userinfo.v3, (wchar_t *)(*(DWORD *)(address + 0x18)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.v3, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x30);
userinfo.BigAvatar = new wchar_t[length + 1];
userinfo.l_BigAvatar = length;
if (length)
memcpy(userinfo.BigAvatar, (wchar_t *)(*(DWORD *)(address + 0x2C)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.BigAvatar, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0xC8);
userinfo.NickName = new wchar_t[length + 1];
userinfo.l_NickName = length;
if (length)
memcpy(userinfo.NickName, (wchar_t *)(*(DWORD *)(address + 0xC4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.NickName, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x108);
userinfo.v2 = new wchar_t[length + 1];
userinfo.l_v2 = 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 + 0x16C);
userinfo.SmallAvatar = new wchar_t[length + 1];
userinfo.l_SmallAvatar = length;
if (length)
memcpy(userinfo.SmallAvatar, (wchar_t *)(*(DWORD *)(address + 0x168)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.SmallAvatar, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x1F8);
userinfo.Signature = new wchar_t[length + 1];
userinfo.l_Signature = length;
if (length)
memcpy(userinfo.Signature, (wchar_t *)(*(DWORD *)(address + 0x1F4)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Signature, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x20C);
userinfo.Nation = new wchar_t[length + 1];
userinfo.l_Nation = length;
if (length)
memcpy(userinfo.Nation, (wchar_t *)(*(DWORD *)(address + 0x208)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Nation, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x220);
userinfo.Province = new wchar_t[length + 1];
userinfo.l_Province = length;
if (length)
memcpy(userinfo.Province, (wchar_t *)(*(DWORD *)(address + 0x21C)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.Province, (length + 1) * sizeof(wchar_t));
length = *(DWORD *)(address + 0x234);
userinfo.City = new wchar_t[length + 1];
userinfo.l_City = length;
if (length)
memcpy(userinfo.City, (wchar_t *)(*(DWORD *)(address + 0x230)), (length + 1) * sizeof(wchar_t));
else
ZeroMemory(userinfo.City, (length + 1) * sizeof(wchar_t));
userinfo.sex = *(DWORD *)(address + 0x1BC);
userinfo.over = true;
}
void ChangeSearchContactErrcode(int errcode) {
userinfo.errcode = errcode;
void ChangeSearchContactErrcode(int errcode)
{
userinfo.errcode = errcode;
}
__declspec(naked) void dealSearchContactErrcode() {
__asm {
__declspec(naked) void dealSearchContactErrcode()
{
__asm {
pushad;
pushfd;
push edi;
......@@ -124,11 +127,12 @@ __declspec(naked) void dealSearchContactErrcode() {
popad;
call HookSearchContactErrcodeNextCall;
jmp HookSearchContactErrcodeJmpBackAddr;
}
}
}
__declspec(naked) void dealUserInfo() {
__asm {
__declspec(naked) void dealUserInfo()
{
__asm {
pushad;
pushfd;
push dword ptr [ebp + 0x14];
......@@ -138,77 +142,90 @@ __declspec(naked) void dealUserInfo() {
popad;
call HookUserInfoNextCall;
jmp HookUserInfoJmpBackAddr;
}
}
}
static void HookSearchContact() {
WeChatWinBase = GetWeChatWinBase();
if (SearchContactHooked || WeChatWinBase == 0)
return;
HookSearchContactErrcodeNextCall = WeChatWinBase + HookSearchContactErrcodeNextCallOffset;
HookSearchContactErrcodeAddr = WeChatWinBase + HookSearchContactErrcodeAddrOffset;
HookSearchContactErrcodeJmpBackAddr = HookSearchContactErrcodeAddr + 0x5;
HookUserInfoNextCall = WeChatWinBase + HookUserInfoNextCallOffset;
HookUserInfoAddr = WeChatWinBase + HookUserInfoAddrOffset;
HookUserInfoJmpBackAddr = HookUserInfoAddr + 0x5;
HookAnyAddress(HookSearchContactErrcodeAddr, (LPVOID)dealSearchContactErrcode, HookSearchContactErrcodeOldAsm);
HookAnyAddress(HookUserInfoAddr,(LPVOID)dealUserInfo, HookUserInfoOldAsm);
SearchContactHooked = true;
}
static void HookSearchContact()
{
WeChatWinBase = GetWeChatWinBase();
if (SearchContactHooked || WeChatWinBase == 0)
return;
HookSearchContactErrcodeNextCall = WeChatWinBase + HookSearchContactErrcodeNextCallOffset;
HookSearchContactErrcodeAddr = WeChatWinBase + HookSearchContactErrcodeAddrOffset;
HookSearchContactErrcodeJmpBackAddr = HookSearchContactErrcodeAddr + 0x5;
void UnHookSearchContact() {
if (!SearchContactHooked)
return;
UnHookAnyAddress(HookSearchContactErrcodeAddr, HookSearchContactErrcodeOldAsm);
UnHookAnyAddress(HookUserInfoAddr, HookUserInfoOldAsm);
SearchContactHooked = false;
HookUserInfoNextCall = WeChatWinBase + HookUserInfoNextCallOffset;
HookUserInfoAddr = WeChatWinBase + HookUserInfoAddrOffset;
HookUserInfoJmpBackAddr = HookUserInfoAddr + 0x5;
HookAnyAddress(HookSearchContactErrcodeAddr, (LPVOID)dealSearchContactErrcode, HookSearchContactErrcodeOldAsm);
HookAnyAddress(HookUserInfoAddr, (LPVOID)dealUserInfo, HookUserInfoOldAsm);
SearchContactHooked = true;
}
static void DeleteUserInfoCache() {
if (userinfo.keyword) {
delete userinfo.keyword;
}
if (userinfo.v2) {
delete userinfo.v2;
}
if (userinfo.v3) {
delete userinfo.v3;
}
if (userinfo.NickName) {
delete userinfo.NickName;
}
if (userinfo.Nation) {
delete userinfo.Nation;
}
if (userinfo.Province) {
delete userinfo.Province;
}
if (userinfo.City) {
delete userinfo.City;
}
if (userinfo.Signature) {
delete userinfo.Signature;
}
if (userinfo.SmallAvatar) {
delete userinfo.SmallAvatar;
}
if (userinfo.BigAvatar) {
delete userinfo.BigAvatar;
}
ZeroMemory(&userinfo, sizeof(UserInfo));
userinfo.errcode = 1;
void UnHookSearchContact()
{
if (!SearchContactHooked)
return;
UnHookAnyAddress(HookSearchContactErrcodeAddr, HookSearchContactErrcodeOldAsm);
UnHookAnyAddress(HookUserInfoAddr, HookUserInfoOldAsm);
SearchContactHooked = false;
}
static void DeleteUserInfoCache()
{
if (userinfo.keyword)
{
delete userinfo.keyword;
}
if (userinfo.v2)
{
delete userinfo.v2;
}
if (userinfo.v3)
{
delete userinfo.v3;
}
if (userinfo.NickName)
{
delete userinfo.NickName;
}
if (userinfo.Nation)
{
delete userinfo.Nation;
}
if (userinfo.Province)
{
delete userinfo.Province;
}
if (userinfo.City)
{
delete userinfo.City;
}
if (userinfo.Signature)
{
delete userinfo.Signature;
}
if (userinfo.SmallAvatar)
{
delete userinfo.SmallAvatar;
}
if (userinfo.BigAvatar)
{
delete userinfo.BigAvatar;
}
ZeroMemory(&userinfo, sizeof(UserInfo));
userinfo.errcode = 1;
}
void* __stdcall SearchContactByNet(wchar_t* keyword) {
HookSearchContact();
DeleteUserInfoCache();
DWORD SearchContactByNetCall1 = GetWeChatWinBase() + SearchContactByNetCall1Offset;
DWORD SearchContactByNetCall2 = GetWeChatWinBase() + SearchContactByNetCall2Offset;
WxBaseStruct pkeyword(keyword);
void *__stdcall SearchContactByNet(wchar_t *keyword)
{
HookSearchContact();
DeleteUserInfoCache();
DWORD SearchContactByNetCall1 = GetWeChatWinBase() + SearchContactByNetCall1Offset;
DWORD SearchContactByNetCall2 = GetWeChatWinBase() + SearchContactByNetCall2Offset;
WxString pkeyword(keyword);
__asm {
__asm {
pushad;
pushfd;
call SearchContactByNetCall1;
......@@ -218,26 +235,29 @@ void* __stdcall SearchContactByNet(wchar_t* keyword) {
call SearchContactByNetCall2;
popfd;
popad;
}
while (userinfo.errcode == 1 && SearchContactHooked)
{
Sleep(50);
}
if (userinfo.errcode == 0) {
while (userinfo.over == false && SearchContactHooked) {
Sleep(50);
}
}
while (userinfo.errcode == 1 && SearchContactHooked)
{
Sleep(50);
}
if (userinfo.errcode == 0)
{
while (userinfo.over == false && SearchContactHooked)
{
Sleep(50);
}
#ifdef _DEBUG
wcout << userinfo.v2 << endl;
wcout << userinfo.v3 << endl;
wcout << userinfo.v2 << endl;
wcout << userinfo.v3 << endl;
#endif
}
return &userinfo;
}
return &userinfo;
}
#ifndef USE_SOCKET
DWORD SearchContactByNetRemote(LPVOID keyword) {
SearchContactByNet((wchar_t*)keyword);
return (DWORD)&userinfo;
DWORD SearchContactByNetRemote(LPVOID keyword)
{
SearchContactByNet((wchar_t *)keyword);
return (DWORD)&userinfo;
}
#endif
\ No newline at end of file
#endif
......@@ -5,26 +5,28 @@
#define SendAppMsgCall3Offset 0x78E5CB30 - 0x786A0000
#ifndef USE_SOCKET
struct SendAppMsgStruct {
wchar_t* wxid;
wchar_t* appid;
struct SendAppMsgStruct
{
wchar_t *wxid;
wchar_t *appid;
};
#endif
BOOL __stdcall SendAppMsg(wchar_t* wxid,wchar_t* appid) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendAppMsgCall1 = WeChatWinBase + SendAppMsgCall1Offset;
DWORD SendAppMsgCall2 = WeChatWinBase + SendAppMsgCall2Offset;
DWORD SendAppMsgCall3 = WeChatWinBase + SendAppMsgCall3Offset;
vector<WxBaseStruct> receiver;
VectorStruct* vs = (VectorStruct*)&receiver;
DWORD preceiver = (DWORD)&vs->v_data;
WxBaseStruct pwxid(wxid);
receiver.push_back(pwxid);
WxBaseStruct pappid(appid);
char buffer[0x1E0] = { 0 };
BOOL isSuccess = 0x0;
__asm {
BOOL __stdcall SendAppMsg(wchar_t *wxid, wchar_t *appid)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendAppMsgCall1 = WeChatWinBase + SendAppMsgCall1Offset;
DWORD SendAppMsgCall2 = WeChatWinBase + SendAppMsgCall2Offset;
DWORD SendAppMsgCall3 = WeChatWinBase + SendAppMsgCall3Offset;
vector<WxString> receiver;
VectorStruct *vs = (VectorStruct *)&receiver;
DWORD preceiver = (DWORD)&vs->v_data;
WxString pwxid(wxid);
receiver.push_back(pwxid);
WxString pappid(appid);
char buffer[0x1E0] = {0};
BOOL isSuccess = 0x0;
__asm {
pushad;
pushfd;
push 0x60966;
......@@ -44,14 +46,15 @@ BOOL __stdcall SendAppMsg(wchar_t* wxid,wchar_t* appid) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
return isSuccess;
}
#ifndef USE_SOCKET
BOOL SendAppMsgRemote(LPVOID lpParameter) {
SendAppMsgStruct* sams = (SendAppMsgStruct*)lpParameter;
BOOL isSuccess = SendAppMsg(sams->wxid, sams->appid);
return isSuccess;
BOOL SendAppMsgRemote(LPVOID lpParameter)
{
SendAppMsgStruct *sams = (SendAppMsgStruct *)lpParameter;
BOOL isSuccess = SendAppMsg(sams->wxid, sams->appid);
return isSuccess;
}
#endif
\ No newline at end of file
#endif
......@@ -24,12 +24,13 @@
* url:文章链接的保存地址
*/
#ifndef USE_SOCKET
struct SendArticleStruct {
DWORD wxid;
DWORD title;
DWORD abstract;
DWORD url;
DWORD imgpath;
struct SendArticleStruct
{
DWORD wxid;
DWORD title;
DWORD abstract;
DWORD url;
DWORD imgpath;
};
#endif
......@@ -39,14 +40,15 @@ struct SendArticleStruct {
* return:void
*/
#ifndef USE_SOCKET
VOID SendArticleRemote(LPVOID lparameter) {
SendArticleStruct* sas = (SendArticleStruct*)lparameter;
wchar_t* wxid = (wchar_t*)sas->wxid;
wchar_t* title = (wchar_t*)sas->title;
wchar_t* abstract = (wchar_t*)sas->abstract;
wchar_t* url = (wchar_t*)sas->url;
wchar_t* imgpath = sas->imgpath ? (wchar_t*)sas->imgpath : NULL;
SendArticle(wxid,title,abstract,url, imgpath);
VOID SendArticleRemote(LPVOID lparameter)
{
SendArticleStruct *sas = (SendArticleStruct *)lparameter;
wchar_t *wxid = (wchar_t *)sas->wxid;
wchar_t *title = (wchar_t *)sas->title;
wchar_t *abstract = (wchar_t *)sas->abstract;
wchar_t *url = (wchar_t *)sas->url;
wchar_t *imgpath = sas->imgpath ? (wchar_t *)sas->imgpath : NULL;
SendArticle(wxid, title, abstract, url, imgpath);
}
#endif
......@@ -58,40 +60,42 @@ VOID SendArticleRemote(LPVOID lparameter) {
* url:文章链接
* return:BOOL,成功返回`1`,失败返回`0`
*/
BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url,wchar_t* imgpath) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendArticleCall1 = WeChatWinBase + SendArticleCall1Offset;
DWORD SendArticleCall2 = WeChatWinBase + SendArticleCall2Offset;
DWORD SendArticleCall3 = WeChatWinBase + SendArticleCall3Offset;
DWORD SendArticleCall4 = WeChatWinBase + SendArticleCall4Offset;
BOOL __stdcall SendArticle(wchar_t *wxid, wchar_t *title, wchar_t *abstract, wchar_t *url, wchar_t *imgpath)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendArticleCall1 = WeChatWinBase + SendArticleCall1Offset;
DWORD SendArticleCall2 = WeChatWinBase + SendArticleCall2Offset;
DWORD SendArticleCall3 = WeChatWinBase + SendArticleCall3Offset;
DWORD SendArticleCall4 = WeChatWinBase + SendArticleCall4Offset;
DWORD SendArticleParam = WeChatWinBase + SendArticleParamOffset;
DWORD SendArticleParam = WeChatWinBase + SendArticleParamOffset;
DWORD SendArticleClearCacheCall1 = WeChatWinBase + SendArticleClearCacheCall1Offset;
DWORD SendArticleClearCacheCall2 = WeChatWinBase + SendArticleClearCacheCall2Offset;
// 自己的wxid,发送者
wstring wselfwxid = GetSelfWxid();
// 构造xml数据
wchar_t* xmlbuffer = new wchar_t[0x2000];
ZeroMemory(xmlbuffer, 0x2000 * 2);
swprintf_s(xmlbuffer,0x2000, (wchar_t*)L"<msg>\n <fromusername>%ws</fromusername>\n <scene>0</scene>\n <commenturl></commenturl>\n <appmsg appid=\"\" sdkver=\"0\">\n <title>%ws</title>\n <des>%ws</des>\n <action>view</action>\n <type>5</type>\n <showtype>0</showtype>\n <content></content>\n <url>%ws</url>\n <dataurl></dataurl>\n <lowurl></lowurl>\n <lowdataurl></lowdataurl>\n <recorditem>\n <![CDATA[]]>\n </recorditem>\n <thumburl></thumburl>\n <messageaction></messageaction>\n <extinfo></extinfo>\n <sourceusername></sourceusername>\n <sourcedisplayname></sourcedisplayname>\n <commenturl></commenturl>\n <appattach>\n <totallen>0</totallen>\n <attachid></attachid>\n <emoticonmd5></emoticonmd5>\n <fileext></fileext>\n <aeskey></aeskey>\n </appattach>\n <weappinfo>\n <pagepath></pagepath>\n <username></username>\n <appid></appid>\n <appservicetype>0</appservicetype>\n </weappinfo>\n <websearch />\n </appmsg>\n <appinfo>\n <version>1</version>\n <appname>Window wechat</appname>\n </appinfo>\n</msg>",
wselfwxid.c_str(),title,abstract,url);
DWORD SendArticleClearCacheCall1 = WeChatWinBase + SendArticleClearCacheCall1Offset;
DWORD SendArticleClearCacheCall2 = WeChatWinBase + SendArticleClearCacheCall2Offset;
// 自己的wxid,发送者
wstring wselfwxid = GetSelfWxid();
// 构造xml数据
wchar_t *xmlbuffer = new wchar_t[0x2000];
ZeroMemory(xmlbuffer, 0x2000 * 2);
swprintf_s(xmlbuffer, 0x2000, (wchar_t *)L"<msg>\n <fromusername>%ws</fromusername>\n <scene>0</scene>\n <commenturl></commenturl>\n <appmsg appid=\"\" sdkver=\"0\">\n <title>%ws</title>\n <des>%ws</des>\n <action>view</action>\n <type>5</type>\n <showtype>0</showtype>\n <content></content>\n <url>%ws</url>\n <dataurl></dataurl>\n <lowurl></lowurl>\n <lowdataurl></lowdataurl>\n <recorditem>\n <![CDATA[]]>\n </recorditem>\n <thumburl></thumburl>\n <messageaction></messageaction>\n <extinfo></extinfo>\n <sourceusername></sourceusername>\n <sourcedisplayname></sourcedisplayname>\n <commenturl></commenturl>\n <appattach>\n <totallen>0</totallen>\n <attachid></attachid>\n <emoticonmd5></emoticonmd5>\n <fileext></fileext>\n <aeskey></aeskey>\n </appattach>\n <weappinfo>\n <pagepath></pagepath>\n <username></username>\n <appid></appid>\n <appservicetype>0</appservicetype>\n </weappinfo>\n <websearch />\n </appmsg>\n <appinfo>\n <version>1</version>\n <appname>Window wechat</appname>\n </appinfo>\n</msg>",
wselfwxid.c_str(), title, abstract, url);
DWORD sendtype = 0x5;
WxBaseStruct pSender((wchar_t*)wselfwxid.c_str());
char nullbuffer[0x1C] = { 0 };
WxBaseStruct pXml(xmlbuffer);
WxBaseStruct pReceiver(wxid);
WxString imgbuffer = { 0 };
if (imgpath) {
imgbuffer.buffer = imgpath;
imgbuffer.length = wcslen(imgpath);
imgbuffer.maxLength = wcslen(imgpath) * 2;
}
WxString nullStruct = { 0 };
char buffer[0xFF0] = { 0 };
DWORD isSuccess = 0x0;
__asm {
DWORD sendtype = 0x5;
WxString pSender((wchar_t *)wselfwxid.c_str());
char nullbuffer[0x1C] = {0};
WxString pXml(xmlbuffer);
WxString pReceiver(wxid);
WxString imgbuffer = {0};
if (imgpath)
{
imgbuffer.buffer = imgpath;
imgbuffer.length = wcslen(imgpath);
imgbuffer.maxLength = wcslen(imgpath) * 2;
}
WxString nullStruct = {0};
char buffer[0xFF0] = {0};
DWORD isSuccess = 0x0;
__asm {
pushad;
pushfd;
lea ecx, buffer;
......@@ -127,8 +131,8 @@ BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wcha
call SendArticleClearCacheCall2;
popfd;
popad;
}
delete[] xmlbuffer;
xmlbuffer = NULL;
return (isSuccess == 0x1);
}
\ No newline at end of file
}
delete[] xmlbuffer;
xmlbuffer = NULL;
return (isSuccess == 0x1);
}
......@@ -19,7 +19,7 @@ struct SendAtTextStruct
DWORD wxidlist;
DWORD wxmsg;
DWORD length;
BOOL AutoNickName;
BOOL AutoNickName;
};
#endif
......@@ -31,7 +31,8 @@ struct SendAtTextStruct
* addr_end1:数组尾地址
* addr_end2:数组尾地址
*/
struct AtStruct {
struct AtStruct
{
DWORD AtUser;
DWORD addr_end1;
DWORD addr_end2;
......@@ -43,16 +44,17 @@ struct AtStruct {
* return:void
*/
#ifndef USE_SOCKET
void SendAtTextRemote(LPVOID lpParameter) {
SendAtTextStruct* rp = (SendAtTextStruct*)lpParameter;
wchar_t* wsChatRoomId = (WCHAR*)rp->chatroomid;
wchar_t* wsTextMsg = (WCHAR*)rp->wxmsg;
void SendAtTextRemote(LPVOID lpParameter)
{
SendAtTextStruct *rp = (SendAtTextStruct *)lpParameter;
wchar_t *wsChatRoomId = (WCHAR *)rp->chatroomid;
wchar_t *wsTextMsg = (WCHAR *)rp->wxmsg;
if (rp->length == 0)
return;
else if (rp->length == 1)
SendAtText(wsChatRoomId, (DWORD*)&rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
SendAtText(wsChatRoomId, (DWORD *)&rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
else
SendAtText(wsChatRoomId, (DWORD*)rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
SendAtText(wsChatRoomId, (DWORD *)rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
}
#endif
......@@ -65,26 +67,30 @@ void SendAtTextRemote(LPVOID lpParameter) {
* AutoNickName:是否自动填充被艾特人昵称
* return:void
*/
void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsTextMsg,int length,BOOL AutoNickName) {
void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsTextMsg, int length, BOOL AutoNickName)
{
// +1的作用是补充一个空结构体,将`AtStruct`尾地址设定为空结构的首地址即可
WxString* AtUsers = new WxString[length + 1];
WxString *AtUsers = new WxString[length + 1];
wstring AtMessage = L"";
int querySuccess = 0;
for (int i = 0; i < length; i++) {
wchar_t* nickname = NULL;
if (!lstrcmpW((wchar_t*)wsWxId[i], (wchar_t*)L"notify@all")) {
nickname = (wchar_t*)L"所有人";
for (int i = 0; i < length; i++)
{
wchar_t *nickname = NULL;
if (!lstrcmpW((wchar_t *)wsWxId[i], (wchar_t *)L"notify@all"))
{
nickname = (wchar_t *)L"所有人";
}
else
nickname = GetUserNickNameByWxId((wchar_t*)wsWxId[i]);
nickname = GetUserNickNameByWxId((wchar_t *)wsWxId[i]);
if (!nickname)
continue;
WxString temp = { 0 };
temp.buffer = (wchar_t*)wsWxId[i];
temp.length = wcslen((wchar_t*)wsWxId[i]);
temp.maxLength = wcslen((wchar_t*)wsWxId[i]) * 2;
WxString temp = {0};
temp.buffer = (wchar_t *)wsWxId[i];
temp.length = wcslen((wchar_t *)wsWxId[i]);
temp.maxLength = wcslen((wchar_t *)wsWxId[i]) * 2;
memcpy(&AtUsers[querySuccess], &temp, sizeof(WxString));
if (AutoNickName) {
if (AutoNickName)
{
AtMessage = AtMessage + L"@" + nickname + L" ";
}
querySuccess++;
......@@ -92,15 +98,15 @@ void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsText
AtMessage += wsTextMsg;
if (!querySuccess)
return;
WxBaseStruct wxChatRoomId(wsChatRoomId);
WxBaseStruct wxTextMsg((wchar_t*)AtMessage.c_str());
AtStruct at = { 0 };
WxString wxChatRoomId(wsChatRoomId);
WxString wxTextMsg((wchar_t *)AtMessage.c_str());
AtStruct at = {0};
at.AtUser = (DWORD)AtUsers;
at.addr_end1 = (DWORD)&AtUsers[querySuccess];
at.addr_end2 = (DWORD)&AtUsers[querySuccess];
wchar_t** pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = { 0 };
wchar_t **pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = {0};
DWORD dllBaseAddress = GetWeChatWinBase();
DWORD callAddress = dllBaseAddress + SendAtTextCallOffset;
......@@ -121,4 +127,4 @@ void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsText
}
delete[] AtUsers;
AtUsers = NULL;
}
\ No newline at end of file
}
......@@ -12,10 +12,11 @@
* nickname:名片显示的昵称保存地址
*/
#ifndef USE_SOCKET
struct SendCardStruct {
DWORD receiver;
DWORD sharedwxid;
DWORD nickname;
struct SendCardStruct
{
DWORD receiver;
DWORD sharedwxid;
DWORD nickname;
};
#endif
......@@ -25,12 +26,13 @@ struct SendCardStruct {
* return:void
*/
#ifndef USE_SOCKET
VOID SendCardRemote(LPVOID lparameter) {
SendCardStruct* scs = (SendCardStruct*)lparameter;
wchar_t* receiver = (WCHAR*)scs->receiver;
wchar_t* sharedwxid = (WCHAR*)scs->sharedwxid;
wchar_t* nickname = (WCHAR*)scs->nickname;
SendCard(receiver,sharedwxid,nickname);
VOID SendCardRemote(LPVOID lparameter)
{
SendCardStruct *scs = (SendCardStruct *)lparameter;
wchar_t *receiver = (WCHAR *)scs->receiver;
wchar_t *sharedwxid = (WCHAR *)scs->sharedwxid;
wchar_t *nickname = (WCHAR *)scs->nickname;
SendCard(receiver, sharedwxid, nickname);
}
#endif
......@@ -41,20 +43,21 @@ VOID SendCardRemote(LPVOID lparameter) {
* nickname:名片显示的昵称
* return:BOOL,发送成功返回`0`,发送失败返回`1`
*/
BOOL __stdcall SendCard(wchar_t* receiver, wchar_t* sharedwxid, wchar_t* nickname) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendCardCall = WeChatWinBase + SendCardCallOffset;
DWORD DeleteCardCacheCall = WeChatWinBase + DeleteCardCacheCallOffset;
wchar_t* xml = new wchar_t[0x2000];
ZeroMemory(xml, 0x2000 * 2);
swprintf_s(xml, 0x2000,L"<?xml version=\"1.0\"?><msg bigheadimgurl=\"\" smallheadimgurl=\"\" username=\"%ws\" nickname=\"%ws\" fullpy=\"?\" shortpy=\"\" alias=\"%ws\" imagestatus=\"3\" scene=\"17\" province=\"北京\" city=\"中国\" sign=\"\" sex=\"2\" certflag=\"0\" certinfo=\"\" brandIconUrl=\"\" brandHomeUrl=\"\" brandSubscriptConfigUrl= \"\" brandFlags=\"0\" regionCode=\"CN_BeiJing_BeiJing\" />",
sharedwxid, nickname, sharedwxid);
WxBaseStruct pReceiver(receiver);
WxBaseStruct pXml(xml);
char buffer[0x2D0] = { 0 };
DWORD isSuccess = 0x1;
BOOL __stdcall SendCard(wchar_t *receiver, wchar_t *sharedwxid, wchar_t *nickname)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendCardCall = WeChatWinBase + SendCardCallOffset;
DWORD DeleteCardCacheCall = WeChatWinBase + DeleteCardCacheCallOffset;
wchar_t *xml = new wchar_t[0x2000];
ZeroMemory(xml, 0x2000 * 2);
swprintf_s(xml, 0x2000, L"<?xml version=\"1.0\"?><msg bigheadimgurl=\"\" smallheadimgurl=\"\" username=\"%ws\" nickname=\"%ws\" fullpy=\"?\" shortpy=\"\" alias=\"%ws\" imagestatus=\"3\" scene=\"17\" province=\"北京\" city=\"中国\" sign=\"\" sex=\"2\" certflag=\"0\" certinfo=\"\" brandIconUrl=\"\" brandHomeUrl=\"\" brandSubscriptConfigUrl= \"\" brandFlags=\"0\" regionCode=\"CN_BeiJing_BeiJing\" />",
sharedwxid, nickname, sharedwxid);
WxString pReceiver(receiver);
WxString pXml(xml);
char buffer[0x2D0] = {0};
DWORD isSuccess = 0x1;
__asm {
__asm {
pushad;
push 0x2A;
lea eax, pXml;
......@@ -68,8 +71,8 @@ BOOL __stdcall SendCard(wchar_t* receiver, wchar_t* sharedwxid, wchar_t* nicknam
call DeleteCardCacheCall;
mov isSuccess, eax;
popad;
}
delete[] xml;
xml = NULL;
return isSuccess;
}
\ No newline at end of file
}
delete[] xml;
xml = NULL;
return isSuccess;
}
......@@ -15,9 +15,10 @@
* filepath:文件绝对路径的保存地址
*/
#ifndef USE_SOCKET
struct FileParamStruct {
DWORD wxid;
DWORD filepath;
struct FileParamStruct
{
DWORD wxid;
DWORD filepath;
};
#endif
......@@ -30,18 +31,20 @@ struct FileParamStruct {
* fill:占位用空缓冲区
* WxFileStruct:默认构造函数
*/
struct WxFileStruct {
int type = 3;
wchar_t* buffer;
DWORD length;
DWORD maxLength;
char fill[0x34] = { 0 };
struct WxFileStruct
{
int type = 3;
wchar_t *buffer;
DWORD length;
DWORD maxLength;
char fill[0x34] = {0};
WxFileStruct(wchar_t* pStr) {
buffer = pStr;
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
WxFileStruct(wchar_t *pStr)
{
buffer = pStr;
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
};
/*
......@@ -50,9 +53,10 @@ struct WxFileStruct {
* return:void
*/
#ifndef USE_SOCKET
void SendFileRemote(LPVOID lpParamStruct) {
FileParamStruct* params = (FileParamStruct*)lpParamStruct;
SendFile((WCHAR*)params->wxid, (WCHAR*)params->filepath);
void SendFileRemote(LPVOID lpParamStruct)
{
FileParamStruct *params = (FileParamStruct *)lpParamStruct;
SendFile((WCHAR *)params->wxid, (WCHAR *)params->filepath);
}
#endif
......@@ -62,26 +66,27 @@ void SendFileRemote(LPVOID lpParamStruct) {
* FilePath:文件绝对路径
* return:void
*/
void __stdcall SendFile(wchar_t* receiver, wchar_t* FilePath) {
WxBaseStruct pReceiver(receiver);
WxBaseStruct pFilePath(FilePath);
WxFileStruct esi_(FilePath);
WxString nullbuffer = { 0 };
void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath)
{
WxString pReceiver(receiver);
WxString pFilePath(FilePath);
WxFileStruct esi_(FilePath);
WxString nullbuffer = {0};
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD WxSendFileCall1 = WeChatWinBase + SendFileCall1Offset;
DWORD WxSendFileCall2 = WeChatWinBase + SendFileCall2Offset;
DWORD WxSendFileCall3 = WeChatWinBase + SendFileCall3Offset;
DWORD DeleteSendFileCacheCall = WeChatWinBase + DeleteSendFileCacheCallOffset;
DWORD WxSendFileParams = 0;
char buffer[0x3B0] = { 0 };
DWORD WxSendFileCall1 = WeChatWinBase + SendFileCall1Offset;
DWORD WxSendFileCall2 = WeChatWinBase + SendFileCall2Offset;
DWORD WxSendFileCall3 = WeChatWinBase + SendFileCall3Offset;
DWORD DeleteSendFileCacheCall = WeChatWinBase + DeleteSendFileCacheCallOffset;
DWORD WxSendFileParams = 0;
DWORD edi_ = pReceiver.length;
DWORD ptrReceiver = (DWORD)pReceiver.buffer;
char buffer[0x3B0] = {0};
__asm {
DWORD edi_ = pReceiver.length;
DWORD ptrReceiver = (DWORD)pReceiver.buffer;
__asm {
pushad;
pushfd;
call WxSendFileCall1;
......@@ -117,5 +122,5 @@ void __stdcall SendFile(wchar_t* receiver, wchar_t* FilePath) {
call DeleteSendFileCacheCall;
popfd;
popad;
}
}
\ No newline at end of file
}
}
......@@ -15,9 +15,10 @@
* imagepath:保存图片绝对路径的地址
*/
#ifndef USE_SOCKET
struct ImageParamStruct {
DWORD wxid;
DWORD imagepath;
struct ImageParamStruct
{
DWORD wxid;
DWORD imagepath;
};
#endif
......@@ -27,9 +28,10 @@ struct ImageParamStruct {
* return:void
*/
#ifndef USE_SOCKET
void SendImageRemote(LPVOID lpParamStruct) {
ImageParamStruct* params = (ImageParamStruct*)lpParamStruct;
SendImage((WCHAR*)params->wxid, (WCHAR*)params->imagepath);
void SendImageRemote(LPVOID lpParamStruct)
{
ImageParamStruct *params = (ImageParamStruct *)lpParamStruct;
SendImage((WCHAR *)params->wxid, (WCHAR *)params->imagepath);
}
#endif
......@@ -39,20 +41,21 @@ void SendImageRemote(LPVOID lpParamStruct) {
* ImagePath:图片绝对路径
* return:void
*/
void __stdcall SendImage(wchar_t* receiver, wchar_t* ImagePath) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendImageCall1 = WeChatWinBase + SendImageCall1Offset;
DWORD SendImageCall2 = WeChatWinBase + SendImageCall2Offset;
DWORD SendImageCall3 = WeChatWinBase + SendImageCall3Offset;
DWORD DeleteSendImageCacheCall = WeChatWinBase + DeleteSendImageCacheCallOffset;
char nullbuffer[0x50] = { 0 };
char buffer[0x3B0] = { 0 };
WxBaseStruct pReceiver(receiver);
WxBaseStruct pImagePath(ImagePath);
WxString nullStruct = { 0 };
DWORD tempeax = 0;
__asm {
void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendImageCall1 = WeChatWinBase + SendImageCall1Offset;
DWORD SendImageCall2 = WeChatWinBase + SendImageCall2Offset;
DWORD SendImageCall3 = WeChatWinBase + SendImageCall3Offset;
DWORD DeleteSendImageCacheCall = WeChatWinBase + DeleteSendImageCacheCallOffset;
char nullbuffer[0x50] = {0};
char buffer[0x3B0] = {0};
WxString pReceiver(receiver);
WxString pImagePath(ImagePath);
WxString nullStruct = {0};
DWORD tempeax = 0;
__asm {
pushad;
call SendImageCall1;
sub esp, 0x14;
......@@ -72,5 +75,5 @@ void __stdcall SendImage(wchar_t* receiver, wchar_t* ImagePath) {
lea ecx, buffer;
call DeleteSendImageCacheCall;
popad;
}
}
\ No newline at end of file
}
}
......@@ -24,10 +24,11 @@ struct SendTextStruct
* return:void
*/
#ifndef USE_SOCKET
void SendTextRemote(LPVOID lpParameter) {
SendTextStruct* rp = (SendTextStruct*)lpParameter;
wchar_t* wsWxId = (WCHAR*)rp->wxid;
wchar_t* wsTextMsg = (WCHAR*)rp->wxmsg;
void SendTextRemote(LPVOID lpParameter)
{
SendTextStruct *rp = (SendTextStruct *)lpParameter;
wchar_t *wsWxId = (WCHAR *)rp->wxid;
wchar_t *wsTextMsg = (WCHAR *)rp->wxmsg;
SendText(wsWxId, wsTextMsg);
}
#endif
......@@ -38,13 +39,14 @@ void SendTextRemote(LPVOID lpParameter) {
* wsTextMsg:发送的消息内容
* return:void
*/
void __stdcall SendText(wchar_t* wsWxId, wchar_t* wsTextMsg) {
WxBaseStruct wxWxid(wsWxId);
WxBaseStruct wxTextMsg(wsTextMsg);
wchar_t** pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = { 0 };
void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg)
{
WxString wxWxid(wsWxId);
WxString wxTextMsg(wsTextMsg);
wchar_t **pWxmsg = &wxTextMsg.buffer;
char buffer[0x3B0] = {0};
WxString wxNull = { 0 };
WxString wxNull = {0};
DWORD dllBaseAddress = GetWeChatWinBase();
DWORD callAddress = dllBaseAddress + SendTextCallOffset;
DWORD DeleteTextCacheCall = dllBaseAddress + DeleteTextCacheCallOffset;
......@@ -64,4 +66,4 @@ void __stdcall SendText(wchar_t* wsWxId, wchar_t* wsTextMsg) {
call DeleteTextCacheCall;
popad;
}
}
\ No newline at end of file
}
......@@ -4,26 +4,29 @@
#define SetChatRoomNameCall2Offset 0x685090A0 - 0x68010000
#ifndef USE_SOCKET
struct SetChatRoomNameStruct {
wchar_t* chatroomid;
wchar_t* chatroomname;
struct SetChatRoomNameStruct
{
wchar_t *chatroomid;
wchar_t *chatroomname;
};
BOOL SetChatRoomNameRemote(LPVOID lpParameter) {
SetChatRoomNameStruct* scrns = (SetChatRoomNameStruct*)lpParameter;
return SetChatRoomName(scrns->chatroomid, scrns->chatroomname);
BOOL SetChatRoomNameRemote(LPVOID lpParameter)
{
SetChatRoomNameStruct *scrns = (SetChatRoomNameStruct *)lpParameter;
return SetChatRoomName(scrns->chatroomid, scrns->chatroomname);
}
#endif // !USE_SOCKET
BOOL SetChatRoomName(wchar_t* chatroomid, wchar_t* chatroomname) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SetChatRoomNameCall1 = WeChatWinBase + SetChatRoomNameCall1Offset;
DWORD SetChatRoomNameCall2 = WeChatWinBase + SetChatRoomNameCall2Offset;
WxBaseStruct pchatroomid(chatroomid);
WxBaseStruct pchatroomname(chatroomname);
int isSuccess = 0;
BOOL SetChatRoomName(wchar_t *chatroomid, wchar_t *chatroomname)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SetChatRoomNameCall1 = WeChatWinBase + SetChatRoomNameCall1Offset;
DWORD SetChatRoomNameCall2 = WeChatWinBase + SetChatRoomNameCall2Offset;
WxString pchatroomid(chatroomid);
WxString pchatroomname(chatroomname);
int isSuccess = 0;
__asm {
__asm {
pushad;
pushfd;
call SetChatRoomNameCall1;
......@@ -37,6 +40,6 @@ BOOL SetChatRoomName(wchar_t* chatroomid, wchar_t* chatroomname) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess == 0x1;
}
\ No newline at end of file
}
return isSuccess == 0x1;
}
......@@ -5,30 +5,33 @@
#define SetChatRoomSelfNicknameCall3Offset 0x68509FE0 - 0x68010000
#ifndef USE_SOCKET
struct SetChatRoomSelfNicknameStruct {
wchar_t* chatroomid;
wchar_t* nickname;
struct SetChatRoomSelfNicknameStruct
{
wchar_t *chatroomid;
wchar_t *nickname;
};
BOOL SetChatRoomSelfNicknameRemote(LPVOID lpParameter) {
SetChatRoomSelfNicknameStruct* scrsns = (SetChatRoomSelfNicknameStruct*)lpParameter;
if (!scrsns->nickname)
return false;
return SetChatRoomSelfNickname(scrsns->chatroomid, scrsns->nickname);
BOOL SetChatRoomSelfNicknameRemote(LPVOID lpParameter)
{
SetChatRoomSelfNicknameStruct *scrsns = (SetChatRoomSelfNicknameStruct *)lpParameter;
if (!scrsns->nickname)
return false;
return SetChatRoomSelfNickname(scrsns->chatroomid, scrsns->nickname);
}
#endif // !USE_SOCKET
BOOL SetChatRoomSelfNickname(wchar_t* chatroomid,wchar_t* nickname) {
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SetChatRoomSelfNicknameCall1 = WeChatWinBase + SetChatRoomSelfNicknameCall1Offset;
DWORD SetChatRoomSelfNicknameCall2 = WeChatWinBase + SetChatRoomSelfNicknameCall2Offset;
DWORD SetChatRoomSelfNicknameCall3 = WeChatWinBase + SetChatRoomSelfNicknameCall3Offset;
wstring selfwxid = GetSelfWxid();
WxBaseStruct pchatroomid(chatroomid);
WxBaseStruct pselfwxid((wchar_t*)selfwxid.c_str());
WxBaseStruct pnickname(nickname);
BOOL SetChatRoomSelfNickname(wchar_t *chatroomid, wchar_t *nickname)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SetChatRoomSelfNicknameCall1 = WeChatWinBase + SetChatRoomSelfNicknameCall1Offset;
DWORD SetChatRoomSelfNicknameCall2 = WeChatWinBase + SetChatRoomSelfNicknameCall2Offset;
DWORD SetChatRoomSelfNicknameCall3 = WeChatWinBase + SetChatRoomSelfNicknameCall3Offset;
wstring selfwxid = GetSelfWxid();
WxString pchatroomid(chatroomid);
WxString pselfwxid((wchar_t *)selfwxid.c_str());
WxString pnickname(nickname);
int isSuccess = 0x0;
__asm {
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
call SetChatRoomSelfNicknameCall1;
......@@ -53,6 +56,6 @@ BOOL SetChatRoomSelfNickname(wchar_t* chatroomid,wchar_t* nickname) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess == 0x1;
}
\ No newline at end of file
}
return isSuccess == 0x1;
}
......@@ -5,44 +5,48 @@
#define VerifyFriendApplyParamOffset 0x11EE40E0 - 0x10000000
#ifndef USE_SOCKET
struct VerifyFriendApplyStruct {
wchar_t* v3_data;
wchar_t* v4_data;
struct VerifyFriendApplyStruct
{
wchar_t *v3_data;
wchar_t *v4_data;
};
#endif
struct VerifyFriendApplyParamStruct {
DWORD handle;
DWORD* StatusCode;
DWORD StatusCodeEndAddr1;
DWORD StatusCodeEndAddr2;
char buffer[0x3C] = { 0 };
struct VerifyFriendApplyParamStruct
{
DWORD handle;
DWORD *StatusCode;
DWORD StatusCodeEndAddr1;
DWORD StatusCodeEndAddr2;
char buffer[0x3C] = {0};
};
#ifndef USE_SOCKET
BOOL VerifyFriendApplyRemote(LPVOID lparameter) {
VerifyFriendApplyStruct* vfas = (VerifyFriendApplyStruct*)lparameter;
BOOL isSuccess = VerifyFriendApply(vfas->v3_data, vfas->v4_data);
return isSuccess;
BOOL VerifyFriendApplyRemote(LPVOID lparameter)
{
VerifyFriendApplyStruct *vfas = (VerifyFriendApplyStruct *)lparameter;
BOOL isSuccess = VerifyFriendApply(vfas->v3_data, vfas->v4_data);
return isSuccess;
}
#endif
BOOL __stdcall VerifyFriendApply(wchar_t* v3_data, wchar_t* v4_data) {
WxBaseStruct v3(v3_data);
WxBaseStruct v4(v4_data);
DWORD VerifyFriendApplyCall1 = GetWeChatWinBase() + VerifyFriendApplyCall1Offset;
DWORD VerifyFriendApplyCall2 = GetWeChatWinBase() + VerifyFriendApplyCall2Offset;
DWORD VerifyFriendApplyParam = GetWeChatWinBase() + VerifyFriendApplyParamOffset;
VerifyFriendApplyParamStruct* param = new VerifyFriendApplyParamStruct;
DWORD StatusCode[9] = { 0xB2,(DWORD)param,0xB5,(DWORD)param,0xB0,(DWORD)param,0xB1,(DWORD)param,0x0 };
param->handle = VerifyFriendApplyParam;
param->StatusCode = StatusCode;
param->StatusCodeEndAddr1 = (DWORD)&StatusCode[8];
param->StatusCodeEndAddr2 = (DWORD)&StatusCode[8];
BOOL __stdcall VerifyFriendApply(wchar_t *v3_data, wchar_t *v4_data)
{
WxString v3(v3_data);
WxString v4(v4_data);
DWORD VerifyFriendApplyCall1 = GetWeChatWinBase() + VerifyFriendApplyCall1Offset;
DWORD VerifyFriendApplyCall2 = GetWeChatWinBase() + VerifyFriendApplyCall2Offset;
DWORD VerifyFriendApplyParam = GetWeChatWinBase() + VerifyFriendApplyParamOffset;
VerifyFriendApplyParamStruct *param = new VerifyFriendApplyParamStruct;
DWORD StatusCode[9] = {0xB2, (DWORD)param, 0xB5, (DWORD)param, 0xB0, (DWORD)param, 0xB1, (DWORD)param, 0x0};
param->handle = VerifyFriendApplyParam;
param->StatusCode = StatusCode;
param->StatusCodeEndAddr1 = (DWORD)&StatusCode[8];
param->StatusCodeEndAddr2 = (DWORD)&StatusCode[8];
char nullbuffer[0x94] = { 0 };
BOOL isSuccess = false;
__asm {
char nullbuffer[0x94] = {0};
BOOL isSuccess = false;
__asm {
pushad;
pushfd;
push 0x0;
......@@ -63,6 +67,6 @@ BOOL __stdcall VerifyFriendApply(wchar_t* v3_data, wchar_t* v4_data) {
mov isSuccess, eax;
popfd;
popad;
}
return isSuccess;
}
\ No newline at end of file
}
return isSuccess;
}
# 注意
此处源码来自以下仓库:
[json](https://github.com/nlohmann/json)
需要自行克隆该仓库并将json.hpp拷贝到此处
# Thanks
[json](https://github.com/nlohmann/json)
\ No newline at end of file
......@@ -8,14 +8,18 @@
* 创建一个控制台窗口
* return:BOOL,成功返回`0`,失败返回`1`
*/
BOOL CreateConsole(void) {
if (AllocConsole()) {
BOOL CreateConsole(void)
{
if (AllocConsole())
{
AttachConsole(GetCurrentProcessId());
FILE* retStream;
FILE *retStream;
freopen_s(&retStream, "CONOUT$", "w", stdout);
if (!retStream) throw std::runtime_error("Stdout redirection failed.");
if (!retStream)
throw std::runtime_error("Stdout redirection failed.");
freopen_s(&retStream, "CONOUT$", "w", stderr);
if (!retStream) throw std::runtime_error("Stderr redirection failed.");
if (!retStream)
throw std::runtime_error("Stderr redirection failed.");
return 0;
}
return 1;
......@@ -25,11 +29,12 @@ BOOL CreateConsole(void) {
* 获取`WeChatWin.dll`基址
* return:DWORD,`WeChatWin.dll`模块基址
*/
DWORD GetWeChatWinBase() {
DWORD GetWeChatWinBase()
{
return (DWORD)GetModuleHandleA("WeChatWin.dll");
}
BOOL FindOrCreateDirectory(const wchar_t* pszPath)
BOOL FindOrCreateDirectory(const wchar_t *pszPath)
{
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(pszPath, &fd);
......@@ -49,38 +54,53 @@ BOOL FindOrCreateDirectory(const wchar_t* pszPath)
/*
* 将宽字节字符串转换成`std::string`
*/
void Wchar_tToString(std::string& szDst, wchar_t* wchar)
void unicode_to_string(std::string &szDst, wchar_t *wchar)
{
wchar_t* wText = wchar;
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用
char* psText; // psText为char*的临时数组,作为赋值给std::string的中间变量
wchar_t *wText = wchar;
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);
char *psText;
psText = new char[dwNum];
WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用
szDst = psText;// std::string赋值
delete[]psText;// psText的清除
WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);
szDst = psText;
delete[] psText;
}
/*
* 将UTF8编码数据转换为GBK编码
*/
string UTF8ToGBK(const std::string& strUTF8)
string utf8_to_gb2312(const char *strUTF8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
wchar_t* wszGBK = new wchar_t[len + 1];
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0);
wchar_t *wszGBK = new wchar_t[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, wszGBK, len);
MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, wszGBK, len);
len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
char* szGBK = new char[len + 1];
char *szGBK = new char[len + 1];
memset(szGBK, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
//strUTF8 = szGBK;
std::string strTemp(szGBK);
delete[]szGBK;
delete[]wszGBK;
//strUTF8 = szGBK;
string strTemp(szGBK);
delete[] szGBK;
delete[] wszGBK;
return strTemp;
}
/*
* 将UTF8编码数据转换为GBK编码
*/
wstring utf8_to_unicode(const char *buffer)
{
int c_size = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, 0, 0);
wchar_t *temp = new wchar_t[c_size + 1];
MultiByteToWideChar(CP_UTF8, 0, buffer, -1, temp, c_size);
temp[c_size] = L'\0';
wstring ret(temp);
delete[] temp;
temp = NULL;
return ret;
}
/*
* 对任意地址添加HOOK
* dwHookAddr:HOOK的目标地址
......@@ -88,14 +108,14 @@ string UTF8ToGBK(const std::string& strUTF8)
* originalRecieveCode:保存旧指令的数组
* return:void
*/
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress,char* originalRecieveCode)
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieveCode)
{
//组装跳转数据
BYTE jmpCode[5] = { 0 };
BYTE jmpCode[5] = {0};
jmpCode[0] = 0xE9;
//计算偏移
*(DWORD*)&jmpCode[1] = (DWORD)dwJmpAddress - dwHookAddr - 5;
*(DWORD *)&jmpCode[1] = (DWORD)dwJmpAddress - dwHookAddr - 5;
// 保存以前的属性用于还原
DWORD OldProtext = 0;
......@@ -105,7 +125,7 @@ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress,char* originalRecieveC
ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwHookAddr, originalRecieveCode, 5, 0);
//写入自己的代码
memcpy((void*)dwHookAddr, jmpCode, 5);
memcpy((void *)dwHookAddr, jmpCode, 5);
// 执行完了操作之后需要进行还原
VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext);
......@@ -117,7 +137,7 @@ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress,char* originalRecieveC
* originalRecieveCode:保存旧指令的数组
* return:void
*/
void UnHookAnyAddress(DWORD dwHookAddr, char* originalRecieveCode)
void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode)
{
DWORD OldProtext = 0;
VirtualProtect((LPVOID)dwHookAddr, 5, PAGE_EXECUTE_READWRITE, &OldProtext);
......@@ -129,7 +149,8 @@ void UnHookAnyAddress(DWORD dwHookAddr, char* originalRecieveCode)
* 取消所有HOOK
* return:void
*/
void UnHookAll() {
void UnHookAll()
{
UnHookLogMsgInfo();
UnHookReceiveMessage();
UnHookFriendStatusCode();
......@@ -146,11 +167,14 @@ void UnHookAll() {
* replaceto:替换成的字符串
* return:std::wstring,替换后的字符串
*/
wstring wreplace(wstring source, wchar_t replaced, wstring replaceto) {
wstring wreplace(wstring source, wchar_t replaced, wstring replaceto)
{
wstring temp = L"";
wchar_t* buffer = (wchar_t*)source.c_str();
for (unsigned int i = 0; i < source.length(); i++) {
if (buffer[i] == replaced) {
wchar_t *buffer = (wchar_t *)source.c_str();
for (unsigned int i = 0; i < source.length(); i++)
{
if (buffer[i] == replaced)
{
temp += replaceto;
continue;
}
......@@ -162,19 +186,23 @@ wstring wreplace(wstring source, wchar_t replaced, wstring replaceto) {
/*
* 获取当前时间
*/
wchar_t* GetTimeW(long long timestamp) {
wchar_t* wstr = new wchar_t[20];
wstring GetTimeW(long long timestamp)
{
wchar_t *wstr = new wchar_t[20];
memset(wstr, 0, 20 * 2);
// time_t cTime = time(NULL);
tm tm_out;
localtime_s(&tm_out, &timestamp);
swprintf_s(wstr,20, L"%04d-%02d-%02d %02d:%02d:%02d",
1900 + tm_out.tm_year, tm_out.tm_mon + 1, tm_out.tm_mday,
tm_out.tm_hour, tm_out.tm_min, tm_out.tm_sec);
return wstr;
swprintf_s(wstr, 20, L"%04d-%02d-%02d %02d:%02d:%02d",
1900 + tm_out.tm_year, tm_out.tm_mon + 1, tm_out.tm_mday,
tm_out.tm_hour, tm_out.tm_min, tm_out.tm_sec);
wstring strTimeW(wstr);
delete[] wstr;
return strTimeW;
}
void PrintProcAddr() {
void PrintProcAddr()
{
CreateConsole();
printf("WeChatVersion %s\n", GetWeChatVerStr().c_str());
printf("SendImage 0x%08X\n", (DWORD)SendImage);
......@@ -204,7 +232,7 @@ void PrintProcAddr() {
BOOL ProcessIsWeChat()
{
char szFileFullPath[MAX_PATH] = { 0 }, szProcessName[MAX_PATH] = { 0 };
char szFileFullPath[MAX_PATH] = {0}, szProcessName[MAX_PATH] = {0};
GetModuleFileNameA(NULL, szFileFullPath, MAX_PATH);
int length = ::strlen(szFileFullPath);
for (int i = length - 1; i >= 0; i--)
......@@ -230,6 +258,7 @@ BOOL ProcessIsWeChat()
}
}
DWORD OffsetFromIdaAddr(DWORD idaAddr) {
DWORD OffsetFromIdaAddr(DWORD idaAddr)
{
return idaAddr - IDA_BASE;
}
\ No newline at end of file
}
......@@ -9,9 +9,10 @@
// 添加要在此处预编译的标头
#include "framework.h"
#include<iostream>
#include<vector>
#include<strstream>
#include <iostream>
#include <vector>
#include <strstream>
#include <string>
#include "wxdata.h"
#include "wxapi.h"
#endif //PCH_H
......@@ -20,4 +21,4 @@
#include "wxsocketapi.h"
#else
#include "comclient.h"
#endif
\ No newline at end of file
#endif
......@@ -30,20 +30,36 @@
#include "GetChatRoomMemberNickname.h"
using namespace std;
#pragma comment(lib,"version.lib")
#pragma warning(disable:4731)
#pragma comment(lib, "version.lib")
#pragma warning(disable : 4731 26812)
// 对于导出函数,需要使用此宏修饰
#define DLLEXPORT extern "C" __declspec(dllexport)
BOOL CreateConsole(void);
DWORD GetWeChatWinBase();
void Wchar_tToString(std::string& szDst, wchar_t* wchar);
string UTF8ToGBK(const std::string& strUTF8);
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char* originalRecieveCode);
void UnHookAnyAddress(DWORD dwHookAddr, char* originalRecieveCode);
void unicode_to_string(std::string &szDst, wchar_t *wchar);
string utf8_to_gb2312(const char *strUTF8);
wstring utf8_to_unicode(const char *buffer);
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieveCode);
void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode);
DLLEXPORT void UnHookAll();
wstring wreplace(wstring source, wchar_t replaced, wstring replaceto);
void PrintProcAddr();
wchar_t* GetTimeW(long long timestamp);
wstring GetTimeW(long long timestamp);
BOOL ProcessIsWeChat();
BOOL FindOrCreateDirectory(const wchar_t* pszPath);
\ No newline at end of file
BOOL FindOrCreateDirectory(const wchar_t *pszPath);
template <typename T1, typename T2>
vector<T1> split(T1 str, T2 letter)
{
vector<T1> arr;
size_t pos;
while ((pos = str.find_first_of(letter)) != T1::npos)
{
T1 str1 = str.substr(0, pos);
arr.push_back(str1);
str = str.substr(pos + 1, str.length() - pos - 1);
}
arr.push_back(str);
return arr;
}
#pragma once
#include<windows.h>
#include <windows.h>
using namespace std;
/*
......@@ -9,82 +9,70 @@ using namespace std;
* maxLength:`buffer`最大字符数
* fill1:占位成员1,默认为0
* fill2:占位成员2,默认为0
* WxBaseStruct:默认构造函数
* WxString:默认构造函数
*/
struct WxBaseStruct
struct WxString
{
wchar_t* buffer;
wchar_t *buffer;
DWORD length;
DWORD maxLength;
DWORD fill1;
DWORD fill2;
WxBaseStruct(wchar_t* pStr) {
if (pStr) {
buffer = pStr;
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
else {
buffer = NULL;
length = 0x0;
maxLength = 0x0;
}
fill1 = 0x0;
fill2 = 0x0;
}
};
/*
* 不使用构造函数的微信基础数据结构,使用频率较低
*/
struct WxString
{
wchar_t* buffer = NULL;
DWORD length = 0;
DWORD maxLength = 0;
DWORD fill1 = 0;
DWORD fill2 = 0;
WxString()
{
WxString(NULL);
}
WxString(wstring str)
{
buffer = (wchar_t *)str.c_str();
length = str.length();
maxLength = str.length() * 2;
}
WxString(const wchar_t *pStr)
{
WxString((wchar_t *)pStr);
}
WxString(int tmp)
{
buffer = NULL;
length = 0x0;
maxLength = 0x0;
}
WxString(wchar_t *pStr)
{
buffer = pStr;
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
};
/*
* 保存单条信息的结构
* messagetype:消息类型
* sender:发送者wxid;l_sender:`sender`字符数
* wxid:如果sender是群聊id,则此成员保存具体发送人wxid,否则与`sender`一致;l_wxid:`wxid`字符数
* message:消息内容,非文本消息是xml格式;l_message:`message`字符数
* filepath:图片、文件及其他资源的保存路径;l_filepath:`filepath`字符数
* sender:发送者wxid
* wxid:如果sender是群聊id,则此成员保存具体发送人wxid,否则与`sender`一致
* message:消息内容,非文本消息是xml格式
* filepath:图片、文件及其他资源的保存路径
*/
struct ReceiveMsgStruct {
DWORD pid;
DWORD messagetype;
BOOL isSendMessage;
wchar_t* sender;
DWORD l_sender;
wchar_t* wxid;
DWORD l_wxid;
wchar_t* message;
DWORD l_message;
wchar_t* filepath;
DWORD l_filepath;
wchar_t* time;
DWORD l_time;
~ReceiveMsgStruct() {
if (this->sender)
delete[] this->sender;
if (this->wxid)
delete[] this->wxid;
if (this->message)
delete[] this->message;
if (this->filepath)
delete[] this->filepath;
if (this->time)
delete[] this->time;
struct ReceiveMsgStruct
{
DWORD pid = 0;
DWORD messagetype = 0;
BOOL isSendMessage = 0;
unsigned long long msgid = 0;
wstring sender;
wstring wxid;
wstring message;
wstring filepath;
wstring time;
~ReceiveMsgStruct()
{
}
};
// vector在内存中的表现形式
struct VectorStruct {
struct VectorStruct
{
#ifdef _DEBUG
DWORD v_head;
#endif
......@@ -93,27 +81,28 @@ struct VectorStruct {
DWORD v_end2;
};
struct UserInfo {
struct UserInfo
{
int errcode;
wchar_t* keyword;
wchar_t *keyword;
int l_keyword;
wchar_t* v3;
wchar_t *v3;
int l_v3;
wchar_t* NickName;
wchar_t *NickName;
int l_NickName;
wchar_t* Signature;
wchar_t *Signature;
int l_Signature;
wchar_t* v2;
wchar_t *v2;
int l_v2;
wchar_t* Nation;
wchar_t *Nation;
int l_Nation;
wchar_t* Province;
wchar_t *Province;
int l_Province;
wchar_t* City;
wchar_t *City;
int l_City;
wchar_t* BigAvatar;
wchar_t *BigAvatar;
int l_BigAvatar;
wchar_t* SmallAvatar;
wchar_t *SmallAvatar;
int l_SmallAvatar;
DWORD sex;
BOOL over;
......@@ -126,14 +115,15 @@ struct UserInfo {
* sql:建表语句;l_sql:`sql`字符数
* rootpage:表编号;l_rootpage:`rootpage`字符数
*/
struct TableInfoStruct {
char* name;
struct TableInfoStruct
{
char *name;
DWORD l_name;
char* tbl_name;
char *tbl_name;
DWORD l_tbl_name;
char* sql;
char *sql;
DWORD l_sql;
char* rootpage;
char *rootpage;
DWORD l_rootpage;
};
......@@ -145,9 +135,10 @@ struct TableInfoStruct {
* tables:保存库中所有表信息的容器
* count:库中表的数量
*/
struct DbInfoStruct {
struct DbInfoStruct
{
DWORD handle;
wchar_t* dbname;
wchar_t *dbname;
DWORD l_dbname;
vector<TableInfoStruct> tables;
DWORD count;
......@@ -161,15 +152,17 @@ struct DbInfoStruct {
* wxRemarkAddr:备注保存地址
* WxFriendStructW:默认构造函数
*/
struct WxFriendStruct {
struct WxFriendStruct
{
DWORD wxIdAddr;
DWORD wxNumberAddr;
DWORD wxNickNameAddr;
DWORD wxRemarkAddr;
WxFriendStruct(DWORD wxIdAddr, DWORD wxNumberAddr, DWORD wxNickNameAddr, DWORD wxRemarkAddr) {
WxFriendStruct(DWORD wxIdAddr, DWORD wxNumberAddr, DWORD wxNickNameAddr, DWORD wxRemarkAddr)
{
this->wxIdAddr = wxIdAddr;
this->wxNumberAddr = wxNumberAddr;
this->wxNickNameAddr = wxNickNameAddr;
this->wxRemarkAddr = wxRemarkAddr;
}
};
\ No newline at end of file
};
此差异已折叠。
......@@ -3,7 +3,67 @@
#include <signal.h>
// mongoose: https://github.com/cesanta/mongoose
#include "mongoose/mongoose.h"
#pragma comment(lib,"ws2_32.lib")
extern "C" __declspec(dllexport) void HttpStart();
extern "C" __declspec(dllexport) int HttpClose();
#endif
\ No newline at end of file
#pragma comment(lib, "ws2_32.lib")
extern "C" __declspec(dllexport) void http_start(int port);
extern "C" __declspec(dllexport) int http_close();
string getMgStrA(struct mg_str str);
string getMgVarA(mg_http_message *hm, string name);
bool is_digit_number(string str);
typedef enum HTTP_METHODSTag
{
HTTP_METHOD_GET = 1,
HTTP_METHOD_POST
} HTTP_METHODS,
*PHTTP_METHODS;
typedef enum WECHAT_HTTP_APISTag
{
WECHAT_GET_SELF_INFO = 1,
// send message
WECHAT_MSG_SEND_TEXT,
WECHAT_MSG_SEND_AT,
WECHAT_MSG_SEND_CARD,
WECHAT_MSG_SEND_IMAGE,
WECHAT_MSG_SEND_FILE,
WECHAT_MSG_SEND_ARTICLE,
WECHAT_MSG_SEND_APP,
// receive message
WECHAT_MSG_START_HOOK,
WECHAT_MSG_STOP_HOOK,
WECHAT_MSG_START_IMAGE_HOOK,
WECHAT_MSG_STOP_IMAGE_HOOK,
WECHAT_MSG_START_VOICE_HOOK,
WECHAT_MSG_STOP_VOICE_HOOK,
// contact
WECHAT_CONTACT_GET_LIST,
WECHAT_CONTACT_CHECK_STATUS,
WECHAT_CONTACT_DEL,
WECHAT_CONTACT_SEARCH_BY_CACHE,
WECHAT_CONTACT_SEARCH_BY_NET,
WECHAT_CONTACT_ADD_BY_WXID,
WECHAT_CONTACT_ADD_BY_V3,
WECHAT_CONTACT_ADD_BY_PUBLIC_ID,
WECHAT_CONTACT_VERIFY_APPLY,
WECHAT_CONTACT_EDIT_REMARK,
// chatroom
WECHAT_CHATROOM_GET_MEMBER_LIST,
WECHAT_CHATROOM_GET_MEMBER_NICKNAME,
WECHAT_CHATROOM_DEL_MEMBER,
WECHAT_CHATROOM_ADD_MEMBER,
WECHAT_CHATROOM_SET_ANNOUNCEMENT,
WECHAT_CHATROOM_SET_CHATROOM_NAME,
WECHAT_CHATROOM_SET_SELF_NICKNAME,
// database
WECHAT_DATABASE_GET_HANDLES,
WECHAT_DATABASE_BACKUP,
WECHAT_DATABASE_QUERY,
// version
WECHAT_SET_VERSION,
// log
WECHAT_LOG_START_HOOK,
WECHAT_LOG_STOP_HOOK,
} WECHAT_HTTP_APIS,
*PWECHAT_HTTP_APIS;
#endif
......@@ -88,5 +88,5 @@ if __name__ == '__main__':
wx = WeChatRobot(pid_list[0])
wx.StartService()
wx.StartReceiveMessage()
wxRobot.register_msg_event(wx.pid)
wxRobot.start_socket_server()
wx.StopService()
......@@ -62,6 +62,7 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler):
_fields_ = [("pid", ctypes.wintypes.DWORD),
("type", ctypes.wintypes.DWORD),
("isSendMsg", ctypes.wintypes.DWORD),
("msgid",ctypes.c_ulonglong),
("sender", ctypes.c_wchar * 80),
("wxid", ctypes.c_wchar * 80),
("message", ctypes.c_wchar * 0x1000B),
......@@ -101,8 +102,11 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler):
@staticmethod
def msg_callback(data):
# 主线程中已经注入,此处禁止调用StartService和StopService
msg = {'pid': data.pid, 'time': data.time, 'type': data.type, 'isSendMsg': data.isSendMsg, 'wxid': data.wxid,
'sendto' if data.isSendMsg else 'from': data.sender, 'message': data.message}
msg = {'pid': data.pid, 'time': data.time, 'type': data.type,
'isSendMsg': data.isSendMsg, 'msgid': data.msgid,
'wxid': data.wxid,
'sendto' if data.isSendMsg else 'from': data.sender,
'message': data.message}
robot = comtypes.client.CreateObject("WeChatRobot.CWeChatRobot")
event = comtypes.client.CreateObject("WeChatRobot.RobotEvent")
wx = WeChatRobot(data.pid, robot, event)
......@@ -616,7 +620,7 @@ class WeChatRobot:
dbs[dbname] = {'Handle': table['Handle'], 'tables': []}
dbs[dbname]['tables'].append(
{'name': table['name'], 'tbl_name': table['tbl_name'],
'root_page': table['root_page'], 'sql': table['sql']}
'root_page': table['rootpage'], 'sql': table['sql']}
)
return dbs
......@@ -1039,8 +1043,11 @@ def get_wechat_pid_list() -> list:
pid_list = []
process_list = psutil.pids()
for pid in process_list:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
try:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
except psutil.NoSuchProcess:
pass
return pid_list
......
......@@ -117,6 +117,10 @@ CWeChatRobot.exe /unregserver
## 2022.07.28
1. 解决部分已知问题,优化多开管理
2. 重构COM中的部分实现
## 2022.08.13
1. 现在消息HOOK内容包含消息ID
2. 完成发送消息的http接口,可参考[wxDriverTest.py](/Release/socket/wxDriverTest.py),其他接口还需要一点时间
3. 新增项目配置文件,感谢@amchii 提供的方法
# 打赏作者
请给作者一个star,感谢感谢
......
import ctypes
import json
import requests
PORT = 8000
def call_http_api(api,data,port = PORT):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.post(url = url,data = json.dumps(data))
print("POST",resp.json())
def get_wechat_pid_list() -> list:
import psutil
pid_list = []
process_list = psutil.pids()
for pid in process_list:
try:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
except psutil.NoSuchProcess:
pass
return pid_list
def test():
data = {"wxid":"filehelper","msg":"hello http"}
call_http_api(2,data)
data = {"receiver":'filehelper',"shared_wxid":"filehelper","nickname":"文件传输助手"}
call_http_api(4,data)
data = {"receiver":'filehelper',"img_path":r"D:\C++\ComWeChatRobot\test\测试图片.png"}
call_http_api(5,data)
data = {"receiver":'filehelper',"file_path":r"D:\C++\ComWeChatRobot\test\测试文件"}
call_http_api(6,data)
data = {"wxid":'filehelper',
"title":"百度",
"abstract":"百度一下,你就知道",
"url":"https://www.baidu.com/",
"img_path":""}
call_http_api(7,data)
wx = ctypes.cdll.LoadLibrary('./wxDriver64.dll')
pids = get_wechat_pid_list()
if len(pids) == 0:
pids.append(wx.new_wechat())
wx.start_listen(pids[0],PORT)
\ No newline at end of file
此差异已折叠。
#pragma once
#include<windows.h>
#include<iostream>
#include <windows.h>
#include <iostream>
#include <tchar.h>
#include <TlHelp32.h>
#include "driverdata.h"
#include "templatefunc.h"
using namespace std;
#pragma warning(disable:4311;disable:4302;disable:4312)
#pragma warning(disable : 4311; disable : 4302; disable : 4312)
#define DLLEXPORT extern "C" __declspec(dllexport)
#ifdef _WIN64
PVOID GetSystem32ProcAddr(PCWSTR ObjectName, PCSTR procName);
#define TEXTLENGTHW(buffer) buffer ? (wcslen(buffer) * 2 + 2) : 0
#define TEXTLENGTHA(buffer) buffer ? (strlen(buffer) + 1) : 0
#ifdef _UNICODE
#define tstring std::wstring
#define TEXTLENGTH TEXTLENGTHW
#else
#define tstring std::string
#define TEXTLENGTH TEXTLENGTHW
#endif
BOOL CloseProcessHandle(DWORD pid, wchar_t* handlename);
BOOL InjectDll(DWORD dwId, const wchar_t* szPath);
BOOL RemoveDll(DWORD dwId, PCWSTR dllname);
#ifdef _WIN64
PVOID GetSystem32ProcAddr(PCWSTR ObjectName, PCSTR procName);
#endif
BOOL InjectDll(DWORD pid, const wchar_t *szPath);
BOOL RemoveDll(DWORD pid);
BOOL CreateConsole();
BOOL isFileExists_stat(wstring name);
DWORD GetWeChatPid();
extern HANDLE GlobalProcess;
extern PVOID pRemoteGetProc;
BOOL CloseProcessHandle(DWORD pid, wchar_t *handlename);
tstring GetWeChatVersion();
tstring GetWeChatInstallDir();
DLLEXPORT BOOL StartRobotService();
DLLEXPORT BOOL StopRobotService();
\ No newline at end of file
DLLEXPORT BOOL start_listen(DWORD pid, int port);
DLLEXPORT BOOL stop_listen(DWORD pid);
DLLEXPORT DWORD new_wechat();
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -164,6 +164,7 @@
<ClInclude Include="framework.h" />
<ClInclude Include="ntapi.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="templatefunc.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
......@@ -176,6 +177,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="templatefunc.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -30,6 +30,9 @@
<ClInclude Include="driverdata.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="templatefunc.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
......@@ -47,5 +50,8 @@
<ClCompile Include="driver.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="templatefunc.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册