diff --git a/rpc/pb_util.cpp b/rpc/pb_util.cpp new file mode 100644 index 0000000..c57ad23 --- /dev/null +++ b/rpc/pb_util.cpp @@ -0,0 +1,66 @@ +#include + +#include "log.h" +#include "pb_util.h" +#include "wcf.pb.h" + +#define BUF_SIZE (1024 * 1024) +static char buf[BUF_SIZE] = { 0 }; + +typedef std::map MsgTypes_t; + +void log_buffer(uint8_t *buffer, size_t len) +{ + size_t j = sprintf_s(buf, BUF_SIZE, "Encoded message[%ld]: ", len); + for (size_t i = 0; i < len; i++) { + j += sprintf_s(buf + j, BUF_SIZE, "%02X ", buffer[i]); + if (j > BUF_SIZE - 3) { + break; + } + } + LOG_INFO(buf); +} + +bool encode_string(pb_ostream_t *stream, const pb_field_t *field, void *const *arg) +{ + const char *str = (const char *)*arg; + + if (!pb_encode_tag_for_field(stream, field)) { + return false; + } + + return pb_encode_string(stream, (uint8_t *)str, strlen(str)); +} + +bool decode_string(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + std::string *str = static_cast(*arg); + size_t len = stream->bytes_left; + str->resize(len); + if (!pb_read(stream, (uint8_t *)str->data(), len)) { + return false; + } + return true; +} + +bool encode_types(pb_ostream_t *stream, const pb_field_t *field, void *const *arg) +{ + MsgTypes_t *m = (MsgTypes_t *)*arg; + MsgTypes_TypesEntry message = MsgTypes_TypesEntry_init_default; + + for (auto it = m->begin(); it != m->end(); it++) { + message.key = it->first; + message.value.funcs.encode = &encode_string; + message.value.arg = (void *)it->second.c_str(); + + if (!pb_encode_tag_for_field(stream, field)) { + return false; + } + + if (!pb_encode_submessage(stream, MsgTypes_TypesEntry_fields, &message)) { + return false; + } + } + + return true; +} diff --git a/rpc/pb_util.h b/rpc/pb_util.h new file mode 100644 index 0000000..34ab1eb --- /dev/null +++ b/rpc/pb_util.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +void log_buffer(uint8_t *buffer, size_t len); +bool encode_string(pb_ostream_t *stream, const pb_field_t *field, void *const *arg); +bool decode_string(pb_istream_t *stream, const pb_field_t *field, void **arg); +bool encode_types(pb_ostream_t *stream, const pb_field_t *field, void *const *arg); \ No newline at end of file diff --git a/rpc/proto/wcf.options b/rpc/proto/wcf.options index 147be93..6be6891 100644 --- a/rpc/proto/wcf.options +++ b/rpc/proto/wcf.options @@ -1,6 +1,5 @@ # Generate all fields as pointers. * mangle_names:M_STRIP_PACKAGE * fallback_type:FT_POINTER -MsgTypes.types max_count:10 -MsgTypes.TypesEntry.value max_size:16 -# MsgTypes.* max_size:16 \ No newline at end of file +MsgTypes* fallback_type:FT_CALLBACK +RpcContact* fallback_type:FT_CALLBACK diff --git a/rpc/proto/wcf.proto b/rpc/proto/wcf.proto index 8d60a11..8628c17 100644 --- a/rpc/proto/wcf.proto +++ b/rpc/proto/wcf.proto @@ -55,14 +55,14 @@ message Response Functions func = 1; oneof msg { - int32 status = 2; - string str = 3; - WxMsg wxmsg = 4; - MsgTypes types = 5; + int32 status = 2; + string str = 3; + WxMsg wxmsg = 4; + MsgTypes types = 5; RpcContacts contacts = 6; - DbNames dbs = 7; - DbTables tables = 8; - DbRows rows = 9; + DbNames dbs = 7; + DbTables tables = 8; + DbRows rows = 9; }; } diff --git a/spy/Spy.vcxproj b/spy/Spy.vcxproj index 5c7c6d2..a982ca0 100644 --- a/spy/Spy.vcxproj +++ b/spy/Spy.vcxproj @@ -115,7 +115,7 @@ NotUsing - $(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;C:\Tools\vcpkg\installed\x86-windows-static\include + $(SolutionDir)rpc;$(SolutionDir)rpc\nanopb;$(SolutionDir)rpc\proto;$(SolutionDir)spy;C:\Tools\vcpkg\installed\x86-windows-static\include 4251;4819 MultiThreaded @@ -194,6 +194,7 @@ C:\Tools\nanopb\protoc --nanopb_out=. wcf.proto + @@ -212,6 +213,7 @@ C:\Tools\nanopb\protoc --nanopb_out=. wcf.proto + diff --git a/spy/Spy.vcxproj.filters b/spy/Spy.vcxproj.filters index d4e25a8..8adbac0 100644 --- a/spy/Spy.vcxproj.filters +++ b/spy/Spy.vcxproj.filters @@ -69,6 +69,9 @@ nnrpc + + nnrpc + @@ -116,6 +119,9 @@ nnrpc + + nnrpc + diff --git a/spy/receive_msg.cpp b/spy/receive_msg.cpp index d9cd734..6163c88 100644 --- a/spy/receive_msg.cpp +++ b/spy/receive_msg.cpp @@ -1,4 +1,31 @@ #pragma execution_character_set("utf-8") + +#include "receive_msg.h" + +MsgTypes_t GetMsgTypes() +{ + const std::map m = { { 0x01, "文字" }, + { 0x03, "图片" }, + { 0x22, "语音" }, + { 0x25, "好友确认" }, + { 0x28, "POSSIBLEFRIEND_MSG" }, + { 0x2A, "名片" }, + { 0x2B, "视频" }, + { 0x2F, "石头剪刀布 | 表情图片" }, + { 0x30, "位置" }, + { 0x31, "共享实时位置、文件、转账、链接" }, + { 0x32, "VOIPMSG" }, + { 0x33, "微信初始化" }, + { 0x34, "VOIPNOTIFY" }, + { 0x35, "VOIPINVITE" }, + { 0x3E, "小视频" }, + { 0x270F, "SYSNOTICE" }, + { 0x2710, "红包、系统消息" }, + { 0x2712, "撤回消息" } }; + + return m; +} + #if 0 #include @@ -55,11 +82,11 @@ void GetMsgTypes(MsgTypes *types) void HookAddress(DWORD hookAddr, LPVOID funcAddr, CHAR recvMsgBackupCode[5]) { - //组装跳转数据 + // 组装跳转数据 BYTE jmpCode[5] = { 0 }; jmpCode[0] = 0xE9; - //计算偏移 + // 计算偏移 *(DWORD *)&jmpCode[1] = (DWORD)funcAddr - hookAddr - 5; // 备份原来的代码 @@ -76,7 +103,7 @@ void UnHookAddress(DWORD hookAddr, CHAR restoreCode[5]) void DispatchMsg(DWORD reg) { WxMsg wxMsg; - DWORD *p = (DWORD *)reg; //消息结构基址 + DWORD *p = (DWORD *)reg; // 消息结构基址 wxMsg.set_type(GET_DWORD(*p + g_WxCalls.recvMsg.type)); wxMsg.set_is_self(GET_DWORD(*p + g_WxCalls.recvMsg.isSelf)); @@ -106,7 +133,7 @@ void DispatchMsg(DWORD reg) __declspec(naked) void RecieveMsgFunc() { __asm { - mov reg_buffer, edi //把值复制出来 + mov reg_buffer, edi // 把值复制出来 } DispatchMsg(reg_buffer); diff --git a/spy/receive_msg.h b/spy/receive_msg.h index 5c6be34..24294d9 100644 --- a/spy/receive_msg.h +++ b/spy/receive_msg.h @@ -1,4 +1,12 @@ #pragma once + +#include +#include + +typedef std::map MsgTypes_t; + +MsgTypes_t GetMsgTypes(); + #if 0 #include "../proto/wcf.grpc.pb.h" diff --git a/spy/rpc_server.cpp b/spy/rpc_server.cpp index 29136f3..ed8ead6 100644 --- a/spy/rpc_server.cpp +++ b/spy/rpc_server.cpp @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include "wcf.pb.h" @@ -19,6 +17,7 @@ #include "exec_sql.h" #include "get_contacts.h" #include "log.h" +#include "pb_util.h" #include "receive_msg.h" #include "rpc_server.h" #include "send_msg.h" @@ -26,6 +25,8 @@ #include "spy_types.h" #include "util.h" +#define G_BUF_SIZE (1024 * 1024) + extern int IsLogin(void); // Defined in spy.cpp extern std::string GetSelfWxid(); // Defined in spy.cpp @@ -39,18 +40,7 @@ bool gIsListening; static DWORD lThreadId = 0; static bool lIsRunning = false; static nng_socket sock; -static uint8_t gBuffer[1024 * 1024] = { 0 }; - -static void LogBuffer(uint8_t *buffer, size_t len) -{ - int j = 0; - char buf[1024] = { 0 }; - j = sprintf_s(buf, 1024, "Encoded message: "); - for (size_t i = 0; i < len; i++) { - j += sprintf_s(buf + j, 1024, "%02X ", buffer[i]); - } - LOG_INFO(buf); -} +static uint8_t gBuffer[G_BUF_SIZE] = { 0 }; bool func_is_login(uint8_t *out, size_t *len) { @@ -58,15 +48,13 @@ bool func_is_login(uint8_t *out, size_t *len) rsp.func = Functions_FUNC_IS_LOGIN; rsp.which_msg = Response_status_tag; rsp.msg.status = IsLogin(); - if (!pb_get_encoded_size(len, Response_fields, &rsp)) { - return false; - } pb_ostream_t stream = pb_ostream_from_buffer(out, *len); if (!pb_encode(&stream, Response_fields, &rsp)) { printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); return false; } + *len = stream.bytes_written; return true; } @@ -77,15 +65,33 @@ bool func_get_self_wxid(uint8_t *out, size_t *len) rsp.func = Functions_FUNC_IS_LOGIN; rsp.which_msg = Response_str_tag; rsp.msg.str = (char *)GetSelfWxid().c_str(); - if (!pb_get_encoded_size(len, Response_fields, &rsp)) { - return false; - } pb_ostream_t stream = pb_ostream_from_buffer(out, *len); if (!pb_encode(&stream, Response_fields, &rsp)) { printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); return false; } + *len = stream.bytes_written; + + return true; +} + +bool func_get_msg_types(uint8_t *out, size_t *len) +{ + Response rsp = Response_init_default; + rsp.func = Functions_FUNC_GET_MSG_TYPES; + rsp.which_msg = Response_types_tag; + + MsgTypes_t types = GetMsgTypes(); + rsp.msg.types.types.funcs.encode = encode_types; + rsp.msg.types.types.arg = &types; + + pb_ostream_t stream = pb_ostream_from_buffer(out, *len); + if (!pb_encode(&stream, Response_fields, &rsp)) { + printf("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + *len = stream.bytes_written; return true; } @@ -113,6 +119,11 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len ret = func_get_self_wxid(out, out_len); break; } + case Functions_FUNC_GET_MSG_TYPES: { + LOG_INFO("[Functions_FUNC_GET_MSG_TYPES]"); + ret = func_get_msg_types(out, out_len); + break; + } default: { LOG_ERROR("[UNKNOW FUNCTION]"); break; @@ -145,14 +156,15 @@ static int RunServer() lIsRunning = true; while (lIsRunning) { uint8_t *in = NULL; - size_t in_len, out_len; + size_t in_len, out_len = G_BUF_SIZE; if ((rv = nng_recv(sock, &in, &in_len, NNG_FLAG_ALLOC)) != 0) { LOG_ERROR("nng_recv: {}", rv); break; } - LogBuffer(in, in_len); + + log_buffer(in, in_len); if (dispatcher(in, in_len, gBuffer, &out_len)) { - LogBuffer(gBuffer, out_len); + log_buffer(gBuffer, out_len); rv = nng_send(sock, gBuffer, out_len, 0); if (rv != 0) { LOG_ERROR("nng_send: {}", rv);