From d542f34d3e7f94253f37e9b5977ed19846eff391 Mon Sep 17 00:00:00 2001 From: ljc545w Date: Mon, 29 Aug 2022 23:06:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=AE=E5=BD=95=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 35 +- CWeChatRobot/WeChatRobotCOM.vcxproj | 12 +- ComWeChatRobot.sln | 64 ---- DWeChatRobot/DWeChatRobot.vcxproj | 10 + DWeChatRobot/ReceiveMessage.cpp | 2 +- Python/{ => com}/requirements.txt | 4 +- Python/{ => com}/test.py | 0 ...3\350\257\225\345\233\276\347\211\207.png" | Bin ...5\213\350\257\225\346\226\207\344\273\266" | Bin Python/{ => com}/wxRobot.py | 0 Python/http/wxDriver.py | 306 ++++++++++++++++++ README.md | 12 +- Release/CWeChatRobot.exe | Bin 144896 -> 144896 bytes Release/DWeChatRobot.dll | Bin 108032 -> 107520 bytes Release/socket/SWeChatRobot.dll | Bin 249344 -> 249856 bytes Release/socket/wxDriver.dll | Bin 20480 -> 20480 bytes Release/socket/wxDriver64.dll | Bin 27648 -> 27648 bytes WeChatTools/main.h | 2 - .../ESDK/HOOK\347\233\221\345\220\254.e" | Bin {ESDK => old_projects/ESDK}/HPSocket4C.dll | Bin {ESDK => old_projects/ESDK}/HP_Socket.ec | Bin .../VX3.7.0.26HOOK\346\250\241\345\235\227.e" | Bin ...VX3.7.0.26HOOK\346\250\241\345\235\227.ec" | Bin ...277\347\250\213\350\260\203\347\224\250.e" | Bin ...203\347\224\250\344\276\213\347\250\213.e" | Bin {ESDK => old_projects/ESDK}/test.e | Bin .../WeChatTools}/Inject.cpp | 63 ++-- .../WeChatTools}/WeChatTools.vcxproj | 2 +- .../WeChatTools}/WeChatTools.vcxproj.filters | 2 +- .../WeChatTools}/WeChatTools.vcxproj.user | 2 +- .../WeChatTools}/base.cpp | 11 +- .../WeChatTools}/base.h | 6 +- .../WeChatTools}/main.cpp | 21 +- old_projects/WeChatTools/main.h | 2 + {wxRobot => old_projects/wxRobot}/App.config | 4 +- {wxRobot => old_projects/wxRobot}/Program.cs | 4 +- .../wxRobot}/Properties/AssemblyInfo.cs | 26 +- .../wxRobot}/packages.config | 2 +- .../wxRobot}/wxRobot.csproj | 2 +- ...3\350\257\225\345\233\276\347\211\207.png" | Bin 399 -> 0 bytes ...5\213\350\257\225\346\226\207\344\273\266" | Bin 10240 -> 0 bytes wxDriver/wxDriver.vcxproj | 12 +- wxRobot/bin/Release/wxRobot.exe | Bin 7680 -> 0 bytes wxRobot/bin/Release/wxRobot.exe.config | 6 - 44 files changed, 449 insertions(+), 163 deletions(-) rename Python/{ => com}/requirements.txt (54%) rename Python/{ => com}/test.py (100%) rename "Python/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" => "Python/com/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" (100%) rename "Python/test/\346\265\213\350\257\225\346\226\207\344\273\266" => "Python/com/test/\346\265\213\350\257\225\346\226\207\344\273\266" (100%) rename Python/{ => com}/wxRobot.py (100%) create mode 100644 Python/http/wxDriver.py delete mode 100644 WeChatTools/main.h rename "ESDK/HOOK\347\233\221\345\220\254.e" => "old_projects/ESDK/HOOK\347\233\221\345\220\254.e" (100%) rename {ESDK => old_projects/ESDK}/HPSocket4C.dll (100%) rename {ESDK => old_projects/ESDK}/HP_Socket.ec (100%) rename "ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" => "old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" (100%) rename "ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" => "old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" (100%) rename "ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" => "old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" (100%) rename "ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" => "old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" (100%) rename {ESDK => old_projects/ESDK}/test.e (100%) rename {WeChatTools => old_projects/WeChatTools}/Inject.cpp (82%) rename {WeChatTools => old_projects/WeChatTools}/WeChatTools.vcxproj (99%) rename {WeChatTools => old_projects/WeChatTools}/WeChatTools.vcxproj.filters (99%) rename {WeChatTools => old_projects/WeChatTools}/WeChatTools.vcxproj.user (93%) rename {WeChatTools => old_projects/WeChatTools}/base.cpp (91%) rename {WeChatTools => old_projects/WeChatTools}/base.h (78%) rename {WeChatTools => old_projects/WeChatTools}/main.cpp (68%) create mode 100644 old_projects/WeChatTools/main.h rename {wxRobot => old_projects/wxRobot}/App.config (83%) rename {wxRobot => old_projects/wxRobot}/Program.cs (98%) rename {wxRobot => old_projects/wxRobot}/Properties/AssemblyInfo.cs (58%) rename {wxRobot => old_projects/wxRobot}/packages.config (91%) rename {wxRobot => old_projects/wxRobot}/wxRobot.csproj (99%) delete mode 100644 "test/\346\265\213\350\257\225\345\233\276\347\211\207.png" delete mode 100644 "test/\346\265\213\350\257\225\346\226\207\344\273\266" delete mode 100644 wxRobot/bin/Release/wxRobot.exe delete mode 100644 wxRobot/bin/Release/wxRobot.exe.config diff --git a/.gitignore b/.gitignore index b932c49..0b691d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,26 @@ -/Debug -*.exp -*.pdb -*.lib -*/Debug/ -*/Release/ -*/SOCKET_Debug/ -*/SOCKET_Release/ -*/Win32/ -*/x64/ +build/ +Debug/ +!/Release +Release/ +SOCKET_Debug/ +SOCKET_Release/ +Win32/ +x64/ *.rar -/.vs/ -/x64 -*/obj/ -/wxRobot/bin/Debug/ -/wxRobot/bin/Release/*.pdb -*/__pycache__/ -packages +obj/ +packages/ + mongoose.c mongoose.h json.hpp +# py +__pycache__/ +# Visual Studio +.vs +*.exp +*.pdb +*.lib # VSCode .vscode # JetBrians IDE diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index 6eb1e11..f0c6a3c 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -71,6 +71,8 @@ true true + false + false true @@ -79,6 +81,7 @@ true false + true true @@ -114,6 +117,10 @@ Windows true + + + + @@ -177,6 +184,9 @@ true true + + xcopy /y /d "$(TargetPath)" "$(SolutionDir)build\com\" + @@ -337,4 +347,4 @@ - \ No newline at end of file + diff --git a/ComWeChatRobot.sln b/ComWeChatRobot.sln index 0cfc740..c7ca181 100644 --- a/ComWeChatRobot.sln +++ b/ComWeChatRobot.sln @@ -5,21 +5,8 @@ VisualStudioVersion = 16.0.31605.320 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CWeChatRobot", "CWeChatRobot\WeChatRobotCOM.vcxproj", "{F54A8A7E-C2C0-4FD8-B625-59C77FF613BA}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeChatTools", "WeChatTools\WeChatTools.vcxproj", "{3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DWeChatRobot", "DWeChatRobot\DWeChatRobot.vcxproj", "{C0FC8DAB-0590-46AC-9270-6FEA45D52390}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wxRobot", "wxRobot", "{8E5B7B88-AB21-4B97-BAC1-956A35E33671}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Python", "Python", "{9533FA77-5AB8-473D-83D5-55E07137401E}" - ProjectSection(SolutionItems) = preProject - Python\wxRobot.py = Python\wxRobot.py - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSharp", "CSharp", "{4DE1F624-3F17-44E8-9B1F-28D88285D25F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wxRobot", "wxRobot\wxRobot.csproj", "{10504CFA-6D19-4A97-8728-11BCE6C2499F}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxDriver", "wxDriver\wxDriver.vcxproj", "{B8740C2A-CBE7-4873-9669-E0DFEC4A3B8D}" EndProject Global @@ -60,28 +47,6 @@ Global {F54A8A7E-C2C0-4FD8-B625-59C77FF613BA}.SOCKET_Release|x64.Build.0 = Release|x64 {F54A8A7E-C2C0-4FD8-B625-59C77FF613BA}.SOCKET_Release|x86.ActiveCfg = Release|Win32 {F54A8A7E-C2C0-4FD8-B625-59C77FF613BA}.SOCKET_Release|x86.Build.0 = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Debug|x64.ActiveCfg = Debug|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Debug|x64.Build.0 = Debug|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Debug|x86.ActiveCfg = Debug|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Debug|x86.Build.0 = Debug|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Release|Any CPU.ActiveCfg = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Release|x64.ActiveCfg = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Release|x64.Build.0 = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Release|x86.ActiveCfg = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.Release|x86.Build.0 = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|Any CPU.ActiveCfg = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|Any CPU.Build.0 = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|x64.ActiveCfg = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|x64.Build.0 = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|x86.ActiveCfg = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_DEBUG|x86.Build.0 = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|Any CPU.ActiveCfg = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|Any CPU.Build.0 = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|x64.ActiveCfg = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|x64.Build.0 = Release|x64 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|x86.ActiveCfg = Release|Win32 - {3F7198C7-68D1-4BBA-9BF2-B7FC67A9426E}.SOCKET_Release|x86.Build.0 = Release|Win32 {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.Debug|Any CPU.ActiveCfg = Debug|Win32 {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.Debug|x64.ActiveCfg = Debug|x64 {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.Debug|x64.Build.0 = Debug|x64 @@ -102,30 +67,6 @@ Global {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.SOCKET_Release|x64.Build.0 = SOCKET_Release|x64 {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.SOCKET_Release|x86.ActiveCfg = SOCKET_Release|Win32 {C0FC8DAB-0590-46AC-9270-6FEA45D52390}.SOCKET_Release|x86.Build.0 = SOCKET_Release|Win32 - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|x64.ActiveCfg = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|x64.Build.0 = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|x86.ActiveCfg = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Debug|x86.Build.0 = Debug|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|Any CPU.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|x64.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|x64.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|x86.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.Release|x86.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|Any CPU.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|Any CPU.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|x64.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|x64.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|x86.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_DEBUG|x86.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|Any CPU.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|Any CPU.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|x64.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|x64.Build.0 = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|x86.ActiveCfg = Release|Any CPU - {10504CFA-6D19-4A97-8728-11BCE6C2499F}.SOCKET_Release|x86.Build.0 = Release|Any CPU {B8740C2A-CBE7-4873-9669-E0DFEC4A3B8D}.Debug|Any CPU.ActiveCfg = Debug|Win32 {B8740C2A-CBE7-4873-9669-E0DFEC4A3B8D}.Debug|x64.ActiveCfg = Debug|x64 {B8740C2A-CBE7-4873-9669-E0DFEC4A3B8D}.Debug|x64.Build.0 = Debug|x64 @@ -152,11 +93,6 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {9533FA77-5AB8-473D-83D5-55E07137401E} = {8E5B7B88-AB21-4B97-BAC1-956A35E33671} - {4DE1F624-3F17-44E8-9B1F-28D88285D25F} = {8E5B7B88-AB21-4B97-BAC1-956A35E33671} - {10504CFA-6D19-4A97-8728-11BCE6C2499F} = {4DE1F624-3F17-44E8-9B1F-28D88285D25F} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {20BD2B3B-13AA-4C38-8216-127895041F93} EndGlobalSection diff --git a/DWeChatRobot/DWeChatRobot.vcxproj b/DWeChatRobot/DWeChatRobot.vcxproj index 287ff4a..8e2b58b 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj +++ b/DWeChatRobot/DWeChatRobot.vcxproj @@ -140,12 +140,14 @@ false $(ProjectName) + true false SWeChatRobot $(Configuration)\ $(SolutionDir)Release\socket\ + true true @@ -208,6 +210,10 @@ true false + + xcopy /y /d "$(TargetPath)" "$(SolutionDir)build\com\" +xcopy /y /d "$(OutDir)..\Python\com\wxRobot.py" "$(SolutionDir)build\com\" + @@ -228,6 +234,10 @@ true false + + xcopy /y /d "$(TargetPath)" "$(SolutionDir)build\http\" +xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http\" + diff --git a/DWeChatRobot/ReceiveMessage.cpp b/DWeChatRobot/ReceiveMessage.cpp index 75d1f06..8619442 100644 --- a/DWeChatRobot/ReceiveMessage.cpp +++ b/DWeChatRobot/ReceiveMessage.cpp @@ -142,7 +142,7 @@ static void dealMessage(DWORD messageAddr) string jstr = jMsg.dump() + '\n'; #ifdef USE_COM // 通过连接点,将消息广播给客户端 - VARIANT vsaValue = (_variant_t)jstr.c_str(); + VARIANT vsaValue = (_variant_t)utf8_to_unicode(jstr.c_str()).c_str(); PostComMessage(jMsg["pid"].get(), WX_MESSAGE, msgid, &vsaValue); #endif // 为保证线程安全,需要手动管理内存 diff --git a/Python/requirements.txt b/Python/com/requirements.txt similarity index 54% rename from Python/requirements.txt rename to Python/com/requirements.txt index 2857e84..2113b7a 100644 --- a/Python/requirements.txt +++ b/Python/com/requirements.txt @@ -1,2 +1,2 @@ -comtypes==1.1.11 -psutil==5.9.0 \ No newline at end of file +comtypes==1.1.11 +psutil==5.9.0 diff --git a/Python/test.py b/Python/com/test.py similarity index 100% rename from Python/test.py rename to Python/com/test.py diff --git "a/Python/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" "b/Python/com/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" similarity index 100% rename from "Python/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" rename to "Python/com/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" diff --git "a/Python/test/\346\265\213\350\257\225\346\226\207\344\273\266" "b/Python/com/test/\346\265\213\350\257\225\346\226\207\344\273\266" similarity index 100% rename from "Python/test/\346\265\213\350\257\225\346\226\207\344\273\266" rename to "Python/com/test/\346\265\213\350\257\225\346\226\207\344\273\266" diff --git a/Python/wxRobot.py b/Python/com/wxRobot.py similarity index 100% rename from Python/wxRobot.py rename to Python/com/wxRobot.py diff --git a/Python/http/wxDriver.py b/Python/http/wxDriver.py new file mode 100644 index 0000000..b65ca66 --- /dev/null +++ b/Python/http/wxDriver.py @@ -0,0 +1,306 @@ +import ctypes +import json +import copy +import threading +import requests +import base64 +import socketserver + +if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong): + driver = ctypes.cdll.LoadLibrary('./wxDriver64.dll') +else: + driver = ctypes.cdll.LoadLibrary('./wxDriver.dll') + +new_wechat = driver.new_wechat +new_wechat.argtypes = None +new_wechat.restype = ctypes.c_int + +start_listen = driver.start_listen +start_listen.argtypes = [ctypes.c_int,ctypes.c_int] +start_listen.restype = ctypes.c_int + +stop_listen = driver.stop_listen +stop_listen.argtypes = [ctypes.c_int] +stop_listen.restype = ctypes.c_int + +class WECHAT_HTTP_APIS: + # login check + WECHAT_IS_LOGIN = 0 # 鐧诲綍妫鏌 + + # self info + WECHAT_GET_SELF_INFO = 1 # 鑾峰彇涓汉淇℃伅 + + # send message + WECHAT_MSG_SEND_TEXT = 2 # 鍙戦佹枃鏈 + WECHAT_MSG_SEND_AT = 3 # 鍙戦佺兢鑹剧壒 + WECHAT_MSG_SEND_CARD = 4 # 鍒嗕韩濂藉弸鍚嶇墖 + WECHAT_MSG_SEND_IMAGE = 5 # 鍙戦佸浘鐗 + WECHAT_MSG_SEND_FILE = 6 # 鍙戦佹枃浠 + WECHAT_MSG_SEND_ARTICLE = 7 # 鍙戦亁ml鏂囩珷 + WECHAT_MSG_SEND_APP = 8 # 鍙戦佸皬绋嬪簭 + + # receive message + WECHAT_MSG_START_HOOK = 9 # 寮鍚帴鏀舵秷鎭疕OOK锛屽彧鏀寔socket鐩戝惉 + WECHAT_MSG_STOP_HOOK = 10 # 鍏抽棴鎺ユ敹娑堟伅HOOK + WECHAT_MSG_START_IMAGE_HOOK = 11 # 寮鍚浘鐗囨秷鎭疕OOK + WECHAT_MSG_STOP_IMAGE_HOOK = 12 # 鍏抽棴鍥剧墖娑堟伅HOOK + WECHAT_MSG_START_VOICE_HOOK = 13 # 寮鍚闊虫秷鎭疕OOK + WECHAT_MSG_STOP_VOICE_HOOK = 14 # 鍏抽棴璇煶娑堟伅HOOK + + # contact + WECHAT_CONTACT_GET_LIST = 15 # 鑾峰彇鑱旂郴浜哄垪琛 + WECHAT_CONTACT_CHECK_STATUS = 16 # 妫鏌ユ槸鍚﹁濂藉弸鍒犻櫎 + WECHAT_CONTACT_DEL = 17 # 鍒犻櫎濂藉弸 + WECHAT_CONTACT_SEARCH_BY_CACHE = 18 # 浠庡唴瀛樹腑鑾峰彇濂藉弸淇℃伅 + WECHAT_CONTACT_SEARCH_BY_NET = 19 # 缃戠粶鎼滅储鐢ㄦ埛淇℃伅 + WECHAT_CONTACT_ADD_BY_WXID = 20 # wxid鍔犲ソ鍙 + WECHAT_CONTACT_ADD_BY_V3 = 21 # v3鏁版嵁鍔犲ソ鍙 + WECHAT_CONTACT_ADD_BY_PUBLIC_ID = 22 # 鍏虫敞鍏紬鍙 + WECHAT_CONTACT_VERIFY_APPLY = 23 # 閫氳繃濂藉弸璇锋眰 + WECHAT_CONTACT_EDIT_REMARK = 24 # 淇敼澶囨敞 + + # chatroom + WECHAT_CHATROOM_GET_MEMBER_LIST = 25 # 鑾峰彇缇ゆ垚鍛樺垪琛 + WECHAT_CHATROOM_GET_MEMBER_NICKNAME = 26 # 鑾峰彇鎸囧畾缇ゆ垚鍛樻樀绉 + WECHAT_CHATROOM_DEL_MEMBER = 27 # 鍒犻櫎缇ゆ垚鍛 + WECHAT_CHATROOM_ADD_MEMBER = 28 # 娣诲姞缇ゆ垚鍛 + WECHAT_CHATROOM_SET_ANNOUNCEMENT = 29 # 璁剧疆缇ゅ叕鍛 + WECHAT_CHATROOM_SET_CHATROOM_NAME = 30 # 璁剧疆缇よ亰鍚嶇О + WECHAT_CHATROOM_SET_SELF_NICKNAME = 31 # 璁剧疆缇ゅ唴涓汉鏄电О + + # database + WECHAT_DATABASE_GET_HANDLES = 32 # 鑾峰彇鏁版嵁搴撳彞鏌 + WECHAT_DATABASE_BACKUP = 33 # 澶囦唤鏁版嵁搴 + WECHAT_DATABASE_QUERY = 34 # 鏁版嵁搴撴煡璇 + + # version + WECHAT_SET_VERSION = 35 # 淇敼寰俊鐗堟湰鍙 + + # log + WECHAT_LOG_START_HOOK = 36 # 寮鍚棩蹇椾俊鎭疕OOK + WECHAT_LOG_STOP_HOOK = 37 # 鍏抽棴鏃ュ織淇℃伅HOOK + +APIS = WECHAT_HTTP_APIS + +# http api 鍙傛暟妯℃澘 +class WECHAT_HTTP_API_PARAM_TEMPLATES: + __HTTP_API_PARAM_TEMPLATE = { + # login check + APIS.WECHAT_IS_LOGIN: {}, + + + # self info + APIS.WECHAT_GET_SELF_INFO: {}, + + + # send message + APIS.WECHAT_MSG_SEND_TEXT: {"wxid": "", + "msg": ""}, + # wxids闇瑕佷互`,`鍒嗛殧锛屼緥濡俙wxid1,wxid2,wxid3` + APIS.WECHAT_MSG_SEND_AT: {"chatroom_id":"", + "wxids": "", + "msg": "", + "auto_nickname": 1}, + APIS.WECHAT_MSG_SEND_CARD: {"receiver":"", + "shared_wxid":"", + "nickname":""}, + APIS.WECHAT_MSG_SEND_IMAGE: {"receiver":"", + "img_path":""}, + APIS.WECHAT_MSG_SEND_FILE: {"receiver":"", + "file_path":""}, + APIS.WECHAT_MSG_SEND_ARTICLE: {"wxid":"", + "title":"", + "abstract":"", + "url":"", + "img_path":""}, + APIS.WECHAT_MSG_SEND_APP: {"wxid":"", + "appid":""}, + + + # receive message + APIS.WECHAT_MSG_START_HOOK: {"port": 10808}, + APIS.WECHAT_MSG_STOP_HOOK: {}, + APIS.WECHAT_MSG_START_IMAGE_HOOK: {"save_path":""}, + APIS.WECHAT_MSG_STOP_IMAGE_HOOK: {}, + APIS.WECHAT_MSG_START_VOICE_HOOK: {"save_path":""}, + APIS.WECHAT_MSG_STOP_VOICE_HOOK: {}, + + + # contact + APIS.WECHAT_CONTACT_GET_LIST: {}, + APIS.WECHAT_CONTACT_CHECK_STATUS: {"wxid":""}, + APIS.WECHAT_CONTACT_DEL: {"wxid":""}, + APIS.WECHAT_CONTACT_SEARCH_BY_CACHE: {"wxid":""}, + APIS.WECHAT_CONTACT_SEARCH_BY_NET: {"keyword":""}, + APIS.WECHAT_CONTACT_ADD_BY_WXID: {"wxid":"", + "msg":""}, + APIS.WECHAT_CONTACT_ADD_BY_V3: {"v3":"", + "msg":"", + "add_type": 0x6}, + APIS.WECHAT_CONTACT_ADD_BY_PUBLIC_ID: {"public_id":""}, + APIS.WECHAT_CONTACT_VERIFY_APPLY: {"v3":"", + "v4":""}, + APIS.WECHAT_CONTACT_EDIT_REMARK: {"wxid":"", + "remark":""}, + + + # chatroom + APIS.WECHAT_CHATROOM_GET_MEMBER_LIST: {"chatroom_id":""}, + APIS.WECHAT_CHATROOM_GET_MEMBER_NICKNAME: {"chatroom_id":"", + "wxid":""}, + # wxids闇瑕佷互`,`鍒嗛殧锛屼緥濡俙wxid1,wxid2,wxid3` + APIS.WECHAT_CHATROOM_DEL_MEMBER: {"chatroom_id":"", + "wxids":""}, + # wxids闇瑕佷互`,`鍒嗛殧锛屼緥濡俙wxid1,wxid2,wxid3` + APIS.WECHAT_CHATROOM_ADD_MEMBER: {"chatroom_id":"", + "wxids":""}, + APIS.WECHAT_CHATROOM_SET_ANNOUNCEMENT: {"chatroom_id":"", + "announcement":""}, + APIS.WECHAT_CHATROOM_SET_CHATROOM_NAME: {"chatroom_id":"", + "chatroom_name":""}, + APIS.WECHAT_CHATROOM_SET_SELF_NICKNAME: {"chatroom_id":"", + "nickname":""}, + + + # database + APIS.WECHAT_DATABASE_GET_HANDLES: {}, + APIS.WECHAT_DATABASE_BACKUP: {"db_handle":0, + "save_path":""}, + APIS.WECHAT_DATABASE_QUERY: {"db_handle":0, + "sql":""}, + + + # version + APIS.WECHAT_SET_VERSION: {"version": "3.7.0.30"}, + + + # log + APIS.WECHAT_LOG_START_HOOK: {}, + APIS.WECHAT_LOG_STOP_HOOK: {}, + } + + def get_http_template(self, api_number): + try: + return copy.deepcopy(self.__HTTP_API_PARAM_TEMPLATE[api_number]) + except KeyError: + raise ValueError("There is no interface numbered %s." % api_number) + +get_http_template = WECHAT_HTTP_API_PARAM_TEMPLATES().get_http_template + +class ReceiveMsgSocketServer(socketserver.BaseRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def handle(self): + conn = self.request + while True: + try: + ptr_data = b"" + while True: + data = conn.recv(1024) + ptr_data += data + if len(data) == 0 or data[-1] == 0xA: + break + msg = json.loads(ptr_data.decode('utf-8')) + ReceiveMsgSocketServer.msg_callback(msg) + except OSError: + break + except json.JSONDecodeError: + pass + conn.sendall("200 OK".encode()) + conn.close() + + @staticmethod + def msg_callback(msg): + # 闄勫姞淇℃伅鏄痯rotobuf鏍煎紡锛岄渶瑕佽嚜琛屽鐞 + msg['extrainfo'] = base64.b64decode(msg['extrainfo']) + # TODO: 鍦ㄨ繖閲屽啓棰濆鐨勬秷鎭鐞嗛昏緫 + + print(msg) + +def post_wechat_http_api(api,port,data = {}): + url = "http://127.0.0.1:{}/api/?type={}".format(port,api) + resp = requests.post(url = url,data = json.dumps(data)) + return resp.json() + +def get_wechat_http_api(api,port,data = {}): + url = "http://127.0.0.1:{}/api/?type={}".format(port,api) + resp = requests.get(url = url,params = data) + return 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 start_socket_server(port: int = 10808, + request_handler = ReceiveMsgSocketServer, + main_thread: bool = True) -> int or None: + ip_port = ("127.0.0.1", port) + try: + s = socketserver.ThreadingTCPServer(ip_port, request_handler) + if main_thread: + s.serve_forever() + else: + socket_server = threading.Thread(target=s.serve_forever) + socket_server.setDaemon(True) + socket_server.start() + return socket_server.ident + except KeyboardInterrupt: + pass + except Exception as e: + print(e) + return None + +def test(test_port): + post_wechat_http_api(APIS.WECHAT_LOG_START_HOOK,port = test_port) + if post_wechat_http_api(APIS.WECHAT_IS_LOGIN,port = test_port)["is_login"] == 1: + print(post_wechat_http_api(APIS.WECHAT_GET_SELF_INFO,port = test_port)) + + data = {"wxid":"filehelper","msg":"hello http"} + post_wechat_http_api(APIS.WECHAT_MSG_SEND_TEXT,data = data,port = test_port) + + data = {"receiver":'filehelper',"shared_wxid":"filehelper","nickname":"鏂囦欢浼犺緭鍔╂墜"} + post_wechat_http_api(APIS.WECHAT_MSG_SEND_CARD,data = data,port = test_port) + + data = {"receiver":'filehelper',"img_path":r"D:\VS2019C++\MyWeChatRobot\test\娴嬭瘯鍥剧墖.png"} + post_wechat_http_api(APIS.WECHAT_MSG_SEND_IMAGE,data = data,port = test_port) + + data = {"receiver":'filehelper',"file_path":r"D:\VS2019C++\MyWeChatRobot\test\娴嬭瘯鏂囦欢"} + post_wechat_http_api(APIS.WECHAT_MSG_SEND_FILE,data = data,port = test_port) + + data = {"wxid":'filehelper', + "title":"鐧惧害", + "abstract":"鐧惧害涓涓嬶紝浣犲氨鐭ラ亾", + "url":"https://www.baidu.com/", + "img_path":""} + post_wechat_http_api(APIS.WECHAT_MSG_SEND_ARTICLE,data = data,port = test_port) + + print(post_wechat_http_api(APIS.WECHAT_CONTACT_GET_LIST,port = test_port)) + data = {"wxid":"filehelper"} + print(post_wechat_http_api(APIS.WECHAT_CONTACT_CHECK_STATUS,data = data,port = test_port)) + dbs = post_wechat_http_api(APIS.WECHAT_DATABASE_GET_HANDLES,port = test_port) + db_handle = dbs['data'][0]['handle'] + sql = "select * from Contact limit 1;" + data = {"db_handle":db_handle,"sql":sql} + res = post_wechat_http_api(APIS.WECHAT_DATABASE_QUERY,data = data,port = test_port) + print(res) + post_wechat_http_api(APIS.WECHAT_LOG_STOP_HOOK,port = test_port) + +if __name__ == '__main__': + port = 8000 + pids = get_wechat_pid_list() + if len(pids) == 0: + pids.append(new_wechat()) + start_listen(pids[0],port) + post_wechat_http_api(APIS.WECHAT_LOG_START_HOOK,8000) + post_wechat_http_api(APIS.WECHAT_MSG_START_HOOK,8000,{"port":10808}) + start_socket_server() + stop_listen(pids[0]) diff --git a/README.md b/README.md index 6635bed..430e4ac 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,14 @@ PC寰俊鏈哄櫒浜猴紝瀹炵幇浠ヤ笅鍔熻兘锛 # 鐩綍璇存槑 `./CWeChatRobot`锛欳OM缁勪欢鐨勫疄鐜颁唬鐮 `./DWeChatRobot`锛氭敞鍏ョ殑DLL瀹炵幇浠g爜锛屾牴鎹钩鍙伴厤缃彲缂栬瘧鍑簊ocket鐗堝拰COM鐗 -`./wxRobot`: 鍖呭惈C#鐨勮皟鐢ㄧず渚 +`./old_projects`: 鍖呭惈C#鐨勮皟鐢ㄧず渚嬩互鍙3.7.0.26鐗堟湰鐨凟璇█璋冪敤 `./Python`锛歱ython绀轰緥鍜屾帴鍙f祴璇曟枃浠 `./wxDriver`锛歞river鐨勫疄鐜颁唬鐮侊紝鏈変簺鍑芥暟鍏锋湁涓瀹氱殑瀛︿範鎰忎箟 `./Release/CWeChatRobot.exe`锛氱紪璇戠殑COM缁勪欢 `./Release/DWeChatRobot.dll`锛氱紪璇戠殑DLL鏂囦欢 `./Release/socket`锛氬寘鍚玾xDriver.dll鍜宻ocket鎺ュ彛鐨凞LL `./Release/WeChatTools.exe`锛氱敤浜庤皟璇曟椂娉ㄥ叆鎴栧嵏杞紻LL绋嬪簭锛屽叿浣撳弬闃呯浉鍏充唬鐮 -# 娉ㄥ唽COM +# 蹇熷惎鍔 浠ョ鐞嗗憳鏉冮檺鎵ц浠ヤ笅鍛戒护锛 ```shell # 瀹夎 @@ -49,11 +49,11 @@ CWeChatRobot.exe /unregserver ``` # 璋冪敤 **Python锛** -鍙傝僛wxRobot.py](/Python/wxRobot.py) +鍙傝僛wxRobot.py](/Python/com/wxRobot.py) **C#锛** 鍙傝僛ComWechatRobotCsharp](https://github.com/RingoStudio/ComWechatRobotCsharp)锛屾劅璋RingoStudio 鐨勮础鐚 **鏄撹瑷锛** -鍙傝僛ESDK](/ESDK)锛屾劅璋lovezm 鐨勮础鐚 +鍙傝僛ESDK](/old_projects/ESDK)锛屾劅璋lovezm 鐨勮础鐚 # 鏇村鍔熻兘 1. 灏濊瘯娣诲姞issue涓殑鍔熻兘 @@ -118,11 +118,11 @@ CWeChatRobot.exe /unregserver 2. 閲嶆瀯COM涓殑閮ㄥ垎瀹炵幇 ## 2022.08.13 1. 鐜板湪娑堟伅HOOK鍐呭鍖呭惈娑堟伅ID -2. 瀹屾垚鍙戦佹秷鎭殑http鎺ュ彛锛屽彲鍙傝僛wxDriver.py](/Release/socket/wxDriver.py)锛屽叾浠栨帴鍙h繕闇瑕佷竴鐐规椂闂 +2. 瀹屾垚鍙戦佹秷鎭殑http鎺ュ彛锛屽彲鍙傝僛wxDriver.py](/Python/http/wxDriver.py)锛屽叾浠栨帴鍙h繕闇瑕佷竴鐐规椂闂 3. 鏂板椤圭洰閰嶇疆鏂囦欢锛屾劅璋amchii 鎻愪緵鐨勬柟娉 ## 2022.08.21 1. 鎵鏈夊姛鑳絟ttp鎺ュ彛灏佽瀹屾垚锛屽彲鎺ュ彈get銆乸ost璇锋眰 -2. 鎻愪緵http鎺ュ彛璋冪敤绀轰緥锛屽弬鑰僛wxDriver.py](/Release/socket/wxDriver.py) +2. 鎻愪緵http鎺ュ彛璋冪敤绀轰緥锛屽弬鑰僛wxDriver.py](/Python/http/wxDriver.py) ## 2022.08.25 1. 鎺ユ敹娑堟伅鏍煎紡淇敼涓簀son锛岀幇鍦ㄤ篃鍙互鑾峰彇鍒版墿灞曚俊鎭紝鍙粠鎵╁睍淇℃伅涓幏鍙栧埌鏂囦欢淇濆瓨璺緞鎴栬鑹剧壒浜簑xid 2. 浼樺寲鑾峰彇涓汉淇℃伅锛岃幏鍙栧ソ鍙嬩俊鎭帴鍙 diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index e628e019752e9872a4e492f26ca6c7eda94ff1b5..c2c78b3884ab0400dd46ac1053e1dbae1b9fcca5 100644 GIT binary patch delta 73 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

@^WjwYnIMFXYsCHd_AD>6N?n!#6h0onH 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 diff --git a/Release/socket/SWeChatRobot.dll b/Release/socket/SWeChatRobot.dll index 895c2238b75ed246bb11e26f9fad3574cdf0bd3a..7c59fd54a612b0cc28f643f5105f27b6f3c75c48 100644 GIT binary patch delta 12514 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 MhPG1+Ct$(<0@N|oiU0rr delta 12487 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 delta 112 zcmZozz}T>WaRDQ9)d|MU%#0JwtbvSV1|VPpVt*ixaRXv2kO%_^Gn$qYci1jKWS-bnP2qb6-h?ktL^jp&Jeb8xM&ez+Se7e%s?}3|VcxNa800rkB4*&oF diff --git a/WeChatTools/main.h b/WeChatTools/main.h deleted file mode 100644 index 7b5dfc1..0000000 --- a/WeChatTools/main.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -#include "base.h" \ No newline at end of file diff --git "a/ESDK/HOOK\347\233\221\345\220\254.e" "b/old_projects/ESDK/HOOK\347\233\221\345\220\254.e" similarity index 100% rename from "ESDK/HOOK\347\233\221\345\220\254.e" rename to "old_projects/ESDK/HOOK\347\233\221\345\220\254.e" diff --git a/ESDK/HPSocket4C.dll b/old_projects/ESDK/HPSocket4C.dll similarity index 100% rename from ESDK/HPSocket4C.dll rename to old_projects/ESDK/HPSocket4C.dll diff --git a/ESDK/HP_Socket.ec b/old_projects/ESDK/HP_Socket.ec similarity index 100% rename from ESDK/HP_Socket.ec rename to old_projects/ESDK/HP_Socket.ec diff --git "a/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" "b/old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" similarity index 100% rename from "ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" rename to "old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.e" diff --git "a/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" "b/old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" similarity index 100% rename from "ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" rename to "old_projects/ESDK/VX3.7.0.26HOOK\346\250\241\345\235\227.ec" diff --git "a/ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" "b/old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" similarity index 100% rename from "ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" rename to "old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227_\350\277\234\347\250\213\347\272\277\347\250\213\350\260\203\347\224\250.e" diff --git "a/ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" "b/old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" similarity index 100% rename from "ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" rename to "old_projects/ESDK/VX3.7.0.30\346\250\241\345\235\227\350\260\203\347\224\250\344\276\213\347\250\213.e" diff --git a/ESDK/test.e b/old_projects/ESDK/test.e similarity index 100% rename from ESDK/test.e rename to old_projects/ESDK/test.e diff --git a/WeChatTools/Inject.cpp b/old_projects/WeChatTools/Inject.cpp similarity index 82% rename from WeChatTools/Inject.cpp rename to old_projects/WeChatTools/Inject.cpp index 85e0f42..062cc69 100644 --- a/WeChatTools/Inject.cpp +++ b/old_projects/WeChatTools/Inject.cpp @@ -1,7 +1,8 @@ #include "base.h" HANDLE hProcess = NULL; -bool isFileExists_stat(string& name) { +bool isFileExists_stat(string &name) +{ struct stat buffer; return (stat(name.c_str(), &buffer) == 0); } @@ -9,23 +10,24 @@ bool isFileExists_stat(string& name) { string wstring2string(wstring wstr) { std::string result; - //获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的 + //获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的 int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL); - char* buffer = new char[len + 1]; - //宽字节编码转换成多字节编码 + char *buffer = new char[len + 1]; + //宽字节编码转换成多字节编码 WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL); buffer[len] = '\0'; - //删除缓冲区并返回值 + //删除缓冲区并返回值 result.append(buffer); delete[] buffer; return result; } -bool InjectDll(DWORD dwId, WCHAR* szPath)//参数1:目标进程PID 参数2:DLL路径 +bool InjectDll(DWORD dwId, WCHAR *szPath) //参数1:目标进程PID 参数2:DLL路径 { if (!hProcess) return 1; - if (GetWeChatRobotBase() != 0) { + if (GetWeChatRobotBase() != 0) + { printf("请勿重复注入\n"); return 1; } @@ -44,17 +46,20 @@ bool InjectDll(DWORD dwId, WCHAR* szPath)// { WriteProcessMemory(hProcess, pRemoteAddress, szPath, wcslen(szPath) * 2 + 2, &dwWriteSize); } - else { + else + { printf("写入失败!\n"); return 1; } //三、 创建一个远程线程,让目标进程调用LoadLibrary HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, pRemoteAddress, NULL, NULL); - if (hThread) { - WaitForSingleObject(hThread, -1); + if (hThread) + { + WaitForSingleObject(hThread, -1); } - else { + else + { printf("调用失败!\n"); return 1; } @@ -64,13 +69,15 @@ bool InjectDll(DWORD dwId, WCHAR* szPath)// return 0; } -void Inject(DWORD dwPid, wchar_t* wStr) { +void Inject(DWORD dwPid, wchar_t *wStr) +{ wchar_t dllpath[MAX_PATH]; wchar_t workPath[MAX_PATH]; - wchar_t* pworkPath = _wgetcwd(workPath, MAX_PATH); + wchar_t *pworkPath = _wgetcwd(workPath, MAX_PATH); swprintf_s(dllpath, MAX_PATH, L"%ws%ws%ws", pworkPath, L"\\", wStr); string name = wstring2string((wstring)dllpath); - if (!isFileExists_stat(name)) { + if (!isFileExists_stat(name)) + { wstring info = L"请检查目标文件路径!"; MessageBox(NULL, info.c_str(), _T("警告"), MB_ICONWARNING); return; @@ -79,38 +86,44 @@ void Inject(DWORD dwPid, wchar_t* wStr) { InjectDll(dwPid, dllpath); } -BOOL RemoveDll(DWORD dwId) { +BOOL RemoveDll(DWORD dwId) +{ hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId); LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); DWORD dwWriteSize = 0; HANDLE hThread = NULL; DWORD dwHandle, dwID; LPVOID pFunc = NULL; - if(pRemoteAddress) + if (pRemoteAddress) WriteProcessMemory(hProcess, pRemoteAddress, dllname, wcslen(dllname) * 2 + 2, &dwWriteSize); - else { + else + { printf("写入失败!\n"); return 1; } pFunc = GetModuleHandleW; hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pRemoteAddress, 0, &dwID); - if (hThread) { + if (hThread) + { WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &dwHandle); } - else { + else + { printf("GetModuleHandleW调用失败!\n"); return 1; } CloseHandle(hThread); - + // 释放console窗口,不然关闭console的同时微信也会退出 pFunc = FreeConsole; hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, &dwID); - if (hThread) { + if (hThread) + { WaitForSingleObject(hThread, INFINITE); } - else { + else + { printf("FreeConsole调用失败!\n"); return 1; } @@ -119,10 +132,12 @@ BOOL RemoveDll(DWORD dwId) { // 使目标进程调用FreeLibrary,卸载DLL pFunc = FreeLibrary; hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID); - if (hThread) { + if (hThread) + { WaitForSingleObject(hThread, INFINITE); } - else { + else + { printf("FreeLibrary调用失败!\n"); return 1; } diff --git a/WeChatTools/WeChatTools.vcxproj b/old_projects/WeChatTools/WeChatTools.vcxproj similarity index 99% rename from WeChatTools/WeChatTools.vcxproj rename to old_projects/WeChatTools/WeChatTools.vcxproj index 014152e..3a8d162 100644 --- a/WeChatTools/WeChatTools.vcxproj +++ b/old_projects/WeChatTools/WeChatTools.vcxproj @@ -151,4 +151,4 @@ - \ No newline at end of file + diff --git a/WeChatTools/WeChatTools.vcxproj.filters b/old_projects/WeChatTools/WeChatTools.vcxproj.filters similarity index 99% rename from WeChatTools/WeChatTools.vcxproj.filters rename to old_projects/WeChatTools/WeChatTools.vcxproj.filters index a00d997..a981004 100644 --- a/WeChatTools/WeChatTools.vcxproj.filters +++ b/old_projects/WeChatTools/WeChatTools.vcxproj.filters @@ -34,4 +34,4 @@ 閫氱敤鍑芥暟 - \ No newline at end of file + diff --git a/WeChatTools/WeChatTools.vcxproj.user b/old_projects/WeChatTools/WeChatTools.vcxproj.user similarity index 93% rename from WeChatTools/WeChatTools.vcxproj.user rename to old_projects/WeChatTools/WeChatTools.vcxproj.user index 88a5509..98dadff 100644 --- a/WeChatTools/WeChatTools.vcxproj.user +++ b/old_projects/WeChatTools/WeChatTools.vcxproj.user @@ -1,4 +1,4 @@ 锘 - \ No newline at end of file + diff --git a/WeChatTools/base.cpp b/old_projects/WeChatTools/base.cpp similarity index 91% rename from WeChatTools/base.cpp rename to old_projects/WeChatTools/base.cpp index 617e76d..aa85cca 100644 --- a/WeChatTools/base.cpp +++ b/old_projects/WeChatTools/base.cpp @@ -1,6 +1,7 @@ #include "base.h" -DWORD GetWeChatRobotBase() { +DWORD GetWeChatRobotBase() +{ if (!hProcess) return 0; DWORD dwWriteSize = 0; @@ -12,14 +13,16 @@ DWORD GetWeChatRobotBase() { DWORD dwHandle, dwID; LPVOID pFunc = GetModuleHandleW; HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pRemoteAddress, 0, &dwID); - if (hThread) { + if (hThread) + { WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &dwHandle); } - else { + else + { return 0; } CloseHandle(hThread); VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE); return dwHandle; -} \ No newline at end of file +} diff --git a/WeChatTools/base.h b/old_projects/WeChatTools/base.h similarity index 78% rename from WeChatTools/base.h rename to old_projects/WeChatTools/base.h index 899f5f0..91f6480 100644 --- a/WeChatTools/base.h +++ b/old_projects/WeChatTools/base.h @@ -13,12 +13,12 @@ using namespace std; -void Inject(DWORD dwPid, wchar_t* wStr); -bool isFileExists_stat(string& name); +void Inject(DWORD dwPid, wchar_t *wStr); +bool isFileExists_stat(string &name); string wstring2string(wstring wstr); BOOL RemoveDll(DWORD dwId); extern HANDLE hProcess; DWORD GetWeChatRobotBase(); #define dllname L"DWeChatRobot.dll" -#define SendImageOffset 0x000110BE \ No newline at end of file +#define SendImageOffset 0x000110BE diff --git a/WeChatTools/main.cpp b/old_projects/WeChatTools/main.cpp similarity index 68% rename from WeChatTools/main.cpp rename to old_projects/WeChatTools/main.cpp index 4a2141c..2ad5ab9 100644 --- a/WeChatTools/main.cpp +++ b/old_projects/WeChatTools/main.cpp @@ -1,29 +1,32 @@ #include "main.h" - -int _tmain(int nargv, WCHAR* argvs[]) +int _tmain(int nargv, WCHAR *argvs[]) { DWORD dwId = 0; HWND hCalc = FindWindow(NULL, L"微信"); DWORD dwPid = 0; DWORD dwRub = GetWindowThreadProcessId(hCalc, &dwPid); - if (!dwPid) { + if (!dwPid) + { wstring info = L"请先启动目标进程!"; MessageBox(NULL, info.c_str(), _T("警告"), MB_ICONWARNING); return 1; } - wchar_t* wStr = NULL; - - if (nargv == 1) { + wchar_t *wStr = NULL; + + if (nargv == 1) + { return 1; } - else if (nargv == 2) { + else if (nargv == 2) + { wStr = argvs[1]; Inject(dwPid, argvs[1]); } - else if (nargv == 3 && !((wstring)argvs[1]).compare(L"-r")) { + else if (nargv == 3 && !((wstring)argvs[1]).compare(L"-r")) + { wStr = argvs[2]; RemoveDll(dwPid); } return 0; -} \ No newline at end of file +} diff --git a/old_projects/WeChatTools/main.h b/old_projects/WeChatTools/main.h new file mode 100644 index 0000000..a8f455b --- /dev/null +++ b/old_projects/WeChatTools/main.h @@ -0,0 +1,2 @@ +#pragma once +#include "base.h" diff --git a/wxRobot/App.config b/old_projects/wxRobot/App.config similarity index 83% rename from wxRobot/App.config rename to old_projects/wxRobot/App.config index 56efbc7..359541c 100644 --- a/wxRobot/App.config +++ b/old_projects/wxRobot/App.config @@ -1,6 +1,6 @@ 锘 - + - \ No newline at end of file + diff --git a/wxRobot/Program.cs b/old_projects/wxRobot/Program.cs similarity index 98% rename from wxRobot/Program.cs rename to old_projects/wxRobot/Program.cs index 9f9fb68..68b8172 100644 --- a/wxRobot/Program.cs +++ b/old_projects/wxRobot/Program.cs @@ -83,10 +83,9 @@ namespace wxRobot wx.CStopReceiveMessage(); } - System.Object[,,] FriendList = wx.CGetFriendList() as System.Object[,,]; int length = FriendList.GetLength(0); - for (int i = 0; i < 1/*length*/; i++) + for (int i = 0; i < 1 /*length*/; i++) { Console.WriteLine(FriendList[i, 1, 1]); } @@ -126,7 +125,6 @@ namespace wxRobot Subscription = 3, } - public class WxUserInfo { ///

diff --git a/wxRobot/Properties/AssemblyInfo.cs b/old_projects/wxRobot/Properties/AssemblyInfo.cs similarity index 58% rename from wxRobot/Properties/AssemblyInfo.cs rename to old_projects/wxRobot/Properties/AssemblyInfo.cs index 895fb92..59843f4 100644 --- a/wxRobot/Properties/AssemblyInfo.cs +++ b/old_projects/wxRobot/Properties/AssemblyInfo.cs @@ -5,24 +5,24 @@ using System.Runtime.InteropServices; // 鏈夊叧绋嬪簭闆嗙殑涓鑸俊鎭敱浠ヤ笅 // 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у煎彲淇敼 // 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭 -[assembly: AssemblyTitle("wxRobot")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("wxRobot")] -[assembly: AssemblyCopyright("Copyright 漏 2022")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] +[assembly:AssemblyTitle("wxRobot")] +[assembly:AssemblyDescription("")] +[assembly:AssemblyConfiguration("")] +[assembly:AssemblyCompany("")] +[assembly:AssemblyProduct("wxRobot")] +[assembly:AssemblyCopyright("Copyright 漏 2022")] +[assembly:AssemblyTrademark("")] +[assembly:AssemblyCulture("")] // 灏 ComVisible 璁剧疆涓 false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷 //瀵 COM 缁勪欢涓嶅彲瑙併傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷 //璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规ц缃负 true銆 -[assembly: ComVisible(false)] +[assembly:ComVisible(false)] // 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID -[assembly: Guid("10504cfa-6d19-4a97-8728-11bce6c2499f")] +[assembly:Guid("10504cfa-6d19-4a97-8728-11bce6c2499f")] -// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓肩粍鎴: +// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓肩粍鎴: // // 涓荤増鏈 // 娆$増鏈 @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; //鍙互鎸囧畾鎵鏈夎繖浜涘硷紝涔熷彲浠ヤ娇鐢ㄢ滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊 //閫氳繃浣跨敤 "*"锛屽涓嬫墍绀: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly:AssemblyVersion("1.0.0.0")] +[assembly:AssemblyFileVersion("1.0.0.0")] diff --git a/wxRobot/packages.config b/old_projects/wxRobot/packages.config similarity index 91% rename from wxRobot/packages.config rename to old_projects/wxRobot/packages.config index 5eaa239..d4c6925 100644 --- a/wxRobot/packages.config +++ b/old_projects/wxRobot/packages.config @@ -1,4 +1,4 @@ 锘 - \ No newline at end of file + diff --git a/wxRobot/wxRobot.csproj b/old_projects/wxRobot/wxRobot.csproj similarity index 99% rename from wxRobot/wxRobot.csproj rename to old_projects/wxRobot/wxRobot.csproj index 2952244..6b8d8aa 100644 --- a/wxRobot/wxRobot.csproj +++ b/old_projects/wxRobot/wxRobot.csproj @@ -65,4 +65,4 @@ - \ No newline at end of file + diff --git "a/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" "b/test/\346\265\213\350\257\225\345\233\276\347\211\207.png" deleted file mode 100644 index 83ec3c6f4e02dd823414ad891a456bf18ccb1536..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^>wq|ggAGW^*K^wdDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpavCB7srr_xVM)ac^MQ04s2llKd+HpZQ7Rk zk~gf*JDmB~D)M+zO3b7l?@5K8MtYvdR8Q_uk({nFf&`n=^h%ep967wOcoi@Z89ZJ6 KT-G@yGywoSpqAeN diff --git "a/test/\346\265\213\350\257\225\346\226\207\344\273\266" "b/test/\346\265\213\350\257\225\346\226\207\344\273\266" deleted file mode 100644 index 9df64990f7be3c1f7194a0c22852a1ab3a09f3c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10240 zcmeIu0Sy2E0K%a6Pi+o2h(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM P7%*VKfB^#r47?2tC;$Kf diff --git a/wxDriver/wxDriver.vcxproj b/wxDriver/wxDriver.vcxproj index 1c1112b..884af81 100644 --- a/wxDriver/wxDriver.vcxproj +++ b/wxDriver/wxDriver.vcxproj @@ -79,6 +79,7 @@ false $(Platform)\$(Configuration)\ $(SolutionDir)$(Configuration)\socket\ + true true @@ -89,6 +90,7 @@ false $(ProjectName)64 $(SolutionDir)$(Configuration)\socket\ + true @@ -123,6 +125,10 @@ true false + + xcopy /y /d "$(TargetPath)" "$(SolutionDir)build\http\" +xcopy /y /d "$(OutDir)$(TargetName).lib" "$(SolutionDir)build\http\" + @@ -157,6 +163,10 @@ true false + + xcopy /y /d "$(TargetPath)" "$(SolutionDir)build\http\" +xcopy /y /d "$(OutDir)$(TargetName).lib" "$(SolutionDir)build\http\" + @@ -182,4 +192,4 @@ - \ No newline at end of file + diff --git a/wxRobot/bin/Release/wxRobot.exe b/wxRobot/bin/Release/wxRobot.exe deleted file mode 100644 index fb130d9d6d1f61d153c2163644505db96be0a3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 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 bJN~~=<6z?7WnZew!v6)U|2OeJ5`ljJ?MNNV diff --git a/wxRobot/bin/Release/wxRobot.exe.config b/wxRobot/bin/Release/wxRobot.exe.config deleted file mode 100644 index 56efbc7..0000000 --- a/wxRobot/bin/Release/wxRobot.exe.config +++ /dev/null @@ -1,6 +0,0 @@ -锘 - - - - - \ No newline at end of file -- GitLab