Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ecd7e349 | ||
|
|
c49eaf9203 | ||
|
|
0859358c29 | ||
|
|
3f596a4041 | ||
|
|
cfb4e9461f | ||
|
|
7d290e454c | ||
|
|
1c0bdaf73d | ||
|
|
c58293edc5 | ||
|
|
a39dad9e31 | ||
|
|
c4a9efa322 | ||
|
|
227a296624 |
Vendored
+1
-1
Submodule app/3rdparty/Detours updated: 4b8c659f54...f9204902c3
@@ -0,0 +1,23 @@
|
||||
#ifndef BASE_FUNCTION_RESOLVER_H_
|
||||
#define BASE_FUNCTION_RESOLVER_H_
|
||||
namespace base {
|
||||
class FunctionResolver {
|
||||
public:
|
||||
explicit FunctionResolver(uint64_t base_addr) : base_addr_(base_addr) {}
|
||||
|
||||
template <typename FuncType>
|
||||
FuncType ResolveFunction(uint64_t offset) {
|
||||
return reinterpret_cast<FuncType>(base_addr_ + offset);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t base_addr_;
|
||||
};
|
||||
|
||||
template<typename FuncType>
|
||||
auto CastFunction(FunctionResolver& resolver, uint64_t offset) {
|
||||
return resolver.ResolveFunction<FuncType>(offset);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
#endif
|
||||
@@ -7,6 +7,13 @@
|
||||
namespace base {
|
||||
|
||||
namespace utils {
|
||||
|
||||
#define STRINGIFY(S) #S
|
||||
#define DEFER_STRINGIFY(S) STRINGIFY(S)
|
||||
#define PRAGMA_MESSAGE(MSG) _Pragma(STRINGIFY(message(MSG)))
|
||||
#define FORMATTED_MESSAGE(MSG) "warning [TODO-" DEFER_STRINGIFY(__COUNTER__) "] " MSG " : " __FILE__ "(" DEFER_STRINGIFY(__LINE__) ")"
|
||||
#define TODO(MSG) PRAGMA_MESSAGE(FORMATTED_MESSAGE(MSG))
|
||||
|
||||
std::wstring Utf8ToWstring(const std::string &str);
|
||||
|
||||
std::string WstringToUtf8(const std::wstring &str);
|
||||
|
||||
@@ -30,7 +30,7 @@ add_subdirectory(../base base)
|
||||
|
||||
add_library(wxhelper SHARED ${CPP_FILES} ${ASM_FILES})
|
||||
|
||||
target_compile_definitions(wxhelper PRIVATE WECHAT_VERSION=39943)
|
||||
target_compile_definitions(wxhelper PRIVATE WECHAT_VERSION=391125)
|
||||
|
||||
# target_include_directories(wxhelper
|
||||
# PRIVATE ../base/src/include
|
||||
|
||||
@@ -2,237 +2,171 @@
|
||||
|
||||
#include "json_utils.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "offset.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils.h"
|
||||
#include "wechat_interface.h"
|
||||
#include "wxutils.h"
|
||||
|
||||
namespace offset = wechat::offset;
|
||||
namespace prototype = wechat::prototype;
|
||||
namespace func = wechat::function;
|
||||
namespace utils = base::utils;
|
||||
#include "wechat_service.h"
|
||||
#include "utils.h"
|
||||
namespace jsonutils = wxhelper::jsonutils;
|
||||
namespace wxhelper {
|
||||
prototype::WeChatString* BuildWechatString(const std::wstring& ws) {
|
||||
prototype::WeChatString* p =
|
||||
base::utils::WxHeapAlloc<prototype::WeChatString>(
|
||||
sizeof(prototype::WeChatString));
|
||||
wchar_t* p_chat_room_id =
|
||||
base::utils::WxHeapAlloc<wchar_t>((ws.size() + 1) * 2);
|
||||
wmemcpy(p_chat_room_id, ws.c_str(), ws.size() + 1);
|
||||
p->ptr = p_chat_room_id;
|
||||
p->length = static_cast<int32_t>(ws.size());
|
||||
p->max_length = static_cast<int32_t>(ws.size());
|
||||
p->c_len = 0;
|
||||
p->c_ptr = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
std::string ChatController::SendTextMsg(std::string params) {
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
SPDLOG_INFO("sendTextMsg wxid={},msg={}", jp["wxid"], jp["msg"]);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring msg = jsonutils::GetWStringParam(jp, "msg");
|
||||
prototype::WeChatString to_user(wxid);
|
||||
prototype::WeChatString text_msg(msg);
|
||||
uint64_t send_message_mgr_addr = base_addr + offset::kGetSendMessageMgr;
|
||||
uint64_t send_text_msg_addr = base_addr + offset::kSendTextMsg;
|
||||
uint64_t free_chat_msg_addr = base_addr + offset::kFreeChatMsg;
|
||||
char chat_msg[0x460] = {0};
|
||||
uint64_t temp[3] = {0};
|
||||
func::__GetSendMessageMgr mgr;
|
||||
mgr = (func::__GetSendMessageMgr)send_message_mgr_addr;
|
||||
func::__SendTextMsg send;
|
||||
send = (func::__SendTextMsg)send_text_msg_addr;
|
||||
func::__FreeChatMsg free;
|
||||
free = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
mgr();
|
||||
uint64_t success = send(reinterpret_cast<uint64_t>(&chat_msg),
|
||||
reinterpret_cast<uint64_t>(&to_user),
|
||||
reinterpret_cast<uint64_t>(&text_msg),
|
||||
reinterpret_cast<uint64_t>(&temp), 1, 1, 0, 0);
|
||||
free(reinterpret_cast<uint64_t>(&chat_msg));
|
||||
|
||||
int64_t success = wechat::WeChatService::GetInstance().SendTextMsg(wxid, msg);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret_data.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::SendImageMsg(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
SPDLOG_INFO("SendImageMsg params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring image_path = jsonutils::GetWStringParam(jp, "imagePath");
|
||||
prototype::WeChatString to_user(wxid);
|
||||
prototype::WeChatString image_full_path(image_path);
|
||||
uint64_t send_message_mgr_addr = base_addr + offset::kGetSendMessageMgr;
|
||||
uint64_t send_img_addr = base_addr + offset::kSendImageMsg;
|
||||
uint64_t new_chat_msg_addr = base_addr + offset::kChatMsgInstanceCounter;
|
||||
uint64_t free_chat_msg_addr = base_addr + offset::kFreeChatMsg;
|
||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
||||
func::__GetSendMessageMgr mgr =
|
||||
(func::__GetSendMessageMgr)send_message_mgr_addr;
|
||||
func::__SendImageMsg send_img = (func::__SendImageMsg)send_img_addr;
|
||||
func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
|
||||
char chat_msg[0x460] = {0};
|
||||
char chat_msg_temp[0x460] = {0};
|
||||
|
||||
uint64_t p_chat_msg_temp =
|
||||
new_chat_msg(reinterpret_cast<uint64_t>(&chat_msg_temp));
|
||||
uint64_t temp1 = 0;
|
||||
uint64_t temp2 = 0;
|
||||
uint64_t* flag[10] = {};
|
||||
flag[8] = &temp1;
|
||||
flag[9] = &temp2;
|
||||
flag[1] = reinterpret_cast<uint64_t*>(p_chat_msg_temp);
|
||||
|
||||
uint64_t p_chat_msg = new_chat_msg(reinterpret_cast<uint64_t>(&chat_msg));
|
||||
uint64_t send_mgr = mgr();
|
||||
send_img(send_mgr, p_chat_msg, reinterpret_cast<uint64_t>(&to_user),
|
||||
reinterpret_cast<uint64_t>(&image_full_path),
|
||||
reinterpret_cast<uint64_t>(&flag));
|
||||
free(p_chat_msg);
|
||||
free(p_chat_msg_temp);
|
||||
success = 1;
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendImageMsg(wxid, image_path);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::SendFileMsg(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
SPDLOG_INFO("SendFileMsg params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring file_path = jsonutils::GetWStringParam(jp, "filePath");
|
||||
prototype::WeChatString* to_user = (prototype::WeChatString*)HeapAlloc(
|
||||
GetProcessHeap(), 0, sizeof(prototype::WeChatString));
|
||||
wchar_t* ptr_wxid =
|
||||
(wchar_t*)HeapAlloc(GetProcessHeap(), 0, (wxid.length() + 1) * 2);
|
||||
wmemcpy(ptr_wxid, wxid.c_str(), wxid.length() + 1);
|
||||
to_user->ptr = ptr_wxid;
|
||||
to_user->length = static_cast<DWORD>(wxid.length());
|
||||
to_user->max_length = static_cast<DWORD>(wxid.length());
|
||||
to_user->c_len = 0;
|
||||
to_user->c_ptr = 0;
|
||||
prototype::WeChatString* file_full_path = (prototype::WeChatString*)HeapAlloc(
|
||||
GetProcessHeap(), 0, sizeof(prototype::WeChatString));
|
||||
wchar_t* ptr_path =
|
||||
(wchar_t*)HeapAlloc(GetProcessHeap(), 0, (file_path.length() + 1) * 2);
|
||||
wmemcpy(ptr_path, file_path.c_str(), file_path.length() + 1);
|
||||
file_full_path->ptr = ptr_path;
|
||||
file_full_path->length = static_cast<DWORD>(file_path.length());
|
||||
file_full_path->max_length = static_cast<DWORD>(file_path.length());
|
||||
file_full_path->c_len = 0;
|
||||
file_full_path->c_ptr = 0;
|
||||
|
||||
uint64_t get_app_msg_mgr_addr = base_addr + offset::kGetAppMsgMgr;
|
||||
uint64_t send_file_addr = base_addr + offset::kSendFileMsg;
|
||||
uint64_t new_chat_msg_addr = base_addr + offset::kChatMsgInstanceCounter;
|
||||
uint64_t free_chat_msg_addr = base_addr + offset::kFreeChatMsg;
|
||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
||||
func::__GetAppMsgMgr get_app_mgr = (func::__GetAppMsgMgr)get_app_msg_mgr_addr;
|
||||
func::__SendFile send_file = (func::__SendFile)send_file_addr;
|
||||
func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
|
||||
char* chat_msg = (char*)HeapAlloc(GetProcessHeap(), 0, 0x460);
|
||||
|
||||
uint64_t* temp1 =
|
||||
(uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4);
|
||||
uint64_t* temp2 =
|
||||
(uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4);
|
||||
uint64_t* temp3 =
|
||||
(uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4);
|
||||
uint64_t* temp4 =
|
||||
(uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4);
|
||||
ZeroMemory(temp1, sizeof(uint64_t) * 4);
|
||||
ZeroMemory(temp2, sizeof(uint64_t) * 4);
|
||||
ZeroMemory(temp3, sizeof(uint64_t) * 4);
|
||||
ZeroMemory(temp4, sizeof(uint64_t) * 4);
|
||||
*temp4 = 0x1F;
|
||||
uint64_t app_mgr = get_app_mgr();
|
||||
send_file(app_mgr, reinterpret_cast<uint64_t>(chat_msg),
|
||||
reinterpret_cast<uint64_t>(to_user),
|
||||
reinterpret_cast<uint64_t>(file_full_path), 1,
|
||||
reinterpret_cast<uint64_t>(temp1), 0,
|
||||
reinterpret_cast<uint64_t>(temp2), 0,
|
||||
reinterpret_cast<uint64_t>(temp3), 0, 0);
|
||||
free(reinterpret_cast<uint64_t>(chat_msg));
|
||||
HeapFree(GetProcessHeap(), 0, to_user);
|
||||
HeapFree(GetProcessHeap(), 0, file_full_path);
|
||||
HeapFree(GetProcessHeap(), 0, temp1);
|
||||
HeapFree(GetProcessHeap(), 0, temp2);
|
||||
HeapFree(GetProcessHeap(), 0, temp3);
|
||||
HeapFree(GetProcessHeap(), 0, temp4);
|
||||
success = 1;
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendFileMsg(wxid, file_path);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::SendAtText(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("SendAtText params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring chat_room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = jsonutils::GetArrayParam(jp, "wxids");
|
||||
std::wstring msg = jsonutils::GetWStringParam(jp, "msg");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendAtText(chat_room_id, wxids, msg);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::SendMultiAtText(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("SendMultiAtText params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
nlohmann::json array = jp["at"];
|
||||
std::vector<std::pair<std::wstring, std::wstring>> at;
|
||||
if (array.is_array()) {
|
||||
for (const auto& item : array) {
|
||||
at.push_back(std::make_pair(jsonutils::GetWStringParam(item, "wxid"),
|
||||
jsonutils::GetWStringParam(item, "msg")));
|
||||
}
|
||||
}
|
||||
std::wstring chat_room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendMultiAtText(chat_room_id, at);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
|
||||
std::string ChatController::SendCustomEmotion(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("SendCustomEmotion params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring file_path = jsonutils::GetWStringParam(jp, "filePath");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendCustomEmotion(file_path, wxid);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
TODO("")
|
||||
std::string ChatController::SendApplet(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("SendApplet params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring waid_concat = jsonutils::GetWStringParam(jp, "waidConcat");
|
||||
std::wstring waid = jsonutils::GetWStringParam(jp, "waid");
|
||||
std::wstring app_wxid = jsonutils::GetWStringParam(jp, "appletWxid");
|
||||
std::wstring json_param = jsonutils::GetWStringParam(jp, "jsonParam");
|
||||
std::wstring head_url = jsonutils::GetWStringParam(jp, "headImgUrl");
|
||||
std::wstring main_img = jsonutils::GetWStringParam(jp, "mainImg");
|
||||
std::wstring index_page = jsonutils::GetWStringParam(jp, "indexPage");
|
||||
int64_t success = wechat::WeChatService::GetInstance().SendApplet(
|
||||
wxid, waid_concat, waid, waid, app_wxid, json_param, head_url, main_img,
|
||||
index_page);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::SendPatMsg(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
SPDLOG_INFO("SendPatMsg params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "receiver");
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
UINT64 send_pat_msg_addr = base_addr + offset::kSendPatMsg;
|
||||
func::__SendPatMsg send_pat_msg = (func::__SendPatMsg)send_pat_msg_addr;
|
||||
prototype::WeChatString chat_room(room_id);
|
||||
prototype::WeChatString target(wxid);
|
||||
success = send_pat_msg(reinterpret_cast<UINT64>(&chat_room),
|
||||
reinterpret_cast<UINT64>(&target));
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SendPatMsg(room_id, wxid);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
return ret_data.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::ForwardMsg(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("ForwardMsg params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().ForwardMsg(msg_id, wxid);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::ForwardPublicMsgByMsgId(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("ForwardPublicMsgByMsgId params={}", params);
|
||||
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().ForwardPublicMsgByMsgId(wxid,
|
||||
msg_id);
|
||||
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::ForwardPublicMsg(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("ForwardPublicMsg params={}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring appname = jsonutils::GetWStringParam(jp, "appName");
|
||||
std::wstring username = jsonutils::GetWStringParam(jp, "userName");
|
||||
std::wstring title = jsonutils::GetWStringParam(jp, "title");
|
||||
std::wstring url = jsonutils::GetWStringParam(jp, "url");
|
||||
std::wstring thumburl = jsonutils::GetWStringParam(jp, "thumbUrl");
|
||||
std::wstring digest = jsonutils::GetWStringParam(jp, "digest");
|
||||
INT64 success = wechat::WeChatService::GetInstance().ForwardPublicMsg(
|
||||
wxid, title, url, thumburl, username, appname, digest);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string ChatController::GetContactOrChatRoomNickname(std::string params) {
|
||||
SPDLOG_INFO("GetContactOrChatRoomNickname params={}", params);
|
||||
int64_t success = -1;
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring nickname =
|
||||
wechat::WeChatService::GetInstance().GetContactOrChatRoomNickname(wxid);
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
{"code", success}, {"data", {"nickname", nickname}}, {"msg", "success"}};
|
||||
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
} // namespace wxhelper
|
||||
@@ -20,7 +20,6 @@ class ChatController : public http::HttpController<ChatController> {
|
||||
ADD_PATH("/api/forwardMsg", ForwardMsg);
|
||||
ADD_PATH("/api/forwardPublicMsgByMsgId", ForwardPublicMsgByMsgId);
|
||||
ADD_PATH("/api/forwardPublicMsg", ForwardPublicMsg);
|
||||
|
||||
PATHS_END
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,56 +1,150 @@
|
||||
#include "chat_room_controller.h"
|
||||
|
||||
#include "json_utils.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "wechat_interface.h"
|
||||
#include "wechat_service.h"
|
||||
#include "utils.h"
|
||||
namespace wxhelper {
|
||||
std::string ChatController::GetChatRoomDetailInfo(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::GetChatRoomDetailInfo(std::string params) {
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
SPDLOG_INFO("GetChatRoomDetailInfo chatRoomId={}", jp["chatRoomId"]);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
wechat::ChatRoomInfoInner chat_room_detail;
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetChatRoomDetailInfo(
|
||||
room_id, chat_room_detail);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
nlohmann::json detail = {
|
||||
{"chatRoomId", chat_room_detail.chat_room_id},
|
||||
{"notice", chat_room_detail.notice},
|
||||
{"admin", chat_room_detail.admin},
|
||||
{"xml", chat_room_detail.xml},
|
||||
};
|
||||
ret_data["data"] = detail;
|
||||
return ret_data.dump();
|
||||
}
|
||||
std::string ChatRoomController::GetMemberFromChatRoom(std::string params) {
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
SPDLOG_INFO("GetMemberFromChatRoom chatRoomId={}", jp["chatRoomId"]);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
wechat::ChatRoomMemberInner member;
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetMemberFromChatRoom(
|
||||
room_id, member);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
if (success > 0) {
|
||||
nlohmann::json member_info = {
|
||||
{"admin", member.admin},
|
||||
{"chatRoomId", member.chat_room_id},
|
||||
{"members", member.member},
|
||||
{"adminNickname", member.admin_nickname},
|
||||
{"memberNickname", member.member_nickname},
|
||||
};
|
||||
ret_data["data"] = member_info;
|
||||
}
|
||||
return ret_data.dump();
|
||||
}
|
||||
std::string ChatRoomController::AddMemberToChatRoom(std::string params) {
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
SPDLOG_INFO("AddMemberToChatRoom chatRoomId={},memberIds={}",
|
||||
jp["chatRoomId"], jp["memberIds"]);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = jsonutils::GetArrayParam(jp, "memberIds");
|
||||
std::vector<std::wstring> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(wxids[i]);
|
||||
}
|
||||
int64_t success = wechat::WeChatService::GetInstance().AddMemberToChatRoom(
|
||||
room_id, wxid_list);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::GetMemberFromChatRoom(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::DelMemberFromChatRoom(std::string params) {
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
SPDLOG_INFO("DelMemberFromChatRoom chatRoomId={},memberIds={}",
|
||||
jp["chatRoomId"], jp["memberIds"]);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = jsonutils::GetArrayParam(jp, "memberIds");
|
||||
std::vector<std::wstring> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(wxids[i]);
|
||||
}
|
||||
int64_t success = wechat::WeChatService::GetInstance().DelMemberFromChatRoom(
|
||||
room_id, wxid_list);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
return ret_data.dump();
|
||||
}
|
||||
std::string ChatRoomController::CreateChatRoom(std::string params) {
|
||||
SPDLOG_INFO("CreateChatRoom params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::vector<std::wstring> wxids = jsonutils::GetArrayParam(jp, "memberIds");
|
||||
int64_t success = wechat::WeChatService::GetInstance().CreateChatRoom(wxids);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::AddMemberToChatRoom(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::QuitChatRoom(std::string params) {
|
||||
SPDLOG_INFO("QuitChatRoom params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().QuitChatRoom(room_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::DelMemberFromChatRoom(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::InviteMemberToChatRoom(std::string params) {
|
||||
SPDLOG_INFO("InviteMemberToChatRoom params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = jsonutils::GetArrayParam(jp, "memberIds");
|
||||
int64_t success = wechat::WeChatService::GetInstance().InviteMemberToChatRoom(
|
||||
room_id, wxids);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::CreateChatRoom(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::TopMsg(std::string params) {
|
||||
SPDLOG_INFO("TopMsg params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().SetTopMsg(msg_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::QuitChatRoom(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::RemoveTopMsg(std::string params) {
|
||||
SPDLOG_INFO("RemoveTopMsg params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().RemoveTopMsg(room_id, msg_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::InviteMemberToChatRoom(std::string params) {
|
||||
std::string ChatRoomController::GetChatRoomMemberNickname(std::string params) {
|
||||
SPDLOG_INFO("GetChatRoomMemberNickname params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::wstring member_id = jsonutils::GetWStringParam(jp, "memberId");
|
||||
std::wstring name = wechat::WeChatService::GetInstance().GetChatRoomMemberNickname(room_id,
|
||||
member_id);
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
{"code", 1},
|
||||
{"data", {{"nickname", base::utils::WstringToUtf8(name)}}},
|
||||
{"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::TopMsg(std::string params) { return std::string(); }
|
||||
std::string ChatController::RemoveTopMsg(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::GetChatRoomMemberNickname(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string ChatController::ModifyChatRoomMemberNickName(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ChatRoomController::ModifyChatRoomMemberNickName(
|
||||
std::string params) {
|
||||
SPDLOG_INFO("ModifyChatRoomMemberNickName params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring room_id = jsonutils::GetWStringParam(jp, "chatRoomId");
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring nickName = jsonutils::GetWStringParam(jp, "nickName");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().ModChatRoomMemberNickName(
|
||||
room_id, wxid, nickName);
|
||||
nlohmann::json ret = {{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
return ret.dump();
|
||||
}
|
||||
} // namespace wxhelper
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "http_controller.h"
|
||||
|
||||
namespace wxhelper {
|
||||
class ChatController : public http::HttpController<ChatController> {
|
||||
class ChatRoomController : public http::HttpController<ChatRoomController> {
|
||||
public:
|
||||
PATHS_BEGIN
|
||||
ADD_PATH("/api/getChatRoomDetailInfo", GetChatRoomDetailInfo);
|
||||
|
||||
@@ -1,55 +1,16 @@
|
||||
#include "contacts_controller.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "offset.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "utils.h"
|
||||
#include "wechat_interface.h"
|
||||
#include "wxutils.h"
|
||||
#include "json_utils.h"
|
||||
|
||||
namespace offset = wechat::offset;
|
||||
namespace prototype = wechat::prototype;
|
||||
namespace func = wechat::function;
|
||||
namespace utils = base::utils;
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "wechat_interface.h"
|
||||
#include "wechat_service.h"
|
||||
namespace jsonutils = wxhelper::jsonutils;
|
||||
|
||||
std::string wxhelper::ContactsController::GetContactList(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t get_contact_mgr_addr = base_addr + offset::kGetContactMgr;
|
||||
uint64_t get_contact_list_addr = base_addr + offset::kGetContactList;
|
||||
func::__GetContactMgr get_contact_mgr =
|
||||
(func::__GetContactMgr)get_contact_mgr_addr;
|
||||
func::__GetContactList get_contact_list =
|
||||
(func::__GetContactList)get_contact_list_addr;
|
||||
uint64_t mgr = get_contact_mgr();
|
||||
uint64_t contact_vec[3] = {0, 0, 0};
|
||||
success = get_contact_list(mgr, reinterpret_cast<uint64_t>(&contact_vec));
|
||||
|
||||
uint64_t start = contact_vec[0];
|
||||
uint64_t end = contact_vec[2];
|
||||
namespace wxhelper {
|
||||
std::string ContactsController::GetContactList(std::string params) {
|
||||
SPDLOG_INFO("GetContactList params:{}", params);
|
||||
std::vector<wechat::ContactInner> vec;
|
||||
|
||||
while (start < end) {
|
||||
wechat::ContactInner temp;
|
||||
temp.wxid = wxutils::ReadWstringThenConvert(start + 0x10);
|
||||
temp.custom_account = wxutils::ReadWstringThenConvert(start + 0x30);
|
||||
temp.encrypt_name = wxutils::ReadWstringThenConvert(start + 0x50);
|
||||
temp.remark = wxutils::ReadWstringThenConvert(start + 0x80);
|
||||
temp.remark_pinyin = wxutils::ReadWstringThenConvert(start + 0x148);
|
||||
temp.remark_pinyin_all = wxutils::ReadWstringThenConvert(start + 0x168);
|
||||
temp.label_ids = wxutils::ReadWstringThenConvert(start + 0xc0);
|
||||
temp.nickname = wxutils::ReadWstringThenConvert(start + 0xA0);
|
||||
temp.pinyin = wxutils::ReadWstringThenConvert(start + 0x108);
|
||||
temp.pinyin_all = wxutils::ReadWstringThenConvert(start + 0x128);
|
||||
temp.verify_flag = *(int32_t *)(start + 0x70);
|
||||
temp.type = *(int32_t *)(start + 0x74);
|
||||
temp.reserved1 = *(int32_t *)(start + 0x1F0);
|
||||
temp.reserved2 = *(int32_t *)(start + 0x1F4);
|
||||
vec.push_back(temp);
|
||||
start += 0x6A8;
|
||||
}
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetContacts(vec);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||
@@ -74,33 +35,83 @@ std::string wxhelper::ContactsController::GetContactList(std::string params) {
|
||||
return ret_data.dump();
|
||||
}
|
||||
|
||||
std::string wxhelper::ContactsController::GetContactProfile(
|
||||
std::string ContactsController::GetContactProfile(
|
||||
std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("GetContactProfile params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
wechat::ContactProfileInner profile;
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().GetContactByWxid(wxid, profile);
|
||||
nlohmann::json ret = {{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
if (success == 1) {
|
||||
nlohmann::json contact_profile = {
|
||||
{"account", profile.account}, {"headImage", profile.head_image},
|
||||
{"nickname", profile.nickname}, {"v3", profile.v3},
|
||||
{"wxid", profile.wxid},
|
||||
};
|
||||
ret["data"] = contact_profile;
|
||||
}
|
||||
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string wxhelper::ContactsController::DelContact(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ContactsController::DelContact(std::string params) {
|
||||
SPDLOG_INFO("DelContact params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
int64_t success = wechat::WeChatService::GetInstance().DelContact(wxid);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string wxhelper::ContactsController::SearchContact(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ContactsController::SearchContact(std::string params) {
|
||||
SPDLOG_INFO("SearchContact params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring keyword = jsonutils::GetWStringParam(jp, "keyword");
|
||||
wechat::SearchContactInner contact;
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().SearchContact(keyword, contact);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
if (success == 1) {
|
||||
nlohmann::json info = {
|
||||
{"bigImage", contact.big_image},
|
||||
{"smallImage", contact.small_image},
|
||||
{"city", contact.city},
|
||||
{"nation", contact.nation},
|
||||
{"nickname", contact.nickname},
|
||||
{"province", contact.province},
|
||||
{"sex", contact.sex},
|
||||
{"signature", contact.signature},
|
||||
{"v2", contact.v2},
|
||||
{"v3", contact.v3},
|
||||
};
|
||||
ret["data"] = info;
|
||||
}
|
||||
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string wxhelper::ContactsController::AddContact(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ContactsController::AddContact(std::string params) {
|
||||
SPDLOG_INFO("AddContact params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring msg = jsonutils::GetWStringParam(jp, "msg");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().AddFriendByWxid(wxid, msg);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
|
||||
std::string wxhelper::ContactsController::VerifyApply(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
std::string ContactsController::VerifyApply(std::string params) {
|
||||
SPDLOG_INFO("VerifyApply params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring v3 = jsonutils::GetWStringParam(jp, "v3");
|
||||
std::wstring v4 = jsonutils::GetWStringParam(jp, "v4");
|
||||
int32_t permission = jsonutils::GetIntParam(jp, "permission");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().VerifyApply(v3, v4, permission);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef WXHELPER_HTTP_ROUTER_H_
|
||||
#define WXHELPER_HTTP_ROUTER_H_
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
#include "singleton.h"
|
||||
|
||||
@@ -1,210 +1,22 @@
|
||||
#include "misc_controller.h"
|
||||
|
||||
#include "json_utils.h"
|
||||
#include "memory.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "offset.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "utils.h"
|
||||
#include "wechat_db.h"
|
||||
#include "wechat_interface.h"
|
||||
#include "wxutils.h"
|
||||
#include "wechat_service.h"
|
||||
|
||||
namespace offset = wechat::offset;
|
||||
namespace prototype = wechat::prototype;
|
||||
namespace func = wechat::function;
|
||||
namespace utils = base::utils;
|
||||
namespace jsonutils = wxhelper::jsonutils;
|
||||
|
||||
namespace wxhelper {
|
||||
std::string MiscController::CheckLogin(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t accout_service_addr = base_addr + offset::kGetAccountServiceMgr;
|
||||
func::__GetAccountService GetSevice =
|
||||
(func::__GetAccountService)accout_service_addr;
|
||||
uint64_t service_addr = GetSevice();
|
||||
if (service_addr) {
|
||||
success = *(uint64_t *)(service_addr + 0x7F8);
|
||||
}
|
||||
int64_t success = wechat::WeChatService::GetInstance().CheckLogin();
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetUserInfo(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t accout_service_addr = base_addr + offset::kGetAccountServiceMgr;
|
||||
uint64_t get_app_data_save_path_addr =
|
||||
base_addr + offset::kGetAppDataSavePath;
|
||||
uint64_t get_current_data_path_addr = base_addr + offset::kGetCurrentDataPath;
|
||||
func::__GetAccountService GetSevice =
|
||||
(func::__GetAccountService)accout_service_addr;
|
||||
func::__GetDataSavePath GetDataSavePath =
|
||||
(func::__GetDataSavePath)get_app_data_save_path_addr;
|
||||
func::__GetCurrentDataPath GetCurrentDataPath =
|
||||
(func::__GetCurrentDataPath)get_current_data_path_addr;
|
||||
wechat::SelfInfoInner out;
|
||||
uint64_t service_addr = GetSevice();
|
||||
if (service_addr) {
|
||||
if (*(int64_t *)(service_addr + 0x80) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x80 + 0x10) == 0) {
|
||||
out.wxid = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x80 + 0x18) == 0xF) {
|
||||
out.wxid = std::string((char *)(service_addr + 0x80),
|
||||
*(int64_t *)(service_addr + 0x80 + 0x10));
|
||||
} else {
|
||||
out.wxid = std::string(*(char **)(service_addr + 0x80),
|
||||
*(int64_t *)(service_addr + 0x80 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x108) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x108 + 0x10) == 0) {
|
||||
out.account = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x108 + 0x18) == 0xF) {
|
||||
out.account = std::string((char *)(service_addr + 0x108),
|
||||
*(int64_t *)(service_addr + 0x108 + 0x10));
|
||||
} else {
|
||||
out.account = std::string(*(char **)(service_addr + 0x108),
|
||||
*(int64_t *)(service_addr + 0x108 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x128) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x128 + 0x10) == 0) {
|
||||
out.mobile = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x128 + 0x18) == 0xF) {
|
||||
out.mobile = std::string((char *)(service_addr + 0x128),
|
||||
*(int64_t *)(service_addr + 0x128 + 0x10));
|
||||
} else {
|
||||
out.mobile = std::string(*(char **)(service_addr + 0x128),
|
||||
*(int64_t *)(service_addr + 0x128 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x148) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x148 + 0x10) == 0) {
|
||||
out.signature = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x148 + 0x18) == 0xF) {
|
||||
out.signature = std::string((char *)(service_addr + 0x148),
|
||||
*(int64_t *)(service_addr + 0x148 + 0x10));
|
||||
} else {
|
||||
out.signature = std::string(*(char **)(service_addr + 0x148),
|
||||
*(int64_t *)(service_addr + 0x148 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x168) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x168 + 0x10) == 0) {
|
||||
out.country = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x168 + 0x18) == 0xF) {
|
||||
out.country = std::string((char *)(service_addr + 0x168),
|
||||
*(int64_t *)(service_addr + 0x168 + 0x10));
|
||||
} else {
|
||||
out.country = std::string(*(char **)(service_addr + 0x168),
|
||||
*(int64_t *)(service_addr + 0x168 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x188) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x188 + 0x10) == 0) {
|
||||
out.province = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x188 + 0x18) == 0xF) {
|
||||
out.province = std::string((char *)(service_addr + 0x188),
|
||||
*(int64_t *)(service_addr + 0x188 + 0x10));
|
||||
} else {
|
||||
out.province = std::string(*(char **)(service_addr + 0x188),
|
||||
*(int64_t *)(service_addr + 0x188 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x1A8) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x1A8 + 0x10) == 0) {
|
||||
out.city = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x1A8 + 0x18) == 0xF) {
|
||||
out.city = std::string((char *)(service_addr + 0x1A8),
|
||||
*(int64_t *)(service_addr + 0x1A8 + 0x10));
|
||||
} else {
|
||||
out.city = std::string(*(char **)(service_addr + 0x1A8),
|
||||
*(int64_t *)(service_addr + 0x1A8 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x1E8) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x1E8 + 0x10) == 0) {
|
||||
out.name = std::string();
|
||||
} else {
|
||||
if (*(int64_t *)(service_addr + 0x1E8 + 0x18) == 0xF) {
|
||||
out.name = std::string((char *)(service_addr + 0x1E8),
|
||||
*(int64_t *)(service_addr + 0x1E8 + 0x10));
|
||||
} else {
|
||||
out.name = std::string(*(char **)(service_addr + 0x1E8),
|
||||
*(int64_t *)(service_addr + 0x1E8 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x450) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x450 + 0x10) == 0) {
|
||||
out.head_img = std::string();
|
||||
} else {
|
||||
out.head_img = std::string(*(char **)(service_addr + 0x450),
|
||||
*(int64_t *)(service_addr + 0x450 + 0x10));
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x7B8) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x7B8 + 0x10) == 0) {
|
||||
out.public_key = std::string();
|
||||
} else {
|
||||
out.public_key = std::string(*(char **)(service_addr + 0x7B8),
|
||||
*(int64_t *)(service_addr + 0x7B8 + 0x10));
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x7D8) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x7D8 + 0x10) == 0) {
|
||||
out.private_key = std::string();
|
||||
} else {
|
||||
out.private_key = std::string(*(char **)(service_addr + 0x7D8),
|
||||
*(int64_t *)(service_addr + 0x7D8 + 0x10));
|
||||
}
|
||||
|
||||
if (*(int64_t *)(service_addr + 0x6E0) == 0 ||
|
||||
*(int64_t *)(service_addr + 0x6E8) == 0) {
|
||||
out.db_key = std::string();
|
||||
} else {
|
||||
int64_t byte_addr = *(int64_t *)(service_addr + 0x6E0);
|
||||
int64_t len = *(int64_t *)(service_addr + 0x6E8);
|
||||
out.db_key =
|
||||
base::utils::Bytes2Hex((BYTE *)byte_addr, static_cast<int>(len));
|
||||
}
|
||||
|
||||
uint64_t flag = *(uint64_t *)(service_addr + 0x7F8);
|
||||
if (flag == 1) {
|
||||
prototype::WeChatString current_data_path;
|
||||
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(¤t_data_path));
|
||||
if (current_data_path.ptr) {
|
||||
out.current_data_path = base::utils::WstringToUtf8(
|
||||
std::wstring(current_data_path.ptr, current_data_path.length));
|
||||
} else {
|
||||
out.current_data_path = std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
prototype::WeChatString data_save_path;
|
||||
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(&data_save_path));
|
||||
if (data_save_path.ptr) {
|
||||
out.data_save_path = base::utils::WstringToUtf8(
|
||||
std::wstring(data_save_path.ptr, data_save_path.length));
|
||||
} else {
|
||||
out.data_save_path = std::string();
|
||||
}
|
||||
success = 1;
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetSelfInfo(out);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
nlohmann::json j_info = {
|
||||
{"name", out.name},
|
||||
@@ -226,110 +38,132 @@ std::string MiscController::GetUserInfo(std::string params) {
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetSNSFirstPage(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetSNSFirstPage();
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetSNSNextPage(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("GetSNSNextPage params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t sns_id = jsonutils::GetInt64Param(jp, "snsId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().GetSNSNextPage(sns_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::AddFavFromMsg(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("AddFavFromMsg params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t sns_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().AddFavFromMsg(sns_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::AddFavFromImage(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("AddFavFromImage params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring image_path = jsonutils::GetWStringParam(jp, "imagePath");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().AddFavFromImage(wxid, image_path);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::DecodeImage(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("DecodeImage params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring file_path = jsonutils::GetWStringParam(jp, "filePath");
|
||||
std::wstring store_dir = jsonutils::GetWStringParam(jp, "storeDir");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().DecodeImage(file_path, store_dir);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetVoiceByMsgId(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("GetVoiceByMsgId params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
std::wstring store_dir = jsonutils::GetWStringParam(jp, "storeDir");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().GetVoiceByDB(msg_id, store_dir);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::DoOcrTask(std::string params) {
|
||||
SPDLOG_INFO("DoOcrTask params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring image_path = jsonutils::GetWStringParam(jp, "imagePath");
|
||||
std::string text("");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().DoOCRTask(image_path, text);
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
{"code", success}, {"data", {{"content", text}}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::LockWeChat(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t lock_mgr_addr = base_addr + offset::kGetLockWechatMgr;
|
||||
uint64_t request_lock_addr = base_addr + offset::kRequestLockWechat;
|
||||
func::__GetLockWechatMgr get_lock_mgr =
|
||||
(func::__GetLockWechatMgr)lock_mgr_addr;
|
||||
func::__RequestLockWechat request_lock =
|
||||
(func::__RequestLockWechat)request_lock_addr;
|
||||
uint64_t mgr = get_lock_mgr();
|
||||
success = request_lock(mgr);
|
||||
int64_t success = wechat::WeChatService::GetInstance().LockWeChat();
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::UnlockWeChat(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t lock_mgr_addr = base_addr + offset::kGetLockWechatMgr;
|
||||
uint64_t request_unlock_addr = base_addr + offset::kRequestUnLockWechat;
|
||||
func::__GetLockWechatMgr get_lock_mgr =
|
||||
(func::__GetLockWechatMgr)lock_mgr_addr;
|
||||
func::__RequestUnLockWechat request_unlock =
|
||||
(func::__RequestUnLockWechat)request_unlock_addr;
|
||||
uint64_t mgr = get_lock_mgr();
|
||||
success = request_unlock(mgr);
|
||||
int64_t success = wechat::WeChatService::GetInstance().UnlockWeChat();
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::ClickEnterWeChat(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
int64_t success = wechat::WeChatService::GetInstance().EnterWeChat();
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetLoginUrl(std::string params) {
|
||||
int64_t success = -1;
|
||||
int64_t base_addr = wxutils::GetWeChatWinBase();
|
||||
uint64_t login_mgr_addr = base_addr + offset::kGetQRCodeLoginMgr;
|
||||
func::__GetQRCodeLoginMgr get = (func::__GetQRCodeLoginMgr)login_mgr_addr;
|
||||
uint64_t addr = get();
|
||||
std::string login_url = wxutils::ReadWeChatStr(addr + 0x68);
|
||||
success = 1;
|
||||
std::string login_url = wechat::WeChatService::GetInstance().GetLoginUrl();
|
||||
nlohmann::json ret = {
|
||||
{"code", success},
|
||||
{"data", {"loginUrl", "http://weixin.qq.com/x/" + login_url}},
|
||||
{"msg", "success"}};
|
||||
{"code", 1}, {"data", {"loginUrl", login_url}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::TranslateVoice(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("TranslateVoice params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().TranslateVoice(msg_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::GetTranslateVoiceText(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
return ret.dump();
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
std::string content =
|
||||
wechat::WeChatService::GetInstance().GetTranslateVoiceText(msg_id);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}};
|
||||
return ret_data.dump();
|
||||
}
|
||||
std::string MiscController::OpenUrlByWeChat(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("OpenUrlByWeChat params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring url = jsonutils::GetWStringParam(jp, "url");
|
||||
int flag = jsonutils::GetIntParam(jp, "flag");
|
||||
int64_t success =
|
||||
wechat::WeChatService::GetInstance().OpenUrlByWeChatBrowser(url, flag);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::ConfirmReceipt(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("ConfirmReceipt params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid");
|
||||
std::wstring transcationid = jsonutils::GetWStringParam(jp, "transcationId");
|
||||
std::wstring transferid = jsonutils::GetWStringParam(jp, "transferId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().DoConfirmReceipt(
|
||||
wxid, transcationid, transferid);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
std::string MiscController::DownloadAttach(std::string params) {
|
||||
nlohmann::json ret = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "Not Implemented"}};
|
||||
SPDLOG_INFO("DownloadAttach params:{}", params);
|
||||
nlohmann::json jp = nlohmann::json::parse(params);
|
||||
int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId");
|
||||
int64_t success = wechat::WeChatService::GetInstance().DoDownloadTask(msg_id);
|
||||
nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
return ret.dump();
|
||||
}
|
||||
} // namespace wxhelper
|
||||
|
||||
+349
-1
@@ -4,6 +4,9 @@
|
||||
namespace wechat {
|
||||
#define V_3_9_8_25 39825
|
||||
#define V_3_9_9_43 39943
|
||||
#define V_3_9_10_19 391019
|
||||
#define V_3_9_11_19 391119
|
||||
#define V_3_9_11_25 391125
|
||||
#ifndef WECHAT_VERSION
|
||||
#error " WECHAT_VERSION not defined ."
|
||||
#endif
|
||||
@@ -187,7 +190,7 @@ const uint64_t kHookLog = 0x1304e60;
|
||||
|
||||
const uint64_t kCreateChatRoom = 0xe63340;
|
||||
const uint64_t kQuitChatRoom = 0xe6e3b0;
|
||||
const uint64_t kForwardMsg = 0x1091660;
|
||||
const uint64_t kForwardMsg = 0x11dd780;
|
||||
|
||||
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
|
||||
const uint64_t kSNSGetFirstPage = 0x1a51dd0;
|
||||
@@ -241,6 +244,351 @@ const uint64_t kFreeWebViewPageConfig = 0x951520;
|
||||
const uint64_t kGetWebViewMgr = 0x9412d0;
|
||||
const uint64_t kShowWebView = 0x1d236b0;
|
||||
const uint64_t kSetUrl = 0x13dd410;
|
||||
#elif WECHAT_VERSION == V_3_9_10_19
|
||||
const uint64_t kGetAccountServiceMgr = 0x1c1fe70;
|
||||
const uint64_t kSyncMsg = 0xc39680;
|
||||
const uint64_t kSyncMsgNext = 0xc39680;
|
||||
const uint64_t kGetCurrentDataPath = 0x2315ea0;
|
||||
const uint64_t kGetAppDataSavePath = 0x26a7df0;
|
||||
const uint64_t kGetSendMessageMgr = 0x1c1e670;
|
||||
const uint64_t kSendTextMsg = 0x238ec70;
|
||||
const uint64_t kFreeChatMsg = 0x1c1fef0;
|
||||
|
||||
const uint64_t kDoAddMsg = 0x23d6f50;
|
||||
const uint64_t kSendImageMsg = 0x2384400;
|
||||
const uint64_t kChatMsgInstanceCounter = 0x1c287e0;
|
||||
const uint64_t kSendFileMsg = 0x2197a40;
|
||||
const uint64_t kGetAppMsgMgr = 0x1c23610;
|
||||
const uint64_t kGetContactMgr = 0x1c0bdc0;
|
||||
const uint64_t kGetContactList = 0x22665a0;
|
||||
|
||||
const uint64_t k_sqlite3_exec = 0x3afba50;
|
||||
const uint64_t k_sqlite3_prepare = 0x3b036d0;
|
||||
const uint64_t k_sqlite3_open = 0x3b3aec0;
|
||||
const uint64_t k_sqlite3_step = 0x3abfa50;
|
||||
const uint64_t k_sqlite3_column_count = 0x3ac0270;
|
||||
const uint64_t k_sqlite3_column_name = 0x3ac0c70;
|
||||
const uint64_t k_sqlite3_column_type = 0x3ac0ac0;
|
||||
const uint64_t k_sqlite3_column_blob = 0x3ac02a0;
|
||||
const uint64_t k_sqlite3_column_bytes = 0x3ac0390;
|
||||
const uint64_t k_sqlite3_finalize = 0x3abeb00;
|
||||
|
||||
const uint64_t kGPInstance = 0x5a415a0;
|
||||
const uint64_t kMultiDBMgr = 0x5abc5c8;
|
||||
const uint64_t kPublicMsgMgr = 0x5ab9b68;
|
||||
const uint64_t kFavoriteStorageMgr = 0x5abd178;
|
||||
const uint64_t kHardLinkMgr = 0x5abc4e8;
|
||||
|
||||
const uint64_t kChatRoomMgr = 0x1c4e1e0;
|
||||
const uint64_t kGetChatRoomDetailInfo = 0x222cf00;
|
||||
const uint64_t kNewChatRoomInfo = 0x25d0250;
|
||||
const uint64_t kFreeChatRoomInfo = 0x25d0430;
|
||||
const uint64_t kDoAddMemberToChatRoom = 0x221c900;
|
||||
const uint64_t kDoModChatRoomMemberNickName = 0xe6db00;
|
||||
const uint64_t kDelMemberFromChatRoom = 0x221cf40;
|
||||
const uint64_t kGetMemberFromChatRoom = 0x222e750;
|
||||
const uint64_t kNewChatRoom = 0x25cd670;
|
||||
const uint64_t kFreeChatRoom = 0x25cd870;
|
||||
|
||||
const uint64_t kTopMsg = 0xa5e4f0;
|
||||
const uint64_t kRemoveTopMsg = 0xe787b0;
|
||||
const uint64_t kInviteMember = 0xe63650;
|
||||
const uint64_t kHookLog = 0x1304e60;
|
||||
|
||||
const uint64_t kCreateChatRoom = 0xe63340;
|
||||
const uint64_t kQuitChatRoom = 0xe6e3b0;
|
||||
const uint64_t kForwardMsg = 0x11dd780;
|
||||
|
||||
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
|
||||
const uint64_t kSNSGetFirstPage = 0x1a51dd0;
|
||||
const uint64_t kSNSGetNextPageScene = 0x1a77240;
|
||||
const uint64_t kSNSDataMgr = 0xeebda0;
|
||||
const uint64_t kSNSTimeLineMgr = 0x19e83a0;
|
||||
const uint64_t kGetMgrByPrefixLocalId = 0x105a010;
|
||||
const uint64_t kAddFavFromMsg = 0x1601520;
|
||||
const uint64_t kGetChatMgr = 0xaafd90;
|
||||
const uint64_t kGetFavoriteMgr = 0x8c69b0;
|
||||
const uint64_t kAddFavFromImage = 0x160b920;
|
||||
const uint64_t kGetContact = 0xf67060;
|
||||
const uint64_t kNewContact = 0x12e01f0;
|
||||
const uint64_t kFreeContact = 0x12e08a0;
|
||||
const uint64_t kNewMMReaderItem = 0x8c79a0;
|
||||
const uint64_t kFreeMMReaderItem = 0x8c6da0;
|
||||
const uint64_t kForwordPublicMsg = 0xddc6c0;
|
||||
const uint64_t kParseAppMsgXml = 0x11b0a70;
|
||||
const uint64_t kNewAppMsgInfo = 0x91a550;
|
||||
const uint64_t kFreeAppMsgInfo = 0x8fd1a0;
|
||||
const uint64_t kGetPreDownLoadMgr = 0x9996f0;
|
||||
const uint64_t kPushAttachTask = 0x9c0080;
|
||||
const uint64_t kGetCustomSmileyMgr = 0x915c00;
|
||||
const uint64_t kSendCustomEmotion = 0xec0a40;
|
||||
const uint64_t kNewJsApiShareAppMessage = 0x13be1a0;
|
||||
const uint64_t kInitJsConfig = 0x137bc00;
|
||||
const uint64_t kSendApplet = 0x13c0920;
|
||||
const uint64_t kSendAppletSecond = 0x13c1150;
|
||||
const uint64_t kGetAppInfoByWaid = 0x13c5790;
|
||||
const uint64_t kCopyShareAppMessageRequest = 0x13c0670;
|
||||
const uint64_t kNewWAUpdatableMsgInfo = 0x919ca0;
|
||||
const uint64_t kFreeWAUpdatableMsgInfo = 0x8fc230;
|
||||
const uint64_t kSendPatMsg = 0x195f340;
|
||||
const uint64_t kGetOCRManager = 0x999780;
|
||||
const uint64_t kDoOCRTask = 0x190b2a0;
|
||||
|
||||
const uint64_t kGetLockWechatMgr = 0xbadb10;
|
||||
const uint64_t kRequestLockWechat = 0xb63770;
|
||||
const uint64_t kRequestUnLockWechat = 0xb63a10;
|
||||
|
||||
const uint64_t kOnLoginBtnClick = 0xf4d0f0;
|
||||
|
||||
const uint64_t kGetQRCodeLoginMgr = 0xf3fa20;
|
||||
|
||||
const uint64_t kUpdateMsg = 0xf15c40;
|
||||
const uint64_t kGetVoiceMgr = 0xbf78f0;
|
||||
const uint64_t kChatMsg2NetSceneSendMsg = 0x96e8d0;
|
||||
const uint64_t kTranslateVoice = 0x11217e0;
|
||||
const uint64_t kNewWebViewPageConfig = 0x9512f0;
|
||||
const uint64_t kFreeWebViewPageConfig = 0x951520;
|
||||
const uint64_t kGetWebViewMgr = 0x9412d0;
|
||||
const uint64_t kShowWebView = 0x1d236b0;
|
||||
const uint64_t kSetUrl = 0x13dd410;
|
||||
#elif WECHAT_VERSION == V_3_9_11_19
|
||||
const uint64_t kGetAccountServiceMgr = 0x1b50d00;
|
||||
const uint64_t kSyncMsg = 0xc39680;
|
||||
const uint64_t kSyncMsgNext = 0xc39680;
|
||||
const uint64_t kGetCurrentDataPath = 0x2248ce0;
|
||||
const uint64_t kGetAppDataSavePath = 0x25dc0e0;
|
||||
const uint64_t kGetSendMessageMgr = 0x1b4f500;
|
||||
const uint64_t kSendTextMsg = 0x22c2010;
|
||||
const uint64_t kFreeChatMsg = 0x1b50d80;
|
||||
|
||||
const uint64_t kDoAddMsg = 0x230a3e0;
|
||||
const uint64_t kSendImageMsg = 0x22b77a0;
|
||||
const uint64_t kChatMsgInstanceCounter = 0x1b59670;
|
||||
const uint64_t kSendFileMsg = 0x20cb6f0;
|
||||
const uint64_t kGetAppMsgMgr = 0x1b544a0;
|
||||
const uint64_t kGetContactMgr = 0x1b3ccd0;
|
||||
const uint64_t kGetContactList = 0x219a1c0;
|
||||
|
||||
const uint64_t k_sqlite3_exec = 0x3a59b30;
|
||||
const uint64_t k_sqlite3_prepare = 0x3a617b0;
|
||||
const uint64_t k_sqlite3_open = 0x3a98fa0;
|
||||
const uint64_t k_sqlite3_step = 0x3a1db30;
|
||||
const uint64_t k_sqlite3_column_count = 0x3a1e350;
|
||||
const uint64_t k_sqlite3_column_name = 0x3a1ed50;
|
||||
const uint64_t k_sqlite3_column_type = 0x3a1eba0;
|
||||
const uint64_t k_sqlite3_column_blob = 0x3a1e380;
|
||||
const uint64_t k_sqlite3_column_bytes = 0x3a1e470;
|
||||
const uint64_t k_sqlite3_finalize = 0x3a1cbe0;
|
||||
|
||||
const uint64_t kGPInstance = 0x58dd300;
|
||||
const uint64_t kMultiDBMgr = 0x593abf8;
|
||||
const uint64_t kPublicMsgMgr = 0x5938198;
|
||||
const uint64_t kFavoriteStorageMgr = 0x593b790;
|
||||
const uint64_t kHardLinkMgr = 0x593ab28;
|
||||
|
||||
const uint64_t kChatRoomMgr = 0x1b7f100;
|
||||
const uint64_t kGetChatRoomDetailInfo = 0x2160bb0;
|
||||
const uint64_t kNewChatRoomInfo = 0x2505120;
|
||||
const uint64_t kFreeChatRoomInfo = 0x2505300;
|
||||
const uint64_t kDoAddMemberToChatRoom = 0x21505b0;
|
||||
const uint64_t kDoModChatRoomMemberNickName = 0x215a360;
|
||||
const uint64_t kDelMemberFromChatRoom = 0x2150bf0;
|
||||
const uint64_t kGetMemberFromChatRoom = 0x2162400;
|
||||
const uint64_t kNewChatRoom = 0x2502540;
|
||||
const uint64_t kFreeChatRoom = 0x2502740;
|
||||
|
||||
const uint64_t kTopMsg = 0x1d7d160;
|
||||
const uint64_t kRemoveTopMsg = 0x2166090;
|
||||
const uint64_t kInviteMember = 0x214ff90;
|
||||
const uint64_t kHookLog = 0x1304e60;
|
||||
|
||||
const uint64_t kCreateChatRoom = 0x214fc60;
|
||||
const uint64_t kQuitChatRoom = 0x215ac00;
|
||||
const uint64_t kForwardMsg = 0x22c1590;
|
||||
|
||||
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
|
||||
const uint64_t kSNSGetFirstPage = 0x2e1bec0;
|
||||
const uint64_t kSNSGetNextPageScene = 0x2e41a70;
|
||||
const uint64_t kSNSDataMgr = 0x21dd6b0;
|
||||
const uint64_t kSNSTimeLineMgr = 0x2dadf20;
|
||||
const uint64_t kGetMgrByPrefixLocalId = 0x213afb0;
|
||||
const uint64_t kAddFavFromMsg = 0x2930e40;
|
||||
const uint64_t kGetChatMgr = 0x1b82bf0;
|
||||
const uint64_t kGetFavoriteMgr = 0x1b57ba0;
|
||||
const uint64_t kAddFavFromImage = 0x293d0f0;
|
||||
const uint64_t kGetContact = 0x21945d0;
|
||||
const uint64_t kNewContact = 0x2519300;
|
||||
const uint64_t kFreeContact = 0x25199b0;
|
||||
const uint64_t kNewMMReaderItem = 0x8c79a0;
|
||||
const uint64_t kFreeMMReaderItem = 0x8c6da0;
|
||||
const uint64_t kForwordPublicMsg = 0xddc6c0;
|
||||
const uint64_t kParseAppMsgXml = 0x11b0a70;
|
||||
const uint64_t kNewAppMsgInfo = 0x91a550;
|
||||
const uint64_t kFreeAppMsgInfo = 0x8fd1a0;
|
||||
const uint64_t kGetPreDownLoadMgr = 0x1c0a3a0;
|
||||
const uint64_t kPushAttachTask = 0x1cda920;
|
||||
const uint64_t kGetCustomSmileyMgr = 0x1ca0320;
|
||||
const uint64_t kSendCustomEmotion = 0x21b04c0;
|
||||
const uint64_t kNewJsApiShareAppMessage = 0x26cda20;
|
||||
const uint64_t kInitJsConfig = 0x137bc00;
|
||||
const uint64_t kSendApplet = 0x13c0920;
|
||||
const uint64_t kSendAppletSecond = 0x13c1150;
|
||||
const uint64_t kGetAppInfoByWaid = 0x13c5790;
|
||||
const uint64_t kCopyShareAppMessageRequest = 0x13c0670;
|
||||
const uint64_t kNewWAUpdatableMsgInfo = 0x919ca0;
|
||||
const uint64_t kFreeWAUpdatableMsgInfo = 0x8fc230;
|
||||
const uint64_t kSendPatMsg = 0x2ca9790;
|
||||
const uint64_t kGetOCRManager = 0x999780;
|
||||
const uint64_t kDoOCRTask = 0x2c53910;
|
||||
|
||||
const uint64_t kGetLockWechatMgr = 0x1c85010;
|
||||
const uint64_t kRequestLockWechat = 0x1c397d0;
|
||||
const uint64_t kRequestUnLockWechat = 0x1c39a70;
|
||||
|
||||
const uint64_t kOnLoginBtnClick = 0x202bc30;
|
||||
|
||||
const uint64_t kGetQRCodeLoginMgr = 0x201e350;
|
||||
|
||||
const uint64_t kUpdateMsg = 0x21421a0;
|
||||
const uint64_t kGetVoiceMgr = 0x1e13320;
|
||||
const uint64_t kChatMsg2NetSceneSendMsg = 0x1b70fd0;
|
||||
const uint64_t kTranslateVoice = 0x2353d50;
|
||||
const uint64_t kNewWebViewPageConfig = 0x1b53ae0;
|
||||
const uint64_t kFreeWebViewPageConfig = 0x1b53d10;
|
||||
const uint64_t kGetWebViewMgr = 0x1b43950;
|
||||
const uint64_t kShowWebView = 0x302ed30;
|
||||
const uint64_t kSetUrl = 0x13dd410;
|
||||
|
||||
const uint64_t kNewPayInfo = 0x1bcd930;
|
||||
const uint64_t kFreePayInfo = 0x1b92450;
|
||||
const uint64_t kTransferConfirm = 0x2f8c750;
|
||||
const uint64_t kTransferRefuse = 0x2f8d340;
|
||||
|
||||
const uint64_t kAddFriend = 0x1f3a350;
|
||||
const uint64_t kVerifyApply = 0x1f3a940;
|
||||
const uint64_t kDoDelContact = 0x2310120;
|
||||
|
||||
const uint64_t kGetSearchContactMgr = 0x1f9a730;
|
||||
const uint64_t kStartSearch = 0x22a4200;
|
||||
#elif WECHAT_VERSION == V_3_9_11_25
|
||||
const uint64_t kGetAccountServiceMgr = 0x1b50d00;
|
||||
const uint64_t kSyncMsg = 0xc39680;
|
||||
const uint64_t kSyncMsgNext = 0xc39680;
|
||||
const uint64_t kGetCurrentDataPath = 0x2248ce0;
|
||||
const uint64_t kGetAppDataSavePath = 0x25dc0e0;
|
||||
const uint64_t kGetSendMessageMgr = 0x1b4f500;
|
||||
const uint64_t kSendTextMsg = 0x22c2010;
|
||||
const uint64_t kFreeChatMsg = 0x1b50d80;
|
||||
|
||||
const uint64_t kDoAddMsg = 0x230a3e0;
|
||||
const uint64_t kSendImageMsg = 0x22b77a0;
|
||||
const uint64_t kChatMsgInstanceCounter = 0x1b59670;
|
||||
const uint64_t kSendFileMsg = 0x20cb6f0;
|
||||
const uint64_t kGetAppMsgMgr = 0x1b544a0;
|
||||
const uint64_t kGetContactMgr = 0x1b3ccd0;
|
||||
const uint64_t kGetContactList = 0x219a1c0;
|
||||
|
||||
const uint64_t k_sqlite3_exec = 0x3a59b30;
|
||||
const uint64_t k_sqlite3_prepare = 0x3a617b0;
|
||||
const uint64_t k_sqlite3_open = 0x3a98fa0;
|
||||
const uint64_t k_sqlite3_step = 0x3a1db30;
|
||||
const uint64_t k_sqlite3_column_count = 0x3a1e350;
|
||||
const uint64_t k_sqlite3_column_name = 0x3a1ed50;
|
||||
const uint64_t k_sqlite3_column_type = 0x3a1eba0;
|
||||
const uint64_t k_sqlite3_column_blob = 0x3a1e380;
|
||||
const uint64_t k_sqlite3_column_bytes = 0x3a1e470;
|
||||
const uint64_t k_sqlite3_finalize = 0x3a1cbe0;
|
||||
|
||||
const uint64_t kGPInstance = 0x58dd300;
|
||||
const uint64_t kMultiDBMgr = 0x593abf8;
|
||||
const uint64_t kPublicMsgMgr = 0x5938198;
|
||||
const uint64_t kFavoriteStorageMgr = 0x593b790;
|
||||
const uint64_t kHardLinkMgr = 0x593ab28;
|
||||
|
||||
const uint64_t kChatRoomMgr = 0x1b7f100;
|
||||
const uint64_t kGetChatRoomDetailInfo = 0x2160bb0;
|
||||
const uint64_t kNewChatRoomInfo = 0x2505120;
|
||||
const uint64_t kFreeChatRoomInfo = 0x2505300;
|
||||
const uint64_t kDoAddMemberToChatRoom = 0x21505b0;
|
||||
const uint64_t kDoModChatRoomMemberNickName = 0x215a360;
|
||||
const uint64_t kDelMemberFromChatRoom = 0x2150bf0;
|
||||
const uint64_t kGetMemberFromChatRoom = 0x2162400;
|
||||
const uint64_t kNewChatRoom = 0x2502540;
|
||||
const uint64_t kFreeChatRoom = 0x2502740;
|
||||
|
||||
const uint64_t kTopMsg = 0x1d7d160;
|
||||
const uint64_t kRemoveTopMsg = 0x2166090;
|
||||
const uint64_t kInviteMember = 0x214ff90;
|
||||
const uint64_t kHookLog = 0x1304e60;
|
||||
|
||||
const uint64_t kCreateChatRoom = 0x214fc60;
|
||||
const uint64_t kQuitChatRoom = 0x215ac00;
|
||||
const uint64_t kForwardMsg = 0x22c1590;
|
||||
|
||||
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
|
||||
const uint64_t kSNSGetFirstPage = 0x2e1bec0;
|
||||
const uint64_t kSNSGetNextPageScene = 0x2e41a70;
|
||||
const uint64_t kSNSDataMgr = 0x21dd6b0;
|
||||
const uint64_t kSNSTimeLineMgr = 0x2dadf20;
|
||||
const uint64_t kGetMgrByPrefixLocalId = 0x213afb0;
|
||||
const uint64_t kAddFavFromMsg = 0x2930e40;
|
||||
const uint64_t kGetChatMgr = 0x1b82bf0;
|
||||
const uint64_t kGetFavoriteMgr = 0x1b57ba0;
|
||||
const uint64_t kAddFavFromImage = 0x293d0f0;
|
||||
const uint64_t kGetContact = 0x21945d0;
|
||||
const uint64_t kNewContact = 0x2519300;
|
||||
const uint64_t kFreeContact = 0x25199b0;
|
||||
const uint64_t kNewMMReaderItem = 0x8c79a0;
|
||||
const uint64_t kFreeMMReaderItem = 0x8c6da0;
|
||||
const uint64_t kForwordPublicMsg = 0xddc6c0;
|
||||
const uint64_t kParseAppMsgXml = 0x11b0a70;
|
||||
const uint64_t kNewAppMsgInfo = 0x91a550;
|
||||
const uint64_t kFreeAppMsgInfo = 0x8fd1a0;
|
||||
const uint64_t kGetPreDownLoadMgr = 0x1c0a3a0;
|
||||
const uint64_t kPushAttachTask = 0x1cda920;
|
||||
const uint64_t kGetCustomSmileyMgr = 0x1ca0320;
|
||||
const uint64_t kSendCustomEmotion = 0x21b04c0;
|
||||
const uint64_t kNewJsApiShareAppMessage = 0x26cda20;
|
||||
const uint64_t kInitJsConfig = 0x137bc00;
|
||||
const uint64_t kSendApplet = 0x13c0920;
|
||||
const uint64_t kSendAppletSecond = 0x13c1150;
|
||||
const uint64_t kGetAppInfoByWaid = 0x13c5790;
|
||||
const uint64_t kCopyShareAppMessageRequest = 0x13c0670;
|
||||
const uint64_t kNewWAUpdatableMsgInfo = 0x919ca0;
|
||||
const uint64_t kFreeWAUpdatableMsgInfo = 0x8fc230;
|
||||
const uint64_t kSendPatMsg = 0x2ca9790;
|
||||
const uint64_t kGetOCRManager = 0x999780;
|
||||
const uint64_t kDoOCRTask = 0x2c53910;
|
||||
|
||||
const uint64_t kGetLockWechatMgr = 0x1c85010;
|
||||
const uint64_t kRequestLockWechat = 0x1c397d0;
|
||||
const uint64_t kRequestUnLockWechat = 0x1c39a70;
|
||||
|
||||
const uint64_t kOnLoginBtnClick = 0x202bc30;
|
||||
|
||||
const uint64_t kGetQRCodeLoginMgr = 0x201e350;
|
||||
|
||||
const uint64_t kUpdateMsg = 0x21421a0;
|
||||
const uint64_t kGetVoiceMgr = 0x1e13320;
|
||||
const uint64_t kChatMsg2NetSceneSendMsg = 0x1b70fd0;
|
||||
const uint64_t kTranslateVoice = 0x2353d50;
|
||||
const uint64_t kNewWebViewPageConfig = 0x1b53ae0;
|
||||
const uint64_t kFreeWebViewPageConfig = 0x1b53d10;
|
||||
const uint64_t kGetWebViewMgr = 0x1b43950;
|
||||
const uint64_t kShowWebView = 0x302ed30;
|
||||
const uint64_t kSetUrl = 0x13dd410;
|
||||
|
||||
const uint64_t kNewPayInfo = 0x1bcd930;
|
||||
const uint64_t kFreePayInfo = 0x1b92450;
|
||||
const uint64_t kTransferConfirm = 0x2f8c750;
|
||||
const uint64_t kTransferRefuse = 0x2f8d340;
|
||||
|
||||
const uint64_t kAddFriend = 0x1f3a350;
|
||||
const uint64_t kVerifyApply = 0x1f3a940;
|
||||
const uint64_t kDoDelContact = 0x2310120;
|
||||
|
||||
const uint64_t kGetSearchContactMgr = 0x1f9a730;
|
||||
const uint64_t kStartSearch = 0x22a4200;
|
||||
#else
|
||||
#ifdef WECHAT_VERSION
|
||||
#error "Unsupported WeChat version."
|
||||
|
||||
@@ -128,6 +128,31 @@ struct ContactProfileInner {
|
||||
: wxid(""), account(""), v3(""), nickname(""), head_image("") {}
|
||||
};
|
||||
|
||||
struct SearchContactInner {
|
||||
std::string big_image;
|
||||
std::string small_image;
|
||||
std::string city;
|
||||
std::string nation;
|
||||
std::string province;
|
||||
std::string signature;
|
||||
std::string v2;
|
||||
std::string v3;
|
||||
std::string nickname;
|
||||
int32_t sex;
|
||||
SearchContactInner()
|
||||
: big_image(""),
|
||||
small_image(""),
|
||||
city(""),
|
||||
nation(""),
|
||||
province(""),
|
||||
signature(""),
|
||||
sex(-1),
|
||||
v2(""),
|
||||
v3(""),
|
||||
nickname("") {}
|
||||
};
|
||||
|
||||
|
||||
namespace function {
|
||||
//hook
|
||||
typedef uint64_t(*__DoAddMsg)(uint64_t, uint64_t, uint64_t);
|
||||
@@ -224,6 +249,15 @@ typedef uint64_t (*__NewWebViewPageConfig)(uint64_t);
|
||||
typedef uint64_t (*__FreeWebViewPageConfig)(uint64_t);
|
||||
typedef uint64_t (*__GetWebViewMgr)();
|
||||
typedef uint64_t (*__SetUrl)(uint64_t,uint64_t,uint64_t);
|
||||
typedef uint64_t (*__NewWCPayInfo)(uint64_t);
|
||||
typedef uint64_t (*__FreeWCPayInfo)(uint64_t);
|
||||
typedef uint64_t (*__PayTransferConfirm)(uint64_t,uint64_t);
|
||||
typedef uint64_t (*__PayTransferRefuse)(uint64_t,uint64_t);
|
||||
typedef uint64_t (*__AddFriend)(uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
|
||||
typedef uint64_t (*__Verify)(uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t,uint64_t);
|
||||
typedef uint64_t (*__DelContact)(uint64_t);
|
||||
typedef uint64_t (*__GetSearchContactMgr)();
|
||||
typedef uint64_t (*__StartSearch)(uint64_t,uint64_t);
|
||||
|
||||
} // namespace function
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
#ifndef WXHELPER_WECHAT_SERVICE_H_
|
||||
#define WXHELPER_WECHAT_SERVICE_H_
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "singleton.h"
|
||||
#include "wechat_interface.h"
|
||||
namespace wechat {
|
||||
|
||||
class WeChatService : public base::Singleton<WeChatService> {
|
||||
friend class base::Singleton<WeChatService>;
|
||||
~WeChatService();
|
||||
|
||||
public:
|
||||
void Init();
|
||||
void SetBaseAddr(uint64_t addr);
|
||||
void SetJsApiAddr(uint64_t addr);
|
||||
int64_t CheckLogin();
|
||||
int64_t GetSelfInfo(SelfInfoInner& out);
|
||||
int64_t SendTextMsg(const std::wstring& wxid, const std::wstring& msg);
|
||||
int64_t SendImageMsg(const std::wstring& wxid,
|
||||
const std::wstring& image_path);
|
||||
int64_t SendFileMsg(const std::wstring& wxid, const std::wstring& file_path);
|
||||
int64_t GetContacts(std::vector<ContactInner>& vec);
|
||||
int64_t GetChatRoomDetailInfo(const std::wstring& room_id,
|
||||
ChatRoomInfoInner& room_info);
|
||||
int64_t AddMemberToChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& members);
|
||||
|
||||
int64_t ModChatRoomMemberNickName(const std::wstring& room_id,
|
||||
const std::wstring& wxid,
|
||||
const std::wstring& nickname);
|
||||
int64_t DelMemberFromChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& members);
|
||||
int64_t GetMemberFromChatRoom(const std::wstring& room_id,
|
||||
ChatRoomMemberInner& member);
|
||||
int64_t SetTopMsg(uint64_t msg_id);
|
||||
int64_t RemoveTopMsg(const std::wstring& room_id, uint64_t msg_id);
|
||||
int64_t InviteMemberToChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& wxids);
|
||||
int64_t CreateChatRoom(const std::vector<std::wstring>& wxids);
|
||||
int64_t QuitChatRoom(const std::wstring& room_id);
|
||||
int64_t ForwardMsg(uint64_t msg_id, const std::wstring& wxid);
|
||||
int64_t GetSNSFirstPage();
|
||||
int64_t GetSNSNextPage(uint64_t sns_id);
|
||||
int64_t AddFavFromMsg(uint64_t msg_id);
|
||||
int64_t AddFavFromImage(const std::wstring& wxid,
|
||||
const std::wstring& image_path);
|
||||
int64_t SendAtText(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& wxids,
|
||||
const std::wstring& msg);
|
||||
std::wstring GetContactOrChatRoomNickname(const std::wstring& wxid);
|
||||
int64_t GetContactByWxid(const std::wstring& wxid,
|
||||
ContactProfileInner& profile);
|
||||
int64_t DoDownloadTask(uint64_t msg_id);
|
||||
int64_t ForwardPublicMsg(const std::wstring& wxid, const std::wstring& title,
|
||||
const std::wstring& url,
|
||||
const std::wstring& thumb_url,
|
||||
const std::wstring& sender_id,
|
||||
const std::wstring& sender_name,
|
||||
const std::wstring& digest);
|
||||
int64_t ForwardPublicMsgByMsgId(const std::wstring& wxid, uint64_t msg_id);
|
||||
|
||||
int64_t DecodeImage(const std::wstring& file_path,
|
||||
const std::wstring& save_dir);
|
||||
int64_t GetVoiceByDB(ULONG64 msg_id, const std::wstring& dir);
|
||||
int64_t SendCustomEmotion(const std::wstring& file_path,
|
||||
const std::wstring& wxid);
|
||||
int64_t SendApplet(const std::wstring& recv_wxid,
|
||||
const std::wstring& waid_suff, const std::wstring& waid_w,
|
||||
const std::wstring& waid_s, const std::wstring& wa_wxid,
|
||||
const std::wstring& json_param,
|
||||
const std::wstring& head_image,
|
||||
const std::wstring& big_image,
|
||||
const std::wstring& index_page);
|
||||
int64_t SendPatMsg(const std::wstring& room_id, const std::wstring& wxid);
|
||||
int64_t DoOCRTask(const std::wstring& img_path, std::string& result);
|
||||
int64_t LockWeChat();
|
||||
int64_t UnlockWeChat();
|
||||
int64_t EnterWeChat();
|
||||
int64_t SendMultiAtText(
|
||||
const std::wstring& room_id,
|
||||
const std::vector<std::pair<std::wstring, std::wstring>>& at);
|
||||
std::string GetLoginUrl();
|
||||
|
||||
int64_t TranslateVoice(uint64_t msg_id);
|
||||
std::string GetTranslateVoiceText(uint64_t msg_id);
|
||||
int64_t OpenUrlByWeChatBrowser(const std::wstring& url, int flag);
|
||||
std::wstring GetChatRoomMemberNickname(const std::wstring& room_id,
|
||||
const std::wstring& member_id);
|
||||
int64_t DelContact(const std::wstring& wxid);
|
||||
|
||||
int64_t SearchContact(const std::wstring& keyword,
|
||||
wechat::SearchContactInner& contact);
|
||||
|
||||
int64_t AddFriendByWxid(const std::wstring& wxid, const std::wstring& msg);
|
||||
|
||||
int64_t VerifyApply(const std::wstring& v3, const std::wstring& v4,
|
||||
int32_t permission);
|
||||
int64_t DoConfirmReceipt(const std::wstring& wxid,
|
||||
const std::wstring& transcationid,
|
||||
const std::wstring& transferid);
|
||||
|
||||
int64_t DoRefuseReceipt(const std::wstring& wxid,
|
||||
const std::wstring& transcationid,
|
||||
const std::wstring& transferid);
|
||||
|
||||
private:
|
||||
uint64_t base_addr_;
|
||||
uint64_t js_api_addr_;
|
||||
};
|
||||
|
||||
} // namespace wechat
|
||||
|
||||
#endif
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "wxutils.h"
|
||||
#include "wechat_db.h"
|
||||
#include "sync_msg_hook.h"
|
||||
#include "wechat_service.h"
|
||||
namespace wxhelper {
|
||||
|
||||
void WxHelper::init(HMODULE module) {
|
||||
@@ -16,6 +17,7 @@ void WxHelper::init(HMODULE module) {
|
||||
base::utils::HideModule(module);
|
||||
}
|
||||
wechat::WeChatDb::GetInstance().Init();
|
||||
wechat::WeChatService::GetInstance().Init();
|
||||
SyncMsgHook::GetInstance().Init();
|
||||
http::HttpServer::GetInstance().init(
|
||||
Config::GetInstance().GetHttpServerHost(),
|
||||
|
||||
@@ -105,6 +105,20 @@ int DecodeImage(const wchar_t *file_path, const wchar_t *save_dir) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool FindOrCreateDirectory(const std::wstring &path) {
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE found = ::FindFirstFileW(path.c_str(), &fd);
|
||||
if (found != INVALID_HANDLE_VALUE &&
|
||||
(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
FindClose(found);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!::CreateDirectoryW(path.c_str(), NULL)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wxutils
|
||||
} // namespace wxhelper
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
#include <string>
|
||||
namespace wxhelper {
|
||||
namespace wxutils {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
int64_t GetWeChatWinBase();
|
||||
#else
|
||||
@@ -18,6 +23,7 @@ std::string ImageXor(std::string buf);
|
||||
std::wstring ReadWstring(INT64 addr);
|
||||
std::string ReadWstringThenConvert(INT64 addr);
|
||||
int DecodeImage(const wchar_t* file_path, const wchar_t* save_dir);
|
||||
bool FindOrCreateDirectory(const std::wstring &path);
|
||||
} // namespace wxutils
|
||||
|
||||
} // namespace wxhelper
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,301 @@
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import docking.widgets.filter.TextFilterFactory;
|
||||
import edu.uci.ics.jung.graph.Graph;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.db.FidFile;
|
||||
import ghidra.feature.fid.db.FidFileManager;
|
||||
import ghidra.graph.GDirectedGraph;
|
||||
import ghidra.graph.GEdge;
|
||||
import ghidra.graph.jung.JungDirectedGraph;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.block.CodeBlockIterator;
|
||||
import ghidra.program.model.block.CodeBlockModel;
|
||||
import ghidra.program.model.block.CodeBlockReference;
|
||||
import ghidra.program.model.block.CodeBlockReferenceIterator;
|
||||
import ghidra.program.model.block.graph.CodeBlockVertex;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.FlowType;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class FindCallScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
ContainsTextFilterFactory factory = new ContainsTextFilterFactory(false, true);
|
||||
|
||||
find_send_msg(factory);
|
||||
findFunction(factory,"SendMessageMgr::sendMsg");
|
||||
findFunction(factory,"AppMsgMgr::sendFile");
|
||||
findFunction(factory,"SendMessageMgr::sendImageMsg");
|
||||
findFunction(factory,"SyncMgr::doAddMsg");
|
||||
findFunction(factory,"ChatRoomMgr::doModChatRoomMemberNickName");
|
||||
|
||||
findFunction2(factory,"New_ChatMsg");
|
||||
findFunction2(factory,"Free_ChatMsg");
|
||||
findFunction2(factory,"New_ChatRoomInfo");
|
||||
findFunction2(factory,"Free_ChatRoomInfo");
|
||||
findFunction2(factory,"New_ChatRoom");
|
||||
findFunction2(factory,"Free_ChatRoom");
|
||||
findFunction2(factory,"New_Contact");
|
||||
findFunction2(factory,"Free_Contact");
|
||||
findFunction2(factory,"New_WAUpdatableMsgInfo");
|
||||
findFunction2(factory,"Free_WAUpdatableMsgInfo");
|
||||
findFunction2(factory,"New_AppMsgInfo");
|
||||
findFunction2(factory,"Free_AppMsgInfo");
|
||||
findFunction2(factory,"New_MMReaderItem");
|
||||
findFunction2(factory,"Free_MMReaderItem");
|
||||
findFunction2(factory,"New_WCPayInfo");
|
||||
findFunction2(factory,"Free_WCPayInfo");
|
||||
findFunction2(factory,"New_WebViewPageConfig");
|
||||
findFunction2(factory,"Free_WebViewPageConfig");
|
||||
|
||||
findMgr(factory, "SendMessageMgr::SendMessageMgr", "GetSendMessageMgr");
|
||||
findMgr(factory, "AccountServiceMgr::AccountServiceMgr", "GetAccountServiceMgr");
|
||||
findMgr(factory, "AppMsgMgr::AppMsgMgr", "GetAppMsgMgr");
|
||||
findMgr(factory, "ContactMgr::ContactMgr", "GetContactMgr");
|
||||
findMgr(factory, "ChatRoomMgr::ChatRoomMgr", "GetChatRoomMgr");
|
||||
findMgr(factory, "SNSDataMgr::SNSDataMgr", "GetSNSDataMgr");
|
||||
findMgr(factory, "SNSTimeLineMgr::SNSTimeLineMgr", "GetSNSTimeLineMgr");
|
||||
findMgr(factory, "ChatMgr::ChatMgr", "GetChatMgr");
|
||||
findMgr(factory, "FavoriteMgr::FavoriteMgr", "GetFavoriteMgr");
|
||||
findMgr(factory, "PreDownLoadMgr::PreDownLoadMgr", "GetPreDownLoadMgr");
|
||||
findMgr(factory, "CustomSmileyMgr::CustomSmileyMgr", "GetCustomSmileyMgr");
|
||||
findMgr(factory, "LockWechatMgr::LockWechatMgr", "GetLockWechatMgr");
|
||||
findMgr(factory, "QRCodeLoginMgr::QRCodeLoginMgr", "GetQRCodeLoginMgr");
|
||||
findMgr(factory, "VoiceMgr::VoiceMgr", "GetVoiceMgr");
|
||||
findMgr(factory, "WebViewMgr::WebViewMgr", "GetWebViewMgr");
|
||||
findMgr(factory, "SearchContactMgr::SearchContactMgr", "GetSearchContactMgr");
|
||||
findMgr(factory, "PublicMsgMgr::PublicMsgMgr", "GetPublicMsgMgr");
|
||||
findMgr(factory, "MultiDBMsgMgr::MultiDBMsgMgr", "GetMultiDBMsgMgr");
|
||||
findMgr(factory, "FavoriteStorageMgr::FavoriteStorageMgr", "GetFavoriteStorageMgr");
|
||||
findMgr(factory, "HardLinkMgr::HardLinkMgr", "GetHardLinkMgr");
|
||||
|
||||
}
|
||||
|
||||
private boolean checkFidFile() {
|
||||
FidFileManager fidFileManager = FidFileManager.getInstance();
|
||||
List<FidFile> userFid = fidFileManager.getFidFiles();
|
||||
if (userFid.isEmpty()) {
|
||||
printerr("please import 3.9.11.25.fid fid file.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void find_send_msg(ContainsTextFilterFactory factory) {
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "SendMessageMgr::sendMsg", factory,
|
||||
"SendMessageMgr::sendMsg");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t kSendTextMsg = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void findFunction(ContainsTextFilterFactory factory, String functionName) {
|
||||
assertNotNull(factory);
|
||||
assertNotNull(functionName);
|
||||
String name = "";
|
||||
String[] split = functionName.split("::");
|
||||
if (split.length > 1) {
|
||||
name = split[1];
|
||||
char upperCase = Character.toUpperCase(split[1].charAt(0));
|
||||
name = upperCase + split[1].substring(1);
|
||||
} else {
|
||||
char upperCase = Character.toUpperCase(functionName.charAt(0));
|
||||
name = upperCase + functionName.substring(1);
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, functionName, factory, functionName);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t k" + name + " = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void findFunction2(ContainsTextFilterFactory factory, String functionName) {
|
||||
assertNotNull(factory);
|
||||
assertNotNull(functionName);
|
||||
String name = "";
|
||||
String split = functionName.replace("_", "");
|
||||
char upperCase = Character.toUpperCase(split.charAt(0));
|
||||
name = upperCase + split.substring(1);
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, functionName, factory, functionName);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t k" + name + " = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void find_Mgr(ContainsTextFilterFactory factory) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, "SendMessageMgr::SendMessageMgr", factory,
|
||||
"SendMessageMgr::SendMessageMgr");
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference next = referencesTo.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("fromAddress " + fromAddress.toString());
|
||||
Function functionAt = functionManager.getFunctionContaining(fromAddress);
|
||||
if (null != functionAt) {
|
||||
addresses.add(functionAt.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "GetSendMessageMgr", factory, "GetSendMessageMgr");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
if (addresses.contains(address)) {
|
||||
println("const uint64_t kGetSendMessageMgr = " + address.toString() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void find_SendMessageMgr(ContainsTextFilterFactory factory) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, "SendMessageMgr::SendMessageMgr", factory,
|
||||
"SendMessageMgr::SendMessageMgr");
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
addresses.add(address);
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "GetSendMessageMgr", factory, "GetSendMessageMgr");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
Function function = functionManager.getFunctionAt(address);
|
||||
if (null != function) {
|
||||
AddressSetView functionBody = function.getBody();
|
||||
Address entryPoint = function.getEntryPoint();
|
||||
Set<Reference> references = getReferencesFrom(currentProgram, functionBody, monitor);
|
||||
for (Reference reference : references) {
|
||||
monitor.checkCancelled();
|
||||
Address toAddress = reference.getToAddress();
|
||||
if (toAddress.equals(entryPoint)) {
|
||||
continue;
|
||||
}
|
||||
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
||||
if (null != calledFunction) {
|
||||
if (addresses.contains(toAddress)) {
|
||||
println("const uint64_t kGetSendMessageMgr = " + address.toString() + ";");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void findMgr(ContainsTextFilterFactory factory, String mgr, String getMgr) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, mgr, factory, mgr);
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
addresses.add(address);
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, getMgr, factory, getMgr);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
Function function = functionManager.getFunctionAt(address);
|
||||
if (null != function) {
|
||||
AddressSetView functionBody = function.getBody();
|
||||
Address entryPoint = function.getEntryPoint();
|
||||
Set<Reference> references = getReferencesFrom(currentProgram, functionBody, monitor);
|
||||
for (Reference reference : references) {
|
||||
monitor.checkCancelled();
|
||||
Address toAddress = reference.getToAddress();
|
||||
if (toAddress.equals(entryPoint)) {
|
||||
continue;
|
||||
}
|
||||
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
||||
if (null != calledFunction) {
|
||||
if (addresses.contains(toAddress)) {
|
||||
println("const uint64_t k" + getMgr + " = " + address.toString() + " ;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Set<Reference> getReferencesFrom(Program program, AddressSetView addresses, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
Set<Reference> set = new HashSet<>();
|
||||
ReferenceManager referenceManager = program.getReferenceManager();
|
||||
AddressIterator addressIterator = addresses.getAddresses(true);
|
||||
while (addressIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Address address = addressIterator.next();
|
||||
Reference[] referencesFrom = referenceManager.getReferencesFrom(address);
|
||||
if (referencesFrom != null) {
|
||||
for (Reference reference : referencesFrom) {
|
||||
set.add(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol(SymbolTable symbolTable, String text, TextFilterFactory factory, String filterText) {
|
||||
List<Symbol> list = new ArrayList<>();
|
||||
TextFilter textFilter = factory.getTextFilter(filterText);
|
||||
SymbolIterator symbols = symbolTable.getSymbols(text);
|
||||
while (symbols.hasNext()) {
|
||||
Symbol next = symbols.next();
|
||||
if (textFilter.matches(next.getName())) {
|
||||
list.add(next);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
// find mars
|
||||
//@author ttttupup
|
||||
//@category _NEW_
|
||||
//@keybinding
|
||||
//@menupath
|
||||
//@toolbar
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeBlockBasic;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.sleigh.grammar.SleighParser.stringorident_return;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class FindMarsScript extends GhidraScript {
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
BasicBlockModel basicBlockModel;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
basicBlockModel = new BasicBlockModel(currentProgram);
|
||||
Address findXScopeTracer = findXScopeTracer();
|
||||
// Address findXScopeTracer = currentProgram.getAddressFactory().getAddress("0x183d04d10");
|
||||
if (null != findXScopeTracer) {
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXScopeTracer);
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(fromAddress);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + fromAddress.toString());
|
||||
continue;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
continue;
|
||||
}
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
|
||||
while (pcodeOps.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOpAST opAST = pcodeOps.next();
|
||||
int opcode = opAST.getOpcode();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = opAST.getInput(0);
|
||||
boolean contains = input0.contains(findXScopeTracer);
|
||||
|
||||
if (contains) {
|
||||
Varnode input3 = opAST.getInput(3);
|
||||
Varnode input4 = opAST.getInput(4);
|
||||
if (input4 == null || input3 == null) {
|
||||
continue;
|
||||
}
|
||||
String namespaceString = "";
|
||||
String funcNameString = "";
|
||||
if (input3.isUnique()) {
|
||||
namespaceString = getUniqueValue(input3);
|
||||
} else if (input3.isConstant()) {
|
||||
namespaceString = getConstact(input3);
|
||||
}
|
||||
if (input4.isUnique()) {
|
||||
funcNameString = getUniqueValue(input4);
|
||||
} else if (input4.isConstant()) {
|
||||
funcNameString = getConstact(input4);
|
||||
}
|
||||
if (StringUtilities.isAllBlank(namespaceString)
|
||||
|| StringUtilities.isAllBlank(funcNameString)) {
|
||||
continue;
|
||||
}
|
||||
String name = namespaceString.replace(" ", "") + "::" + funcNameString.replace(" ", "");
|
||||
println("find function :" + name);
|
||||
functionContaining.setName(name, SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionContaining.getEntryPoint(),
|
||||
CodeUnit.EOL_COMMENT, "mars scipt auto define: " + name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getConstact(Varnode input3) {
|
||||
Address address2 = input3.getAddress();
|
||||
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(address2.getOffset());
|
||||
Data dataAt2 = getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void easy(Address findXScopeTracer) throws CancelledException {
|
||||
if (null != findXScopeTracer) {
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXScopeTracer);
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
Instruction instructionAt = currentProgram.getListing().getInstructionAt(fromAddress);
|
||||
if (null != instructionAt) {
|
||||
PcodeOp[] pcode = instructionAt.getPcode();
|
||||
if (null != pcode) {
|
||||
for (PcodeOp pcodeOp : pcode) {
|
||||
if (pcodeOp.getOpcode() == PcodeOp.CALL) {
|
||||
Varnode namespace = pcodeOp.getInput(3);
|
||||
Varnode funcName = pcodeOp.getInput(4);
|
||||
if (null != namespace) {
|
||||
if (namespace.isConstant()) {
|
||||
long offset = namespace.getAddress().getOffset();
|
||||
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(offset);
|
||||
Data dataAt = currentProgram.getListing().getDataAt(address);
|
||||
if (null != dataAt) {
|
||||
if (dataAt.hasStringValue()) {
|
||||
dataAt.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null != funcName) {
|
||||
if (funcName.isConstant()) {
|
||||
long offset = funcName.getAddress().getOffset();
|
||||
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(offset);
|
||||
Data dataAt = currentProgram.getListing().getDataAt(address);
|
||||
if (null != dataAt) {
|
||||
if (dataAt.hasStringValue()) {
|
||||
dataAt.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println("caller address: " + fromAddress.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void find() throws Exception {
|
||||
Function findXLogger = findXLogger();
|
||||
if (null != findXLogger) {
|
||||
if (findXLogger.isThunk()) {
|
||||
currentProgram.getFunctionManager().createFunction("XLogger::operator()", findXLogger.getEntryPoint(),
|
||||
findXLogger.getBody(), findXLogger.getSignatureSource());
|
||||
} else {
|
||||
|
||||
findXLogger.setName("XLogger::operator()", SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(findXLogger.getEntryPoint(), CodeUnit.EOL_COMMENT,
|
||||
"rename function: XLogger::operator()");
|
||||
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXLogger.getEntryPoint());
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("caller address: " + fromAddress.toString());
|
||||
handle(fromAddress, findXLogger.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Address findXScopeTracer() throws Exception {
|
||||
List<FoundString> list = findStrings(null, 5, 1, true, false);
|
||||
ContainsTextFilterFactory factory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = factory.getTextFilter("mars::comm::DNS::GetHostByName");
|
||||
for (FoundString foundString : list) {
|
||||
monitor.checkCancelled();
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println("=====text addr :" + address.toString());
|
||||
|
||||
ReferenceIterator referencesTo = currentProgram.getReferenceManager().getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference ref = referencesTo.next();
|
||||
Address textAddress = ref.getFromAddress();
|
||||
Function func = currentProgram.getFunctionManager().getFunctionContaining(textAddress);
|
||||
if (null == func) {
|
||||
continue;
|
||||
}
|
||||
CodeBlock[] codeBlocksContaining = basicBlockModel.getCodeBlocksContaining(textAddress, monitor);
|
||||
for (CodeBlock codeBlock : codeBlocksContaining) {
|
||||
AddressIterator addressIterator = codeBlock.getAddresses(true);
|
||||
while (addressIterator.hasNext()) {
|
||||
Address next = addressIterator.next();
|
||||
CodeUnit codeUnitAt = currentProgram.getListing().getCodeUnitAt(next);
|
||||
if (null != codeUnitAt) {
|
||||
if (codeUnitAt.getMnemonicString().equals("CALL")) {
|
||||
Instruction instructionAt = currentProgram.getListing().getInstructionAt(next);
|
||||
PcodeOp[] pcode = instructionAt.getPcode();
|
||||
PcodeOp pcodeOp = pcode[pcode.length - 1];
|
||||
Varnode input = pcodeOp.getInput(0);
|
||||
Address address2 = input.getAddress();
|
||||
println("===== XScopeTracer::XScopeTracer addr :" + address2.toString());
|
||||
Function functionAt = currentProgram.getFunctionManager().getFunctionAt(address2);
|
||||
if (null != functionAt) {
|
||||
functionAt.setName("XScopeTracer::XScopeTracer", SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionAt.getEntryPoint(),
|
||||
CodeUnit.EOL_COMMENT, "scipt auto define: XScopeTracer::XScopeTracer");
|
||||
} else {
|
||||
createFunction(address2, "XScopeTracer::XScopeTracer");
|
||||
currentProgram.getListing().setComment(address2, CodeUnit.EOL_COMMENT,
|
||||
"scipt auto create: XScopeTracer::XScopeTracer");
|
||||
}
|
||||
|
||||
return address2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private void handle(Address address, Address calleeAddress) throws CancelledException {
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(address);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + address.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
ArrayList<PcodeBlockBasic> basicBlocks = highFunction.getBasicBlocks();
|
||||
|
||||
for (PcodeBlockBasic pcodeBlockBasic : basicBlocks) {
|
||||
monitor.checkCancelled();
|
||||
boolean contains = pcodeBlockBasic.contains(address);
|
||||
if (contains) {
|
||||
Iterator<PcodeOp> iterator = pcodeBlockBasic.getIterator();
|
||||
for (; iterator.hasNext();) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOp next = iterator.next();
|
||||
if (next.getOpcode() == PcodeOp.CALL) {
|
||||
if (next.getNumInputs() > 4) {
|
||||
Varnode input3 = next.getInput(3);
|
||||
if (null != input3) {
|
||||
if (input3.isUnique()) {
|
||||
String uniqueValue = getUniqueValue(input3);
|
||||
if (null != uniqueValue) {
|
||||
println(uniqueValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getUniqueValue(Varnode input3) {
|
||||
PcodeOp def = input3.getDef();
|
||||
Varnode[] inputs = def.getInputs();
|
||||
if (null != inputs && inputs.length > 0) {
|
||||
if (inputs[0].isConstant()) {
|
||||
Address address2 = inputs[0].getAddress();
|
||||
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(address2.getOffset());
|
||||
Data dataAt2 = currentProgram.getListing().getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Function findXLogger() throws MemoryAccessException, CancelledException {
|
||||
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory factory = currentProgram.getAddressFactory();
|
||||
AddressSpace[] addressSpaces = factory.getAddressSpaces();
|
||||
AddressSetView initializedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
|
||||
|
||||
AddressSet searchSet = initializedMemory.intersect(new AddressSet(initializedMemory));
|
||||
List<FoundString> findStrings = new ArrayList<>();
|
||||
println("初次查询速度较慢,请耐心等待。");
|
||||
for (AddressSpace space : addressSpaces) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
AddressSet intersecting = searchSet.intersectRange(space.getMinAddress(), space.getMaxAddress());
|
||||
findStrings.addAll(findStrings(null, 10, 1, true, true));
|
||||
}
|
||||
|
||||
if (null != findStrings && findStrings.size() > 0) {
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = containsTextFilterFactory
|
||||
.getTextFilter("XLogger& XLogger::operator()(const char* _format, ...)");
|
||||
for (FoundString foundString : findStrings) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println(address.toString());
|
||||
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Reference ref = referencesTo.next();
|
||||
Address xLoggerAddr = ref.getFromAddress();
|
||||
Function targetFunction = functionManager.getFunctionContaining(xLoggerAddr);
|
||||
if (null == targetFunction) {
|
||||
continue;
|
||||
}
|
||||
println("XLogger::operator() :" + targetFunction.getEntryPoint().toString());
|
||||
return targetFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.hash.FidHashQuad;
|
||||
import ghidra.feature.fid.service.FidService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.util.UndefinedFunction;
|
||||
|
||||
public class FindSqliteCloseScript extends GhidraScript {
|
||||
FidService service;
|
||||
DecompInterface decompiler;
|
||||
|
||||
long sql3close_full_hash = -1574752015815545339L;
|
||||
long sql3close_spec_hash = -1262376715505923342L;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
service = new FidService();
|
||||
|
||||
decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
|
||||
List<FoundString> findStrings = findStrings(null, 5, 1, true, false);
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
find_sqlite3Close(findStrings,containsTextFilterFactory);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void find_sqlite3Close(List<FoundString> list, ContainsTextFilterFactory factory) throws MemoryAccessException {
|
||||
int size = currentProgram.getLanguage().getLanguageDescription().getSize() / 8;
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
TextFilter textFilter = factory.getTextFilter("unable to close due to unfinalized statements or unfinished backups");
|
||||
for (FoundString foundString : list) {
|
||||
if(monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if(textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println("=====text addr :"+address.toString() );
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference ref = referencesTo.next();
|
||||
Address sql3CloseAddr = ref.getFromAddress();
|
||||
Function sql3CloseFunction = functionManager.getFunctionContaining(sql3CloseAddr);
|
||||
if(null ==sql3CloseFunction ) {
|
||||
continue;
|
||||
}
|
||||
FidHashQuad hashQuad = service.hashFunction(sql3CloseFunction);
|
||||
if(hashQuad.getFullHash() == sql3close_full_hash && hashQuad.getSpecificHash() == sql3close_spec_hash) {
|
||||
println("found sql3Close :" + sql3CloseFunction.getName() + " at " + sql3CloseFunction.getEntryPoint() +
|
||||
" full hash " + hashQuad.getFullHash() + " specific hash " + hashQuad.getSpecificHash());
|
||||
Address entryPoint = sql3CloseFunction.getEntryPoint();
|
||||
ReferenceIterator referencesTo2 = referenceManager.getReferencesTo(entryPoint);
|
||||
while (referencesTo2.hasNext()) {
|
||||
Reference next = referencesTo2.next();
|
||||
Address addr = next.getFromAddress();
|
||||
Function sql_close_func = functionManager.getFunctionContaining(addr);
|
||||
if(null !=sql_close_func ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CodeUnit codeUnitAt = currentProgram.getListing().getCodeUnitAt(addr);
|
||||
if(null != codeUnitAt) {
|
||||
String mnemonicString = codeUnitAt.getMnemonicString();
|
||||
if("JMP".equals(mnemonicString)) {
|
||||
CodeUnit codeUnitBefore = currentProgram.getListing().getCodeUnitBefore(addr);
|
||||
String mnemonicString2 = codeUnitBefore.getMnemonicString();
|
||||
Function function = UndefinedFunction.findFunction(currentProgram, addr, monitor);
|
||||
if (null != function) {
|
||||
Address entryPoint2 = function.getEntryPoint();
|
||||
if("XOR".equals(mnemonicString2)) {
|
||||
createFunction(entryPoint2, "sqlite3_close");
|
||||
currentProgram.getListing().setComment(entryPoint2, CodeUnit.POST_COMMENT,
|
||||
"auto define function: sqlite3_close");
|
||||
println("sqlite3_close addr: " + entryPoint2.toString());
|
||||
}else if ("MOV".equals(mnemonicString2)) {
|
||||
createFunction(entryPoint2, "sqlite3_close_v2");
|
||||
currentProgram.getListing().setComment(entryPoint2, CodeUnit.POST_COMMENT,
|
||||
"auto define function : sqlite3_close_v2" );
|
||||
println("sqlite3_close_v2 addr: " + entryPoint2.toString());
|
||||
}
|
||||
ReferenceIterator referencesTo3 = referenceManager.getReferencesTo(entryPoint2);
|
||||
while (referencesTo3.hasNext()) {
|
||||
Reference next2 = referencesTo3.next();
|
||||
Address fromAddress = next2.getFromAddress();
|
||||
if("XOR".equals(mnemonicString2)) {
|
||||
long l = fromAddress.getOffset() - 16*size;
|
||||
println("sqlite3_close xref:" + fromAddress.toString());
|
||||
printf("sqlite3_api_routines addr: %x \n", l);
|
||||
}else if ("MOV".equals(mnemonicString2)) {
|
||||
long l = fromAddress.getOffset()- 179*size;
|
||||
println("sqlite3_close_v2 xref:" +fromAddress.toString());
|
||||
printf("sqlite3_api_routines addr: %x \n", l);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
|
||||
import edu.uci.ics.jung.graph.Graph;
|
||||
import generic.stl.Pair;
|
||||
import ghidra.graph.GDirectedGraph;
|
||||
import ghidra.graph.GEdge;
|
||||
import ghidra.graph.jung.JungDirectedGraph;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.block.CodeBlockIterator;
|
||||
import ghidra.program.model.block.CodeBlockModel;
|
||||
import ghidra.program.model.block.CodeBlockReference;
|
||||
import ghidra.program.model.block.CodeBlockReferenceIterator;
|
||||
import ghidra.program.model.block.graph.CodeBlockVertex;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.FlowType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class GraphFunctionFactory {
|
||||
|
||||
public static Pair<GDirectedGraph<FunctionVertex, FunctionEdge>, BidiMap<CodeBlock, FunctionVertex>> createGraph(
|
||||
Function f, TaskMonitor monitor) throws CancelledException {
|
||||
if (monitor == null) {
|
||||
monitor = TaskMonitor.DUMMY;
|
||||
}
|
||||
|
||||
JungDirectedGraph<FunctionVertex, FunctionEdge> graph = new JungDirectedGraph<>();
|
||||
|
||||
BidiMap<CodeBlock, FunctionVertex> vertices = createVertices(f, monitor);
|
||||
for (FunctionVertex v : vertices.values()) {
|
||||
graph.addVertex(v);
|
||||
}
|
||||
|
||||
Collection<FunctionEdge> edges = createdEdges(vertices, monitor);
|
||||
for (FunctionEdge e : edges) {
|
||||
graph.addEdge(e);
|
||||
}
|
||||
|
||||
// this must be done after the edges are added to the graph
|
||||
for (FunctionVertex vertex : vertices.values()) {
|
||||
vertex.setType(getVertexType(graph, vertex));
|
||||
}
|
||||
return new Pair<GDirectedGraph<FunctionVertex, FunctionEdge>, BidiMap<CodeBlock, FunctionVertex>>(graph,
|
||||
vertices);
|
||||
}
|
||||
|
||||
private static BidiMap<CodeBlock, FunctionVertex> createVertices(Function f, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
||||
BidiMap<CodeBlock, FunctionVertex> vertices = new DualHashBidiMap<>();
|
||||
Program p = f.getProgram();
|
||||
CodeBlockModel blockModel = new BasicBlockModel(p);
|
||||
|
||||
AddressSetView addresses = f.getBody();
|
||||
CodeBlockIterator iterator = blockModel.getCodeBlocksContaining(addresses, monitor);
|
||||
monitor.initialize(addresses.getNumAddresses());
|
||||
|
||||
for (; iterator.hasNext();) {
|
||||
CodeBlock codeBlock = iterator.next();
|
||||
|
||||
FlowType flowType = codeBlock.getFlowType();
|
||||
boolean isEntry = isEntry(codeBlock);
|
||||
|
||||
FunctionVertex vertex = new FunctionVertex(codeBlock, flowType, isEntry);
|
||||
|
||||
vertices.put(codeBlock, vertex);
|
||||
|
||||
long blockAddressCount = codeBlock.getNumAddresses();
|
||||
long currentProgress = monitor.getProgress();
|
||||
monitor.setProgress(currentProgress + blockAddressCount);
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
private static Collection<FunctionEdge> createdEdges(BidiMap<CodeBlock, FunctionVertex> vertices,
|
||||
TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
List<FunctionEdge> edges = new ArrayList<>();
|
||||
for (FunctionVertex startVertex : vertices.values()) {
|
||||
Collection<FunctionEdge> vertexEdges = getEdgesForStartVertex(vertices, startVertex, monitor);
|
||||
|
||||
edges.addAll(vertexEdges);
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
private static Collection<FunctionEdge> getEdgesForStartVertex(BidiMap<CodeBlock, FunctionVertex> blockToVertexMap,
|
||||
FunctionVertex startVertex, TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
List<FunctionEdge> edges = new ArrayList<>();
|
||||
CodeBlock codeBlock = blockToVertexMap.getKey(startVertex);
|
||||
CodeBlockReferenceIterator destinations = codeBlock.getDestinations(monitor);
|
||||
for (; destinations.hasNext();) {
|
||||
CodeBlockReference reference = destinations.next();
|
||||
CodeBlock destinationBlock = reference.getDestinationBlock();
|
||||
FunctionVertex destinationVertex = blockToVertexMap.get(destinationBlock);
|
||||
if (destinationVertex == null) {
|
||||
continue;// no vertex means the code block is not in our function
|
||||
}
|
||||
|
||||
edges.add(new FunctionEdge(startVertex, destinationVertex, reference.getFlowType()));
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
private static VertexType getVertexType(Graph<FunctionVertex, FunctionEdge> graph, FunctionVertex v) {
|
||||
|
||||
boolean isEntry = v.isEntry();
|
||||
boolean isExit = false;
|
||||
|
||||
FlowType flowType = v.getFlowType();
|
||||
if (flowType.isTerminal()) {
|
||||
isExit = true;
|
||||
}
|
||||
|
||||
Collection<FunctionEdge> outs = graph.getOutEdges(v);
|
||||
if (outs == null || outs.isEmpty()) {
|
||||
isExit = true;
|
||||
}
|
||||
|
||||
VertexType type = VertexType.BODY;
|
||||
if (isEntry) {
|
||||
if (isExit) {
|
||||
type = VertexType.SINGLETON;
|
||||
} else {
|
||||
type = VertexType.ENTRY;
|
||||
}
|
||||
} else if (isExit) {
|
||||
type = VertexType.EXIT;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static boolean isEntry(CodeBlock codeBlock) {
|
||||
boolean isSource = true;
|
||||
try {
|
||||
CodeBlockReferenceIterator iter = codeBlock.getSources(TaskMonitor.DUMMY);
|
||||
while (iter.hasNext()) {
|
||||
isSource = false;
|
||||
if (iter.next().getFlowType().isCall()) {
|
||||
// any calls into a code block will make it an 'entry'
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (CancelledException e) {
|
||||
// will never happen, because I don't have a monitor
|
||||
}
|
||||
return isSource;
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionVertex extends CodeBlockVertex {
|
||||
|
||||
private VertexType type = VertexType.BODY;
|
||||
private FlowType flowType;
|
||||
private boolean isEntry;
|
||||
|
||||
public FunctionVertex(CodeBlock codeBlock, FlowType flowType, boolean isEntry) {
|
||||
super(codeBlock);
|
||||
this.flowType = flowType;
|
||||
this.isEntry = isEntry;
|
||||
}
|
||||
|
||||
public boolean isEntry() {
|
||||
return isEntry;
|
||||
}
|
||||
|
||||
public FlowType getFlowType() {
|
||||
return flowType;
|
||||
}
|
||||
|
||||
public VertexType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(VertexType type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionEdge implements GEdge<FunctionVertex> {
|
||||
|
||||
private FunctionVertex start;
|
||||
private FunctionVertex end;
|
||||
private FlowType flowType;
|
||||
|
||||
public FunctionEdge(FunctionVertex start, FunctionVertex end, FlowType flowType) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.flowType = flowType;
|
||||
}
|
||||
|
||||
public FlowType getFlowType() {
|
||||
return flowType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionVertex getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionVertex getEnd() {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
enum VertexType {
|
||||
|
||||
//@formatter:off
|
||||
BODY,
|
||||
ENTRY,
|
||||
EXIT,
|
||||
GROUP,
|
||||
SINGLETON;
|
||||
//@formatter:on
|
||||
|
||||
public boolean isEntry() {
|
||||
return this == ENTRY || this == SINGLETON;
|
||||
}
|
||||
|
||||
public boolean isExit() {
|
||||
return this == EXIT || this == SINGLETON;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.hash.FidHashQuad;
|
||||
import ghidra.feature.fid.service.FidService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class NamedScript extends GhidraScript {
|
||||
|
||||
long wxlog_full_hash = 0xf9f7e7c3081f5aa3L;
|
||||
long wxlog_spec_hash = 0x9e71b418c749e4faL;
|
||||
FidService service;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
service = new FidService();
|
||||
|
||||
Address selectAddress = askAddress("填写手动确认的wxlog地址", "wxlog地址或者任意值进行搜索:");
|
||||
Listing listing = currentProgram.getListing();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory addressFactory = currentProgram.getAddressFactory();
|
||||
|
||||
AddressSpace space = addressFactory.getDefaultAddressSpace();
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
|
||||
Address funcAddress = selectAddress;
|
||||
|
||||
Function logFunction = functionManager.getFunctionAt(funcAddress);
|
||||
|
||||
if (null == logFunction) {
|
||||
logFunction = findLogFunc();
|
||||
if (null == logFunction) {
|
||||
printerr("未能成功自动匹配wxlog函数,请手动查找后填写正确地址 ");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ReferenceIterator referenceIterator = referenceManager.getReferencesTo(logFunction.getEntryPoint());
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("lookup address: " + fromAddress.toString());
|
||||
handle(fromAddress, functionManager, decompiler, space, listing, selectAddress);
|
||||
println("caller address: " + fromAddress.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Function findLogFunc() throws MemoryAccessException, CancelledException {
|
||||
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory factory = currentProgram.getAddressFactory();
|
||||
AddressSpace[] addressSpaces = factory.getAddressSpaces();
|
||||
AddressSetView initializedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
|
||||
|
||||
AddressSet searchSet = initializedMemory.intersect(new AddressSet(initializedMemory));
|
||||
List<FoundString> findStrings = new ArrayList<>();
|
||||
println("初次查询速度较慢,请耐心等待。");
|
||||
for (AddressSpace space : addressSpaces) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
AddressSet intersecting = searchSet.intersectRange(space.getMinAddress(), space.getMaxAddress());
|
||||
findStrings.addAll(findStrings(null, 10, 1, true, true));
|
||||
}
|
||||
|
||||
|
||||
if (null != findStrings && findStrings.size() > 0) {
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = containsTextFilterFactory.getTextFilter("(%d-%d-%d:%d:%02d:%02d:%03d %05d)-%s/%s:");
|
||||
for (FoundString foundString : findStrings) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Reference ref = referencesTo.next();
|
||||
Address wxlogAddr = ref.getFromAddress();
|
||||
Function targetFunction = functionManager.getFunctionContaining(wxlogAddr);
|
||||
if (null == targetFunction) {
|
||||
continue;
|
||||
}
|
||||
FidHashQuad hashQuad = service.hashFunction(targetFunction);
|
||||
if (hashQuad.getFullHash() == wxlog_full_hash
|
||||
&& hashQuad.getSpecificHash() == wxlog_spec_hash) {
|
||||
return targetFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handle(Address address, FunctionManager functionManager, DecompInterface decompiler,
|
||||
AddressSpace space, Listing listing, Address selectAddress) {
|
||||
Function functionContaining = functionManager.getFunctionContaining(address);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + address.toString());
|
||||
return;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("Symbol " + res.getErrorMessage());
|
||||
return;
|
||||
}
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
|
||||
while (pcodeOps.hasNext()) {
|
||||
PcodeOpAST next = pcodeOps.next();
|
||||
int opcode = next.getOpcode();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = next.getInput(0);
|
||||
boolean contains = input0.contains(selectAddress);
|
||||
|
||||
if (contains) {
|
||||
Varnode input4 = next.getInput(4);
|
||||
if (input4 == null) {
|
||||
continue;
|
||||
}
|
||||
PcodeOp def4 = input4.getDef();
|
||||
if (null != def4) {
|
||||
Address param4Address = null;
|
||||
|
||||
if (def4.getOpcode() == PcodeOp.COPY) {
|
||||
Varnode vn0 = def4.getInput(0);
|
||||
param4Address = space.getAddress(vn0.getAddress().getOffset());
|
||||
|
||||
Data dataAt = listing.getDataAt(param4Address);
|
||||
if (dataAt.hasStringValue()) {
|
||||
Object value = dataAt.getValue();
|
||||
String funcStr = value.toString();
|
||||
println("func:" + funcStr);
|
||||
try {
|
||||
functionContaining.setName(funcStr, SourceType.USER_DEFINED);
|
||||
listing.setComment(functionContaining.getEntryPoint(), CodeUnit.EOL_COMMENT,
|
||||
"auto define:" + funcStr);
|
||||
} catch (DuplicateNameException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InvalidInputException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// 根据一些日志类的相关函数的引用来获取当前函数的函数名
|
||||
// 输入被调用函数的地址和可以作为函数名称的参数的位置
|
||||
//
|
||||
//@category Functions
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.util.StringUtilities;
|
||||
|
||||
public class RenameScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
Address askAddress = askAddress("输入函数地址", "引用的函数地址");
|
||||
int askInt = askInt("输入参数位置", "函数名称的参数位置");
|
||||
DecompInterface decompiler = getDecompInterface();
|
||||
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager().getReferencesTo(askAddress);
|
||||
for (Reference ref : referenceIterator) {
|
||||
monitor.checkCancelled();
|
||||
Address fromAddress = ref.getFromAddress();
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(fromAddress);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + fromAddress.toString());
|
||||
continue;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 30, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
continue;
|
||||
}
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
|
||||
|
||||
while (pcodeOps.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOpAST opAST = pcodeOps.next();
|
||||
int opcode = opAST.getOpcode();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = opAST.getInput(0);
|
||||
boolean contains = input0.contains(askAddress);
|
||||
if (!contains) {
|
||||
continue;
|
||||
}
|
||||
Varnode inputVarnode = opAST.getInput(askInt);
|
||||
String nameString = null;
|
||||
if (inputVarnode.isUnique()) {
|
||||
nameString = getUniqueValue(inputVarnode);
|
||||
|
||||
} else if (inputVarnode.isConstant()) {
|
||||
nameString = getConstact(inputVarnode);
|
||||
}
|
||||
|
||||
if (StringUtilities.isAllBlank(nameString)) {
|
||||
continue;
|
||||
}
|
||||
String name = nameString.replace(" ", "");
|
||||
println("find function :" + name);
|
||||
SourceType signatureSource = functionContaining.getSignatureSource();
|
||||
if (signatureSource.isLowerPriorityThan(SourceType.USER_DEFINED)) {
|
||||
functionContaining.setName(name, SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionContaining.getEntryPoint(), CodeUnit.POST_COMMENT,
|
||||
"script rename: " + name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DecompInterface getDecompInterface() {
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
return decompiler;
|
||||
}
|
||||
|
||||
private String getConstact(Varnode input3) {
|
||||
Address address2 = input3.getAddress();
|
||||
Address address3 = toAddr(address2.getOffset());
|
||||
Data dataAt2 = getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUniqueValue(Varnode input3) {
|
||||
PcodeOp def = input3.getDef();
|
||||
Varnode[] inputs = def.getInputs();
|
||||
if (null != inputs && inputs.length > 0) {
|
||||
if (inputs[0].isConstant()) {
|
||||
Address address2 = inputs[0].getAddress();
|
||||
Address address3 = toAddr(address2.getOffset());
|
||||
Data dataAt2 = currentProgram.getListing().getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
// sqlite function
|
||||
//@author
|
||||
//@category _NEW_
|
||||
//@keybinding
|
||||
//@menupath
|
||||
//@toolbar
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.address.*;
|
||||
|
||||
public class Sqllite3Script extends GhidraScript {
|
||||
|
||||
public void run() throws Exception {
|
||||
|
||||
run2();
|
||||
|
||||
}
|
||||
|
||||
private void run2() {
|
||||
Listing listing = currentProgram.getListing();
|
||||
AddressSpace defaultAddressSpace = currentProgram.getAddressFactory().getDefaultAddressSpace();
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
Language language = currentProgram.getLanguage();
|
||||
LanguageDescription languageDescription = language.getLanguageDescription();
|
||||
int size = languageDescription.getSize() / 8;
|
||||
|
||||
try {
|
||||
Address selectAddress = askAddress("选择地址", "选择一个sqlite3_api_routines结构体中的函数指针的地址");
|
||||
String xRefLabelName = getXRefLabelName(listing, functionManager, selectAddress);
|
||||
if (null != xRefLabelName) {
|
||||
Sqllite3Script.EnumSql byCode = EnumSql.getByCode(xRefLabelName);
|
||||
if (null != byCode) {
|
||||
Integer code = byCode.getCode();
|
||||
long offset = selectAddress.getOffset();
|
||||
long first = offset - code * size;
|
||||
for (EnumSql item : EnumSql.values()) {
|
||||
long addr = item.getCode() * size + first;
|
||||
setFuncName(listing, functionManager, defaultAddressSpace.getAddress(addr), symbolTable,
|
||||
item.getDesc());
|
||||
printf("sqlite3 function :{%s} \n", item.getDesc());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getXRefLabelName(Listing listing, FunctionManager functionManager, Address selectAddress) {
|
||||
String label = null;
|
||||
Data dataAt = listing.getDataAt(selectAddress);
|
||||
if (null == dataAt) {
|
||||
printerr("not found data from selectAddress");
|
||||
return label;
|
||||
}
|
||||
if (dataAt.isPointer()) {
|
||||
Reference[] referencesFrom = dataAt.getReferencesFrom();
|
||||
if (null == referencesFrom) {
|
||||
printerr("not found references");
|
||||
return label;
|
||||
}
|
||||
|
||||
for (Reference reference : referencesFrom) {
|
||||
Address toAddress = reference.getToAddress();
|
||||
Function functionAt = functionManager.getFunctionAt(toAddress);
|
||||
|
||||
if (null == functionAt) {
|
||||
CodeUnit codeUnitAt = listing.getCodeUnitAt(toAddress);
|
||||
if (null == codeUnitAt) {
|
||||
label = listing.getComment(CodeUnit.POST_COMMENT, toAddress);
|
||||
if (label == null) {
|
||||
label = listing.getComment(CodeUnit.PRE_COMMENT, toAddress);
|
||||
}
|
||||
if (label == null) {
|
||||
label = listing.getComment(CodeUnit.EOL_COMMENT, toAddress);
|
||||
}
|
||||
}
|
||||
label = codeUnitAt.getLabel();
|
||||
|
||||
} else {
|
||||
label = functionAt.getName();
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
return label;
|
||||
|
||||
}
|
||||
|
||||
private void setFuncName(Listing listing, FunctionManager functionManager, Address selectAddress,
|
||||
SymbolTable symbolTable, String name) throws DuplicateNameException, InvalidInputException {
|
||||
Data dataAt = listing.getDataAt(selectAddress);
|
||||
if (null == dataAt) {
|
||||
printerr("not found data from selectAddress");
|
||||
return;
|
||||
}
|
||||
if (dataAt.isPointer()) {
|
||||
Reference[] referencesFrom = dataAt.getReferencesFrom();
|
||||
if (null == referencesFrom) {
|
||||
printerr("not found references");
|
||||
return;
|
||||
}
|
||||
|
||||
for (Reference reference : referencesFrom) {
|
||||
Address toAddress = reference.getToAddress();
|
||||
Function functionAt = functionManager.getFunctionAt(toAddress);
|
||||
|
||||
if (null == functionAt) {
|
||||
CodeUnit codeUnitAt = listing.getCodeUnitAt(toAddress);
|
||||
if (null != codeUnitAt) {
|
||||
codeUnitAt.setComment(CodeUnit.POST_COMMENT, name);
|
||||
}
|
||||
symbolTable.createLabel(toAddress, name, SourceType.USER_DEFINED);
|
||||
} else {
|
||||
functionAt.setName(name, SourceType.USER_DEFINED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum EnumSql {
|
||||
|
||||
SQLITE3_AGGREGATE_CONTEXT(0, "sqlite3_aggregate_context"),
|
||||
SQLITE3_AGGREGATE_COUNT(1, "sqlite3_aggregate_count"), SQLITE3_BIND_BLOB(2, "sqlite3_bind_blob"),
|
||||
SQLITE3_BIND_DOUBLE(3, "sqlite3_bind_double"), SQLITE3_BIND_INT(4, "sqlite3_bind_int"),
|
||||
SQLITE3_BIND_INT64(5, "sqlite3_bind_int64"), SQLITE3_BIND_NULL(6, "sqlite3_bind_null"),
|
||||
SQLITE3_BIND_PARAMETER_COUNT(7, "sqlite3_bind_parameter_count"),
|
||||
SQLITE3_BIND_PARAMETER_INDEX(8, "sqlite3_bind_parameter_index"),
|
||||
SQLITE3_BIND_PARAMETER_NAME(9, "sqlite3_bind_parameter_name"), SQLITE3_BIND_TEXT(10, "sqlite3_bind_text"),
|
||||
SQLITE3_BIND_TEXT16(11, "sqlite3_bind_text16"), SQLITE3_BIND_VALUE(12, "sqlite3_bind_value"),
|
||||
SQLITE3_BUSY_HANDLER(13, "sqlite3_busy_handler"), SQLITE3_BUSY_TIMEOUT(14, "sqlite3_busy_timeout"),
|
||||
SQLITE3_CHANGES(15, "sqlite3_changes"), SQLITE3_CLOSE(16, "sqlite3_close"),
|
||||
SQLITE3_COLLATION_NEEDED(17, "sqlite3_collation_needed"),
|
||||
SQLITE3_COLLATION_NEEDED16(18, "sqlite3_collation_needed16"), SQLITE3_COLUMN_BLOB(19, "sqlite3_column_blob"),
|
||||
SQLITE3_COLUMN_BYTES(20, "sqlite3_column_bytes"), SQLITE3_COLUMN_BYTES16(21, "sqlite3_column_bytes16"),
|
||||
SQLITE3_COLUMN_COUNT(22, "sqlite3_column_count"),
|
||||
SQLITE3_COLUMN_DATABASE_NAME(23, "sqlite3_column_database_name"),
|
||||
SQLITE3_COLUMN_DATABASE_NAME16(24, "sqlite3_column_database_name16"),
|
||||
SQLITE3_COLUMN_DECLTYPE(25, "sqlite3_column_decltype"),
|
||||
SQLITE3_COLUMN_DECLTYPE16(26, "sqlite3_column_decltype16"), SQLITE3_COLUMN_DOUBLE(27, "sqlite3_column_double"),
|
||||
SQLITE3_COLUMN_INT(28, "sqlite3_column_int"), SQLITE3_COLUMN_INT64(29, "sqlite3_column_int64"),
|
||||
SQLITE3_COLUMN_NAME(30, "sqlite3_column_name"), SQLITE3_COLUMN_NAME16(31, "sqlite3_column_name16"),
|
||||
SQLITE3_COLUMN_ORIGIN_NAME(32, "sqlite3_column_origin_name"),
|
||||
SQLITE3_COLUMN_ORIGIN_NAME16(33, "sqlite3_column_origin_name16"),
|
||||
SQLITE3_COLUMN_TABLE_NAME(34, "sqlite3_column_table_name"),
|
||||
SQLITE3_COLUMN_TABLE_NAME16(35, "sqlite3_column_table_name16"), SQLITE3_COLUMN_TEXT(36, "sqlite3_column_text"),
|
||||
SQLITE3_COLUMN_TEXT16(37, "sqlite3_column_text16"), SQLITE3_COLUMN_TYPE(38, "sqlite3_column_type"),
|
||||
SQLITE3_COLUMN_VALUE(39, "sqlite3_column_value"), SQLITE3_COMMIT_HOOK(40, "sqlite3_commit_hook"),
|
||||
SQLITE3_COMPLETE(41, "sqlite3_complete"), SQLITE3_COMPLETE16(42, "sqlite3_complete16"),
|
||||
SQLITE3_CREATE_COLLATION(43, "sqlite3_create_collation"),
|
||||
SQLITE3_CREATE_COLLATION16(44, "sqlite3_create_collation16"),
|
||||
SQLITE3_CREATE_FUNCTION(45, "sqlite3_create_function"),
|
||||
SQLITE3_CREATE_FUNCTION16(46, "sqlite3_create_function16"), SQLITE3_CREATE_MODULE(47, "sqlite3_create_module"),
|
||||
SQLITE3_DATA_COUNT(48, "sqlite3_data_count"), SQLITE3_DB_HANDLE(49, "sqlite3_db_handle"),
|
||||
SQLITE3_DECLARE_VTAB(50, "sqlite3_declare_vtab"),
|
||||
SQLITE3_ENABLE_SHARED_CACHE(51, "sqlite3_enable_shared_cache"), SQLITE3_ERRCODE(52, "sqlite3_errcode"),
|
||||
SQLITE3_ERRMSG(53, "sqlite3_errmsg"), SQLITE3_ERRMSG16(54, "sqlite3_errmsg16"),
|
||||
SQLITE3_EXEC(55, "sqlite3_exec"), SQLITE3_EXPIRED(56, "sqlite3_expired"),
|
||||
SQLITE3_FINALIZE(57, "sqlite3_finalize"), SQLITE3_FREE(58, "sqlite3_free"),
|
||||
SQLITE3_FREE_TABLE(59, "sqlite3_free_table"), SQLITE3_GET_AUTOCOMMIT(60, "sqlite3_get_autocommit"),
|
||||
SQLITE3_GET_AUXDATA(61, "sqlite3_get_auxdata"), SQLITE3_GET_TABLE(62, "sqlite3_get_table"), NULL(63, "0"),
|
||||
SQLITE3_INTERRUPT(64, "sqlite3_interrupt"), SQLITE3_LAST_INSERT_ROWID(65, "sqlite3_last_insert_rowid"),
|
||||
SQLITE3_LIBVERSION(66, "sqlite3_libversion"), SQLITE3_LIBVERSION_NUMBER(67, "sqlite3_libversion_number"),
|
||||
SQLITE3_MALLOC(68, "sqlite3_malloc"), SQLITE3_MPRINTF(69, "sqlite3_mprintf"), SQLITE3_OPEN(70, "sqlite3_open"),
|
||||
SQLITE3_OPEN16(71, "sqlite3_open16"), SQLITE3_PREPARE(72, "sqlite3_prepare"),
|
||||
SQLITE3_PREPARE16(73, "sqlite3_prepare16"), SQLITE3_PROFILE(74, "sqlite3_profile"),
|
||||
SQLITE3_PROGRESS_HANDLER(75, "sqlite3_progress_handler"), SQLITE3_REALLOC(76, "sqlite3_realloc"),
|
||||
SQLITE3_RESET(77, "sqlite3_reset"), SQLITE3_RESULT_BLOB(78, "sqlite3_result_blob"),
|
||||
SQLITE3_RESULT_DOUBLE(79, "sqlite3_result_double"), SQLITE3_RESULT_ERROR(80, "sqlite3_result_error"),
|
||||
SQLITE3_RESULT_ERROR16(81, "sqlite3_result_error16"), SQLITE3_RESULT_INT(82, "sqlite3_result_int"),
|
||||
SQLITE3_RESULT_INT64(83, "sqlite3_result_int64"), SQLITE3_RESULT_NULL(84, "sqlite3_result_null"),
|
||||
SQLITE3_RESULT_TEXT(85, "sqlite3_result_text"), SQLITE3_RESULT_TEXT16(86, "sqlite3_result_text16"),
|
||||
SQLITE3_RESULT_TEXT16BE(87, "sqlite3_result_text16be"), SQLITE3_RESULT_TEXT16LE(88, "sqlite3_result_text16le"),
|
||||
SQLITE3_RESULT_VALUE(89, "sqlite3_result_value"), SQLITE3_ROLLBACK_HOOK(90, "sqlite3_rollback_hook"),
|
||||
SQLITE3_SET_AUTHORIZER(91, "sqlite3_set_authorizer"), SQLITE3_SET_AUXDATA(92, "sqlite3_set_auxdata"),
|
||||
SQLITE3_SNPRINTF(93, "sqlite3_snprintf"), SQLITE3_STEP(94, "sqlite3_step"),
|
||||
SQLITE3_TABLE_COLUMN_METADATA(95, "sqlite3_table_column_metadata"),
|
||||
SQLITE3_THREAD_CLEANUP(96, "sqlite3_thread_cleanup"), SQLITE3_TOTAL_CHANGES(97, "sqlite3_total_changes"),
|
||||
SQLITE3_TRACE(98, "sqlite3_trace"), SQLITE3_TRANSFER_BINDINGS(99, "sqlite3_transfer_bindings"),
|
||||
SQLITE3_UPDATE_HOOK(100, "sqlite3_update_hook"), SQLITE3_USER_DATA(101, "sqlite3_user_data"),
|
||||
SQLITE3_VALUE_BLOB(102, "sqlite3_value_blob"), SQLITE3_VALUE_BYTES(103, "sqlite3_value_bytes"),
|
||||
SQLITE3_VALUE_BYTES16(104, "sqlite3_value_bytes16"), SQLITE3_VALUE_DOUBLE(105, "sqlite3_value_double"),
|
||||
SQLITE3_VALUE_INT(106, "sqlite3_value_int"), SQLITE3_VALUE_INT64(107, "sqlite3_value_int64"),
|
||||
SQLITE3_VALUE_NUMERIC_TYPE(108, "sqlite3_value_numeric_type"), SQLITE3_VALUE_TEXT(109, "sqlite3_value_text"),
|
||||
SQLITE3_VALUE_TEXT16(110, "sqlite3_value_text16"), SQLITE3_VALUE_TEXT16BE(111, "sqlite3_value_text16be"),
|
||||
SQLITE3_VALUE_TEXT16LE(112, "sqlite3_value_text16le"), SQLITE3_VALUE_TYPE(113, "sqlite3_value_type"),
|
||||
SQLITE3_VMPRINTF(114, "sqlite3_vmprintf"), SQLITE3_OVERLOAD_FUNCTION(115, "sqlite3_overload_function"),
|
||||
SQLITE3_PREPARE_V2(116, "sqlite3_prepare_v2"), SQLITE3_PREPARE16_V2(117, "sqlite3_prepare16_v2"),
|
||||
SQLITE3_CLEAR_BINDINGS(118, "sqlite3_clear_bindings"),
|
||||
SQLITE3_CREATE_MODULE_V2(119, "sqlite3_create_module_v2"), SQLITE3_BIND_ZEROBLOB(120, "sqlite3_bind_zeroblob"),
|
||||
SQLITE3_BLOB_BYTES(121, "sqlite3_blob_bytes"), SQLITE3_BLOB_CLOSE(122, "sqlite3_blob_close"),
|
||||
SQLITE3_BLOB_OPEN(123, "sqlite3_blob_open"), SQLITE3_BLOB_READ(124, "sqlite3_blob_read"),
|
||||
SQLITE3_BLOB_WRITE(125, "sqlite3_blob_write"), SQLITE3_CREATE_COLLATION_V2(126, "sqlite3_create_collation_v2"),
|
||||
SQLITE3_FILE_CONTROL(127, "sqlite3_file_control"), SQLITE3_MEMORY_HIGHWATER(128, "sqlite3_memory_highwater"),
|
||||
SQLITE3_MEMORY_USED(129, "sqlite3_memory_used"), SQLITE3_MUTEX_ALLOC(130, "sqlite3_mutex_alloc"),
|
||||
SQLITE3_MUTEX_ENTER(131, "sqlite3_mutex_enter"), SQLITE3_MUTEX_FREE(132, "sqlite3_mutex_free"),
|
||||
SQLITE3_MUTEX_LEAVE(133, "sqlite3_mutex_leave"), SQLITE3_MUTEX_TRY(134, "sqlite3_mutex_try"),
|
||||
SQLITE3_OPEN_V2(135, "sqlite3_open_v2"), SQLITE3_RELEASE_MEMORY(136, "sqlite3_release_memory"),
|
||||
SQLITE3_RESULT_ERROR_NOMEM(137, "sqlite3_result_error_nomem"),
|
||||
SQLITE3_RESULT_ERROR_TOOBIG(138, "sqlite3_result_error_toobig"), SQLITE3_SLEEP(139, "sqlite3_sleep"),
|
||||
SQLITE3_SOFT_HEAP_LIMIT(140, "sqlite3_soft_heap_limit"), SQLITE3_VFS_FIND(141, "sqlite3_vfs_find"),
|
||||
SQLITE3_VFS_REGISTER(142, "sqlite3_vfs_register"), SQLITE3_VFS_UNREGISTER(143, "sqlite3_vfs_unregister"),
|
||||
SQLITE3_THREADSAFE(144, "sqlite3_threadsafe"), SQLITE3_RESULT_ZEROBLOB(145, "sqlite3_result_zeroblob"),
|
||||
SQLITE3_RESULT_ERROR_CODE(146, "sqlite3_result_error_code"), SQLITE3_TEST_CONTROL(147, "sqlite3_test_control"),
|
||||
SQLITE3_RANDOMNESS(148, "sqlite3_randomness"), SQLITE3_CONTEXT_DB_HANDLE(149, "sqlite3_context_db_handle"),
|
||||
SQLITE3_EXTENDED_RESULT_CODES(150, "sqlite3_extended_result_codes"), SQLITE3_LIMIT(151, "sqlite3_limit"),
|
||||
SQLITE3_NEXT_STMT(152, "sqlite3_next_stmt"), SQLITE3_SQL(153, "sqlite3_sql"),
|
||||
SQLITE3_STATUS(154, "sqlite3_status"), SQLITE3_BACKUP_FINISH(155, "sqlite3_backup_finish"),
|
||||
SQLITE3_BACKUP_INIT(156, "sqlite3_backup_init"), SQLITE3_BACKUP_PAGECOUNT(157, "sqlite3_backup_pagecount"),
|
||||
SQLITE3_BACKUP_REMAINING(158, "sqlite3_backup_remaining"), SQLITE3_BACKUP_STEP(159, "sqlite3_backup_step"),
|
||||
SQLITE3_COMPILEOPTION_GET(160, "sqlite3_compileoption_get"),
|
||||
SQLITE3_COMPILEOPTION_USED(161, "sqlite3_compileoption_used"),
|
||||
SQLITE3_CREATE_FUNCTION_V2(162, "sqlite3_create_function_v2"), SQLITE3_DB_CONFIG(163, "sqlite3_db_config"),
|
||||
SQLITE3_DB_MUTEX(164, "sqlite3_db_mutex"), SQLITE3_DB_STATUS(165, "sqlite3_db_status"),
|
||||
SQLITE3_EXTENDED_ERRCODE(166, "sqlite3_extended_errcode"), SQLITE3_LOG(167, "sqlite3_log"),
|
||||
SQLITE3_SOFT_HEAP_LIMIT64(168, "sqlite3_soft_heap_limit64"), SQLITE3_SOURCEID(169, "sqlite3_sourceid"),
|
||||
SQLITE3_STMT_STATUS(170, "sqlite3_stmt_status"), SQLITE3_STRNICMP(171, "sqlite3_strnicmp"),
|
||||
SQLITE3_UNLOCK_NOTIFY(172, "sqlite3_unlock_notify"),
|
||||
SQLITE3_WAL_AUTOCHECKPOINT(173, "sqlite3_wal_autocheckpoint"),
|
||||
SQLITE3_WAL_CHECKPOINT(174, "sqlite3_wal_checkpoint"), SQLITE3_WAL_HOOK(175, "sqlite3_wal_hook"),
|
||||
SQLITE3_BLOB_REOPEN(176, "sqlite3_blob_reopen"), SQLITE3_VTAB_CONFIG(177, "sqlite3_vtab_config"),
|
||||
SQLITE3_VTAB_ON_CONFLICT(178, "sqlite3_vtab_on_conflict"), SQLITE3_CLOSE_V2(179, "sqlite3_close_v2"),
|
||||
SQLITE3_DB_FILENAME(180, "sqlite3_db_filename"), SQLITE3_DB_READONLY(181, "sqlite3_db_readonly"),
|
||||
SQLITE3_DB_RELEASE_MEMORY(182, "sqlite3_db_release_memory"), SQLITE3_ERRSTR(183, "sqlite3_errstr"),
|
||||
SQLITE3_STMT_BUSY(184, "sqlite3_stmt_busy"), SQLITE3_STMT_READONLY(185, "sqlite3_stmt_readonly"),
|
||||
SQLITE3_STRICMP(186, "sqlite3_stricmp"), SQLITE3_URI_BOOLEAN(187, "sqlite3_uri_boolean"),
|
||||
SQLITE3_URI_INT64(188, "sqlite3_uri_int64"), SQLITE3_URI_PARAMETER(189, "sqlite3_uri_parameter"),
|
||||
SQLITE3_VSNPRINTF(190, "sqlite3_vsnprintf"), SQLITE3_WAL_CHECKPOINT_V2(191, "sqlite3_wal_checkpoint_v2"),
|
||||
SQLITE3_AUTO_EXTENSION(192, "sqlite3_auto_extension"), SQLITE3_BIND_BLOB64(193, "sqlite3_bind_blob64"),
|
||||
SQLITE3_BIND_TEXT64(194, "sqlite3_bind_text64"),
|
||||
SQLITE3_CANCEL_AUTO_EXTENSION(195, "sqlite3_cancel_auto_extension"),
|
||||
SQLITE3_LOAD_EXTENSION(196, "sqlite3_load_extension"), SQLITE3_MALLOC64(197, "sqlite3_malloc64"),
|
||||
SQLITE3_MSIZE(198, "sqlite3_msize"), SQLITE3_REALLOC64(199, "sqlite3_realloc64"),
|
||||
SQLITE3_RESET_AUTO_EXTENSION(200, "sqlite3_reset_auto_extension"),
|
||||
SQLITE3_RESULT_BLOB64(201, "sqlite3_result_blob64"), SQLITE3_RESULT_TEXT64(202, "sqlite3_result_text64"),
|
||||
SQLITE3_STRGLOB(203, "sqlite3_strglob"), SQLITE3_VALUE_DUP(204, "sqlite3_value_dup"),
|
||||
SQLITE3_VALUE_FREE(205, "sqlite3_value_free"), SQLITE3_RESULT_ZEROBLOB64(206, "sqlite3_result_zeroblob64"),
|
||||
SQLITE3_BIND_ZEROBLOB64(207, "sqlite3_bind_zeroblob64"), SQLITE3_VALUE_SUBTYPE(208, "sqlite3_value_subtype"),
|
||||
SQLITE3_RESULT_SUBTYPE(209, "sqlite3_result_subtype"), SQLITE3_STATUS64(210, "sqlite3_status64"),
|
||||
SQLITE3_STRLIKE(211, "sqlite3_strlike"), SQLITE3_DB_CACHEFLUSH(212, "sqlite3_db_cacheflush"),
|
||||
SQLITE3_SYSTEM_ERRNO(213, "sqlite3_system_errno"), SQLITE3_TRACE_V2(214, "sqlite3_trace_v2"),
|
||||
SQLITE3_EXPANDED_SQL(215, "sqlite3_expanded_sql"),
|
||||
SQLITE3_SET_LAST_INSERT_ROWID(216, "sqlite3_set_last_insert_rowid"),
|
||||
SQLITE3_PREPARE_V3(217, "sqlite3_prepare_v3"), SQLITE3_PREPARE16_V3(218, "sqlite3_prepare16_v3"),
|
||||
SQLITE3_BIND_POINTER(219, "sqlite3_bind_pointer"), SQLITE3_RESULT_POINTER(220, "sqlite3_result_pointer"),
|
||||
SQLITE3_VALUE_POINTER(221, "sqlite3_value_pointer"), SQLITE3_VTAB_NOCHANGE(222, "sqlite3_vtab_nochange"),
|
||||
SQLITE3_VALUE_NOCHANGE(223, "sqlite3_value_nochange"), SQLITE3_VTAB_COLLATION(224, "sqlite3_vtab_collation"),
|
||||
SQLITE3_KEYWORD_COUNT(225, "sqlite3_keyword_count"), SQLITE3_KEYWORD_NAME(226, "sqlite3_keyword_name"),
|
||||
SQLITE3_KEYWORD_CHECK(227, "sqlite3_keyword_check"), SQLITE3_STR_NEW(228, "sqlite3_str_new"),
|
||||
SQLITE3_STR_FINISH(229, "sqlite3_str_finish"), SQLITE3_STR_APPENDF(230, "sqlite3_str_appendf"),
|
||||
SQLITE3_STR_VAPPENDF(231, "sqlite3_str_vappendf"), SQLITE3_STR_APPEND(232, "sqlite3_str_append"),
|
||||
SQLITE3_STR_APPENDALL(233, "sqlite3_str_appendall"), SQLITE3_STR_APPENDCHAR(234, "sqlite3_str_appendchar"),
|
||||
SQLITE3_STR_RESET(235, "sqlite3_str_reset"), SQLITE3_STR_ERRCODE(236, "sqlite3_str_errcode"),
|
||||
SQLITE3_STR_LENGTH(237, "sqlite3_str_length"), SQLITE3_STR_VALUE(238, "sqlite3_str_value"),
|
||||
SQLITE3_CREATE_WINDOW_FUNCTION(239, "sqlite3_create_window_function"),
|
||||
SQLITE3_NORMALIZED_SQL(240, "sqlite3_normalized_sql"), SQLITE3_STMT_ISEXPLAIN(241, "sqlite3_stmt_isexplain"),
|
||||
SQLITE3_VALUE_FROMBIND(242, "sqlite3_value_frombind"), SQLITE3_DROP_MODULES(243, "sqlite3_drop_modules"),
|
||||
SQLITE3_HARD_HEAP_LIMIT64(244, "sqlite3_hard_heap_limit64"), SQLITE3_URI_KEY(245, "sqlite3_uri_key"),
|
||||
SQLITE3_FILENAME_DATABASE(246, "sqlite3_filename_database"),
|
||||
SQLITE3_FILENAME_JOURNAL(247, "sqlite3_filename_journal"), SQLITE3_FILENAME_WAL(248, "sqlite3_filename_wal"),
|
||||
SQLITE3_CREATE_FILENAME(249, "sqlite3_create_filename"), SQLITE3_FREE_FILENAME(250, "sqlite3_free_filename"),
|
||||
SQLITE3_DATABASE_FILE_OBJECT(251, "sqlite3_database_file_object"), SQLITE3_TXN_STATE(252, "sqlite3_txn_state"),
|
||||
SQLITE3_CHANGES64(253, "sqlite3_changes64"), SQLITE3_TOTAL_CHANGES64(254, "sqlite3_total_changes64"),
|
||||
SQLITE3_AUTOVACUUM_PAGES(255, "sqlite3_autovacuum_pages"), SQLITE3_ERROR_OFFSET(256, "sqlite3_error_offset"),
|
||||
SQLITE3_VTAB_RHS_VALUE(257, "sqlite3_vtab_rhs_value"), SQLITE3_VTAB_DISTINCT(258, "sqlite3_vtab_distinct"),
|
||||
SQLITE3_VTAB_IN(259, "sqlite3_vtab_in"), SQLITE3_VTAB_IN_FIRST(260, "sqlite3_vtab_in_first"),
|
||||
SQLITE3_VTAB_IN_NEXT(261, "sqlite3_vtab_in_next"), SQLITE3_DESERIALIZE(262, "sqlite3_deserialize"),
|
||||
SQLITE3_SERIALIZE(263, "sqlite3_serialize"), SQLITE3_DB_NAME(264, "sqlite3_db_name"),
|
||||
SQLITE3_VALUE_TYPE_3_40(265, "sqlite3_value_type");
|
||||
|
||||
private EnumSql(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
private Integer code;
|
||||
private String desc;
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static EnumSql getByCode(Integer code) {
|
||||
for (EnumSql item : EnumSql.values()) {
|
||||
if (item.getCode().equals(code)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EnumSql getByCode(String desc) {
|
||||
for (EnumSql item : EnumSql.values()) {
|
||||
if (item.getDesc().equals(desc)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user