diff --git a/CWeChatRobot/AddBrandContact.cpp b/CWeChatRobot/AddBrandContact.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f9d633bd3f19e78ec0377b73c059daeb10c0555 --- /dev/null +++ b/CWeChatRobot/AddBrandContact.cpp @@ -0,0 +1,25 @@ +#include "pch.h" + +BOOL AddBrandContact(wchar_t* PublicId) { + if (!hProcess) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwWriteSize = 0; + DWORD dwRet = 1; + + LPVOID PublicIdaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + if (!PublicIdaddr) + return 1; + WriteProcessMemory(hProcess, PublicIdaddr, PublicId, wcslen(PublicId) * 2 + 2, &dwWriteSize); + DWORD AddBrandContactAddr = WeChatRobotBase + AddBrandContactRemoteOffset; + HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)AddBrandContactAddr, (LPVOID)PublicIdaddr, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + GetExitCodeThread(hThread, &dwRet); + CloseHandle(hThread); + } + + VirtualFreeEx(hProcess, PublicIdaddr, 0, MEM_RELEASE); + return dwRet == 0; +} \ No newline at end of file diff --git a/CWeChatRobot/AddFriend.h b/CWeChatRobot/AddFriend.h index 5eb2647c2917800e5f2e412943ed1f2712816a77..638620dfdc4b6c05255bd7d1e305aa02ca5c5335 100644 --- a/CWeChatRobot/AddFriend.h +++ b/CWeChatRobot/AddFriend.h @@ -2,4 +2,5 @@ #include BOOL AddFriendByWxid(wchar_t* wxid, wchar_t* message); -BOOL AddFriendByV3(wchar_t* v3, wchar_t* message,int AddType); \ No newline at end of file +BOOL AddFriendByV3(wchar_t* v3, wchar_t* message,int AddType); +BOOL AddBrandContact(wchar_t* PublicId); \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.cpp b/CWeChatRobot/WeChatRobot.cpp index ba480a2dd711169d704e45af388566fbe58e9964..0adb26dfcb4ebf0022cc4cde4d36d84f1eca461f 100644 --- a/CWeChatRobot/WeChatRobot.cpp +++ b/CWeChatRobot/WeChatRobot.cpp @@ -300,4 +300,13 @@ STDMETHODIMP CWeChatRobot::CSearchContactByNet(BSTR keyword, VARIANT* __result) V_ARRAY(&vsaValue) = SearchContactByNet(keyword); *__result = vsaValue; return S_OK; +} + +/* +* 参数1:公众号id +* 参数2:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CAddBrandContact(BSTR PublicId, int* __result) { + *__result = AddBrandContact(PublicId); + return S_OK; } \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.h b/CWeChatRobot/WeChatRobot.h index aa19747298a1bafd93187a4316ce378765289503..83d9244ec7098ab1acef794d4a65bbc637cff299 100644 --- a/CWeChatRobot/WeChatRobot.h +++ b/CWeChatRobot/WeChatRobot.h @@ -80,6 +80,7 @@ public: STDMETHODIMP CGetWeChatVer(BSTR* __result); STDMETHODIMP CStartWeChat(int* __result); STDMETHODIMP CSearchContactByNet(BSTR keyword, VARIANT* __result); + STDMETHODIMP CAddBrandContact(BSTR PublicId, int* __result); }; OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot) diff --git a/CWeChatRobot/WeChatRobotCOM.idl b/CWeChatRobot/WeChatRobotCOM.idl index 9439ad28cdac8a36f8f4e32dea251cd2e2d9c020..c95bc11282b9d6ff36c6373b74165704e251fc6a 100644 --- a/CWeChatRobot/WeChatRobotCOM.idl +++ b/CWeChatRobot/WeChatRobotCOM.idl @@ -45,6 +45,7 @@ interface IWeChatRobot : IDispatch [id(27)] HRESULT CGetWeChatVer([out, retval] BSTR* __result); [id(28)] HRESULT CStartWeChat([out, retval] int* __result); [id(29)] HRESULT CSearchContactByNet([in] BSTR keyword, [out, retval] VARIANT* __result); + [id(30)] HRESULT CAddBrandContact([in] BSTR PublicId, [out, retval] int* __result); }; [ uuid(721abb35-141a-4aa2-94f2-762e2833fa6c), diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index 15d37e6b90985602d3324a718014c324daab0fed..b5147d56c06a1a98b0912111a8715dc203ef1e76 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -239,6 +239,7 @@ + diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters index 8571b30d69156f3e0a1469bde925d205b57a08b1..e16145c25ff93a58612426ec8e6bd7ad4bc937ec 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters @@ -240,6 +240,9 @@ 好友相关\搜索好友 + + 好友相关\添加好友 + diff --git a/CWeChatRobot/WeChatRobotCOM_i.h b/CWeChatRobot/WeChatRobotCOM_i.h index 55fd6b7a52d9787845a6d156cce5ce7c0efe027d..bb0ccdf5b2eecdec57b665e1edb7ea6bf42cf660 100644 --- a/CWeChatRobot/WeChatRobotCOM_i.h +++ b/CWeChatRobot/WeChatRobotCOM_i.h @@ -206,6 +206,10 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR keyword, /* [retval][out] */ VARIANT *__result) = 0; + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CAddBrandContact( + /* [in] */ BSTR PublicId, + /* [retval][out] */ int *__result) = 0; + }; @@ -411,6 +415,11 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR keyword, /* [retval][out] */ VARIANT *__result); + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CAddBrandContact )( + IWeChatRobot * This, + /* [in] */ BSTR PublicId, + /* [retval][out] */ int *__result); + END_INTERFACE } IWeChatRobotVtbl; @@ -534,6 +543,9 @@ EXTERN_C const IID IID_IWeChatRobot; #define IWeChatRobot_CSearchContactByNet(This,keyword,__result) \ ( (This)->lpVtbl -> CSearchContactByNet(This,keyword,__result) ) +#define IWeChatRobot_CAddBrandContact(This,PublicId,__result) \ + ( (This)->lpVtbl -> CAddBrandContact(This,PublicId,__result) ) + #endif /* COBJMACROS */ diff --git a/CWeChatRobot/WeChatRobotCOM_p.c b/CWeChatRobot/WeChatRobotCOM_p.c index 08253364f6a7d6b941cd894c51b987dff39401ac..ba6a5b5e0f23d3591acb37eb867fa8e1d11aa718 100644 --- a/CWeChatRobot/WeChatRobotCOM_p.c +++ b/CWeChatRobot/WeChatRobotCOM_p.c @@ -49,7 +49,7 @@ #include "WeChatRobotCOM_i.h" #define TYPE_FORMAT_STRING_SIZE 1239 -#define PROC_FORMAT_STRING_SIZE 1231 +#define PROC_FORMAT_STRING_SIZE 1273 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 2 @@ -1184,6 +1184,43 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 1228 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ + /* Procedure CAddBrandContact */ + +/* 1230 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1232 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1236 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1238 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 1240 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1242 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1244 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x3, /* 3 */ +/* 1246 */ 0x8, /* 8 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 1248 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1250 */ NdrFcShort( 0x1 ), /* 1 */ +/* 1252 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter PublicId */ + +/* 1254 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 1256 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1258 */ NdrFcShort( 0x2a ), /* Type Offset=42 */ + + /* Parameter __result */ + +/* 1260 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1262 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1264 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1266 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1268 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1270 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + 0x0 } }; @@ -2057,7 +2094,8 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] = 1062, 1116, 1152, - 1188 + 1188, + 1230 }; static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo = @@ -2081,7 +2119,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo = 0, 0, 0}; -CINTERFACE_PROXY_VTABLE(36) _IWeChatRobotProxyVtbl = +CINTERFACE_PROXY_VTABLE(37) _IWeChatRobotProxyVtbl = { &IWeChatRobot_ProxyInfo, &IID_IWeChatRobot, @@ -2120,7 +2158,8 @@ CINTERFACE_PROXY_VTABLE(36) _IWeChatRobotProxyVtbl = (void *) (INT_PTR) -1 /* IWeChatRobot::CAddFriendByV3 */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CGetWeChatVer */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CStartWeChat */ , - (void *) (INT_PTR) -1 /* IWeChatRobot::CSearchContactByNet */ + (void *) (INT_PTR) -1 /* IWeChatRobot::CSearchContactByNet */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CAddBrandContact */ }; @@ -2158,6 +2197,7 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] = NdrStubCall2, NdrStubCall2, NdrStubCall2, + NdrStubCall2, NdrStubCall2 }; @@ -2165,7 +2205,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl = { &IID_IWeChatRobot, &IWeChatRobot_ServerInfo, - 36, + 37, &IWeChatRobot_table[-3], CStdStubBuffer_DELEGATING_METHODS }; diff --git a/CWeChatRobot/pch.cpp b/CWeChatRobot/pch.cpp index e17571bb26773f2ec86b9570a43a8d760921ed24..1774ac19a8da395d05269db2a4ae49190d589744 100644 --- a/CWeChatRobot/pch.cpp +++ b/CWeChatRobot/pch.cpp @@ -41,6 +41,7 @@ DWORD BackupSQLiteDBRemoteOffset = 0x0; DWORD AddFriendByWxidRemoteOffset = 0x0; DWORD AddFriendByV3RemoteOffset = 0x0; +DWORD AddBrandContactRemoteOffset = 0x0; wstring SelfInfoString = L""; @@ -169,6 +170,8 @@ BOOL GetProcOffset(wchar_t* workPath) { AddFriendByWxidRemoteOffset = AddFriendByWxidRemoteAddr - WeChatBase; DWORD AddFriendByV3RemoteAddr = (DWORD)GetProcAddress(hd, AddFriendByV3Remote); AddFriendByV3RemoteOffset = AddFriendByV3RemoteAddr - WeChatBase; + DWORD AddBrandContactRemoteAddr = (DWORD)GetProcAddress(hd, AddBrandContactRemote); + AddBrandContactRemoteOffset = AddBrandContactRemoteAddr - WeChatBase; FreeLibrary(hd); delete[] dllpath; diff --git a/CWeChatRobot/robotdata.h b/CWeChatRobot/robotdata.h index 036915fa839a83e054eb08375461fe9093ac3dde..90a664343ddb6b1fac29466d1c4d3037a5ba00f4 100644 --- a/CWeChatRobot/robotdata.h +++ b/CWeChatRobot/robotdata.h @@ -58,6 +58,7 @@ extern DWORD BackupSQLiteDBRemoteOffset; extern DWORD AddFriendByWxidRemoteOffset; extern DWORD AddFriendByV3RemoteOffset; +extern DWORD AddBrandContactRemoteOffset; #define dllname L"DWeChatRobot.dll" @@ -99,4 +100,5 @@ extern DWORD AddFriendByV3RemoteOffset; #define BackupSQLiteDBRemote "BackupSQLiteDBRemote" #define AddFriendByWxidRemote "AddFriendByWxidRemote" -#define AddFriendByV3Remote "AddFriendByV3Remote" \ No newline at end of file +#define AddFriendByV3Remote "AddFriendByV3Remote" +#define AddBrandContactRemote "AddBrandContactRemote" \ No newline at end of file diff --git a/DWeChatRobot/AddBrandContact.cpp b/DWeChatRobot/AddBrandContact.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26dbd5849e7813087680f00fbdbd03d5120717a8 --- /dev/null +++ b/DWeChatRobot/AddBrandContact.cpp @@ -0,0 +1,59 @@ +#include "pch.h" + +#define AddPublicNoticeCallOffset 0x64DAC1C4 - 0x62D70000 +#define AddPublicNoticeParamOffset 0x64C51DC4 - 0x62D70000 + +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 { + pushad; + pushfd; + lea eax, ptrparam; + push eax; + lea eax, NoticeCallHandle; + mov edx, dword ptr [eax]; + mov ecx, eax; + lea esi, ptrurl; + push esi; + mov edi, 0x3; + push edi; + call dword ptr [edx + 0x4]; + mov isSuccess, eax; + popfd; + popad; + } + return isSuccess; +} + +BOOL AddBrandContactRemote(LPVOID lpParameter) { + int isSuccess = AddBrandContact((wchar_t*)lpParameter); + return isSuccess; +} \ No newline at end of file diff --git a/DWeChatRobot/AddFriend.h b/DWeChatRobot/AddFriend.h index 265aa557224e55ddeaadd61a08297658671aaad8..5b5c474d32b143980c0eb3acb0ae17e33500141b 100644 --- a/DWeChatRobot/AddFriend.h +++ b/DWeChatRobot/AddFriend.h @@ -3,5 +3,7 @@ BOOL __stdcall AddFriendByV3(wchar_t* v3, wchar_t* message,int AddType); BOOL __stdcall AddFriendByWxid(wchar_t* wxid, wchar_t* message); +BOOL __stdcall AddBrandContact(wchar_t* PublicId); extern "C" __declspec(dllexport) BOOL AddFriendByV3Remote(LPVOID lpParameter); -extern "C" __declspec(dllexport) BOOL AddFriendByWxidRemote(LPVOID lpParameter); \ No newline at end of file +extern "C" __declspec(dllexport) BOOL AddFriendByWxidRemote(LPVOID lpParameter); +extern "C" __declspec(dllexport) BOOL AddBrandContactRemote(LPVOID lpParameter); \ No newline at end of file diff --git a/DWeChatRobot/DWeChatRobot.vcxproj b/DWeChatRobot/DWeChatRobot.vcxproj index 9308abf41d45d4341dbbf169831292678b240751..419fc6e9b16c75a28fe9370ce68925febb30f192 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj +++ b/DWeChatRobot/DWeChatRobot.vcxproj @@ -179,6 +179,7 @@ + diff --git a/DWeChatRobot/DWeChatRobot.vcxproj.filters b/DWeChatRobot/DWeChatRobot.vcxproj.filters index 8b848ed7d30819f28bf76c14e6239e8edfc4fdbc..39fbcbe707bad3ac8f252a91212a56023217ce87 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj.filters +++ b/DWeChatRobot/DWeChatRobot.vcxproj.filters @@ -215,5 +215,8 @@ 好友相关\搜索好友 + + 好友相关\添加好友 + \ No newline at end of file diff --git a/DWeChatRobot/dllmain.cpp b/DWeChatRobot/dllmain.cpp index 06c222e9324b7032f4d9883ce0069378a4dccff1..faad9b4a6edcd7c1598093055c4b41b0bc71c9c0 100644 --- a/DWeChatRobot/dllmain.cpp +++ b/DWeChatRobot/dllmain.cpp @@ -13,7 +13,7 @@ BOOL APIENTRY DllMain( HMODULE hModule, #ifdef _DEBUG if (ProcessIsWeChat()) { PrintProcAddr(); - // HookLogMsgInfo(); + HookLogMsgInfo(); } #endif break; diff --git a/DWeChatRobot/pch.cpp b/DWeChatRobot/pch.cpp index 8e407654532da11a079f39a58c5ba3721275ed49..65c05edbdbe929617d27c614471fac5d920a6e7b 100644 --- a/DWeChatRobot/pch.cpp +++ b/DWeChatRobot/pch.cpp @@ -172,6 +172,7 @@ void PrintProcAddr() { printf("VerifyFriendApply 0x%08X\n", (DWORD)VerifyFriendApply); printf("AddFriendByV3 0x%08X\n", (DWORD)AddFriendByV3); printf("AddFriendByWxid 0x%08X\n", (DWORD)AddFriendByWxid); + printf("AddBrandContact 0x%08X\n", (DWORD)AddBrandContact); printf("SelectDataRemote 0x%08X\n", (DWORD)SelectDataRemote); printf("SearchContactByNet 0x%08X\n", (DWORD)SearchContactByNet); printf("SearchContactByNetRemote 0x%08X\n", (DWORD)SearchContactByNetRemote); diff --git a/DWeChatRobot/pch.h b/DWeChatRobot/pch.h index d46bdcee5a348e60764c346038d1eb9553cf5a0c..acfceaec157a7a95fa6b2f102d49deb2808b4c35 100644 --- a/DWeChatRobot/pch.h +++ b/DWeChatRobot/pch.h @@ -36,6 +36,7 @@ using namespace std; #pragma comment(lib,"version.lib") +#pragma warning(disable:4731) // 对于导出函数,需要使用此宏修饰 #define DLLEXPORT extern "C" __declspec(dllexport) diff --git a/Python/wxRobot.py b/Python/wxRobot.py index 3e6b85141023ba7e071cc8918b913c802822b2d1..2ce1cf639cb2d13e2fb11cf91265dc645c495dac 100644 --- a/Python/wxRobot.py +++ b/Python/wxRobot.py @@ -265,4 +265,7 @@ class WeChatRobot(): userinfo = self.robot.CSearchContactByNet(keyword) if userinfo: return dict(userinfo) - return userinfo \ No newline at end of file + return userinfo + + def AddBrandContact(self,PublicId): + return self.robot.CAddBrandContact(PublicId) \ No newline at end of file diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index 729075af70abaea3af7bfba20db2d00ef418b6f3..e6d54ef3b588db8e696770b22545bae0b7138638 100644 Binary files a/Release/CWeChatRobot.exe and b/Release/CWeChatRobot.exe differ diff --git a/Release/DWeChatRobot.dll b/Release/DWeChatRobot.dll index 1ad249f5e5cdce9f90ef944fb8237418fbe5e30f..ead797405aa3b5b239b66c76659d4efe6ea15b26 100644 Binary files a/Release/DWeChatRobot.dll and b/Release/DWeChatRobot.dll differ