diff --git a/rpc/proto/wcf.proto b/rpc/proto/wcf.proto index af52d80..b2937c8 100644 --- a/rpc/proto/wcf.proto +++ b/rpc/proto/wcf.proto @@ -22,6 +22,7 @@ enum Functions { FUNC_EXEC_DB_QUERY = 0x50; FUNC_ACCEPT_FRIEND = 0x51; FUNC_ADD_ROOM_MEMBERS = 0x52; + FUNC_DECRYPT_IMAGE = 0x60; } message Request @@ -37,6 +38,7 @@ message Request Verification v = 7; AddMembers m = 8; XmlMsg xml = 9; + DecPath dec = 10; } } @@ -151,3 +153,9 @@ message UserInfo string mobile = 3; // 手机号 string home = 4; // 文件/图片等父路径 } + +message DecPath +{ + string src = 1; // 源路径 + string dst = 2; // 目标路径 +} diff --git a/spy/Spy.vcxproj b/spy/Spy.vcxproj index fc410c9..c3d6591 100644 --- a/spy/Spy.vcxproj +++ b/spy/Spy.vcxproj @@ -232,6 +232,7 @@ C:\Tools\nanopb\protoc --nanopb_out=. wcf.proto + @@ -254,6 +255,7 @@ C:\Tools\nanopb\protoc --nanopb_out=. wcf.proto + diff --git a/spy/Spy.vcxproj.filters b/spy/Spy.vcxproj.filters index e02336a..b41235e 100644 --- a/spy/Spy.vcxproj.filters +++ b/spy/Spy.vcxproj.filters @@ -84,6 +84,9 @@ 头文件 + + 头文件 + @@ -140,6 +143,9 @@ 源文件 + + 源文件 + diff --git a/spy/decrypt_image.cpp b/spy/decrypt_image.cpp new file mode 100644 index 0000000..73b812f --- /dev/null +++ b/spy/decrypt_image.cpp @@ -0,0 +1,77 @@ +#include + +#include "decrypt_image.h" +#include "log.h" + +#define HEADER_PNG1 0x89 +#define HEADER_PNG2 0x50 +#define HEADER_JPG1 0xFF +#define HEADER_JPG2 0xD8 +#define HEADER_GIF1 0x47 +#define HEADER_GIF2 0x49 + +using namespace std; + +static string get_key(uint8_t header1, uint8_t header2, uint8_t *key) +{ + // PNG? + *key = HEADER_PNG1 ^ header1; + if ((HEADER_PNG2 ^ *key) == header2) { + return ".png"; + } + + // JPG? + *key = HEADER_JPG1 ^ header1; + if ((HEADER_JPG2 ^ *key) == header2) { + return ".jpg"; + } + + // GIF? + *key = HEADER_GIF1 ^ header1; + if ((HEADER_GIF2 ^ *key) == header2) { + return ".gif"; + } + + return ""; // 错误 +} + +bool DecryptImage(string src, string dst) +{ + ifstream in(src.c_str(), ios::binary); + if (!in.is_open()) { + LOG_ERROR("Failed to open file {}", src); + return false; + } + + filebuf *pfb = in.rdbuf(); + size_t size = pfb->pubseekoff(0, ios::end, ios::in); + pfb->pubseekpos(0, ios::in); + + char *pBuf = new char[size]; + pfb->sgetn(pBuf, size); + in.close(); + + uint8_t key = 0x00; + string ext = get_key(pBuf[0], pBuf[1], &key); + if (ext.empty()) { + LOG_ERROR("Failed to get key."); + return false; + } + + for (size_t i = 0; i < size; i++) { + pBuf[i] ^= key; + } + + ofstream out((dst + ext).c_str(), ios::binary); + if (!out.is_open()) { + LOG_ERROR("Failed to open file {}", dst); + return false; + } + + out.write(pBuf, size); + out.close(); + + delete[] pBuf; + + return true; +} diff --git a/spy/decrypt_image.h b/spy/decrypt_image.h new file mode 100644 index 0000000..727726c --- /dev/null +++ b/spy/decrypt_image.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool DecryptImage(std::string src, std::string dst); diff --git a/spy/rpc_server.cpp b/spy/rpc_server.cpp index 863ce08..9183e84 100644 --- a/spy/rpc_server.cpp +++ b/spy/rpc_server.cpp @@ -18,6 +18,7 @@ #include "accept_new_friend.h" #include "add_chatroom_member.h" +#include "decrypt_image.h" #include "exec_sql.h" #include "get_contacts.h" #include "log.h" @@ -485,6 +486,28 @@ bool func_add_room_members(char *roomid, char *wxids, uint8_t *out, size_t *len) return true; } +bool func_decrypt_image(char *src, char *dst, uint8_t *out, size_t *len) +{ + Response rsp = Response_init_default; + rsp.func = Functions_FUNC_DECRYPT_IMAGE; + rsp.which_msg = Response_status_tag; + rsp.msg.status = 0; + + rsp.msg.status = (int)DecryptImage(src, dst); + if (rsp.msg.status != 1) { + LOG_ERROR("DecryptImage failed."); + } + + pb_ostream_t stream = pb_ostream_from_buffer(out, *len); + if (!pb_encode(&stream, Response_fields, &rsp)) { + LOG_ERROR("Encoding failed: {}", PB_GET_ERROR(&stream)); + return false; + } + *len = stream.bytes_written; + + return true; +} + static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len) { bool ret = false; @@ -583,6 +606,11 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len ret = func_add_room_members(req.msg.m.roomid, req.msg.m.wxids, out, out_len); break; } + case Functions_FUNC_DECRYPT_IMAGE: { + LOG_DEBUG("[FUNCTIONS_FUNC_DECRYPT_IMAGE]"); + ret = func_decrypt_image(req.msg.dec.src, req.msg.dec.dst, out, out_len); + break; + } default: { LOG_ERROR("[UNKNOW FUNCTION]"); break;