From 8588f832ecb3e7ff1aadd280cd4c28d51afb95d1 Mon Sep 17 00:00:00 2001
From: gzygood <128460659+gzygood@users.noreply.github.com>
Date: Tue, 13 May 2025 18:22:25 +0800
Subject: [PATCH] Add files via upload
---
DbkeyHook.sln | 31 +++++
DbkeyHook.vcxproj | 178 +++++++++++++++++++++++++++
DbkeyHook.vcxproj.filters | 41 ++++++
DbkeyHook.vcxproj.user | 4 +
dllmain.cpp | 253 ++++++++++++++++++++++++++++++++++++++
framework.h | 5 +
pch.cpp | 5 +
pch.h | 13 ++
wrapper.asm | 50 ++++++++
wrapper.h | 4 +
10 files changed, 584 insertions(+)
create mode 100644 DbkeyHook.sln
create mode 100644 DbkeyHook.vcxproj
create mode 100644 DbkeyHook.vcxproj.filters
create mode 100644 DbkeyHook.vcxproj.user
create mode 100644 dllmain.cpp
create mode 100644 framework.h
create mode 100644 pch.cpp
create mode 100644 pch.h
create mode 100644 wrapper.asm
create mode 100644 wrapper.h
diff --git a/DbkeyHook.sln b/DbkeyHook.sln
new file mode 100644
index 0000000..2457d24
--- /dev/null
+++ b/DbkeyHook.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.35931.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DbkeyHook", "DbkeyHook.vcxproj", "{B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Debug|x64.ActiveCfg = Debug|x64
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Debug|x64.Build.0 = Debug|x64
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Debug|x86.ActiveCfg = Debug|Win32
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Debug|x86.Build.0 = Debug|Win32
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Release|x64.ActiveCfg = Release|x64
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Release|x64.Build.0 = Release|x64
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Release|x86.ActiveCfg = Release|Win32
+ {B8305ABB-1F1B-4FD5-AF77-A1F7C9CB67FD}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8CABB8D3-3F51-4D43-A140-C354CCCC4C28}
+ EndGlobalSection
+EndGlobal
diff --git a/DbkeyHook.vcxproj b/DbkeyHook.vcxproj
new file mode 100644
index 0000000..85995c4
--- /dev/null
+++ b/DbkeyHook.vcxproj
@@ -0,0 +1,178 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {b8305abb-1f1b-4fd5-af77-a1f7c9cb67fd}
+ DbkeyHook
+ 10.0
+ mmmojo_64
+
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;DBKEYHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;DBKEYHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+ Level3
+ true
+ _DEBUG;DBKEYHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;DBKEYHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+ Document
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DbkeyHook.vcxproj.filters b/DbkeyHook.vcxproj.filters
new file mode 100644
index 0000000..6ca96f3
--- /dev/null
+++ b/DbkeyHook.vcxproj.filters
@@ -0,0 +1,41 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+
+
+ 源文件
+
+
+
\ No newline at end of file
diff --git a/DbkeyHook.vcxproj.user b/DbkeyHook.vcxproj.user
new file mode 100644
index 0000000..0f14913
--- /dev/null
+++ b/DbkeyHook.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/dllmain.cpp b/dllmain.cpp
new file mode 100644
index 0000000..f0c3c55
--- /dev/null
+++ b/dllmain.cpp
@@ -0,0 +1,253 @@
+// dllmain.cpp : 定义 DLL 应用程序的入口点。
+#include "pch.h"
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//x64汇编
+#include "wrapper.h"
+
+
+// 劫持mmmojo_64.dll -> mmmojo_64_true.dll
+#pragma comment(linker, "/EXPORT:AppendMMSubProcessSwitchNative=mmmojo_64_true.AppendMMSubProcessSwitchNative,@1")
+#pragma comment(linker, "/EXPORT:CreateMMMojoEnvironment=mmmojo_64_true.CreateMMMojoEnvironment,@2")
+#pragma comment(linker, "/EXPORT:CreateMMMojoWriteInfo=mmmojo_64_true.CreateMMMojoWriteInfo,@3")
+#pragma comment(linker, "/EXPORT:GetHandleVerifier=mmmojo_64_true.GetHandleVerifier,@4")
+#pragma comment(linker, "/EXPORT:GetMMMojoReadInfoAttach=mmmojo_64_true.GetMMMojoReadInfoAttach,@5")
+#pragma comment(linker, "/EXPORT:GetMMMojoReadInfoMethod=mmmojo_64_true.GetMMMojoReadInfoMethod,@6")
+#pragma comment(linker, "/EXPORT:GetMMMojoReadInfoRequest=mmmojo_64_true.GetMMMojoReadInfoRequest,@7")
+#pragma comment(linker, "/EXPORT:GetMMMojoReadInfoSync=mmmojo_64_true.GetMMMojoReadInfoSync,@8")
+#pragma comment(linker, "/EXPORT:GetMMMojoWriteInfoAttach=mmmojo_64_true.GetMMMojoWriteInfoAttach,@9")
+#pragma comment(linker, "/EXPORT:GetMMMojoWriteInfoRequest=mmmojo_64_true.GetMMMojoWriteInfoRequest,@10")
+#pragma comment(linker, "/EXPORT:InitializeMMMojo=mmmojo_64_true.InitializeMMMojo,@11")
+#pragma comment(linker, "/EXPORT:IsSandboxedProcess=mmmojo_64_true.IsSandboxedProcess,@12")
+#pragma comment(linker, "/EXPORT:RemoveMMMojoEnvironment=mmmojo_64_true.RemoveMMMojoEnvironment,@13")
+#pragma comment(linker, "/EXPORT:RemoveMMMojoReadInfo=mmmojo_64_true.RemoveMMMojoReadInfo,@14")
+#pragma comment(linker, "/EXPORT:RemoveMMMojoWriteInfo=mmmojo_64_true.RemoveMMMojoWriteInfo,@15")
+#pragma comment(linker, "/EXPORT:SendMMMojoWriteInfo=mmmojo_64_true.SendMMMojoWriteInfo,@16")
+#pragma comment(linker, "/EXPORT:SetMMMojoConfiguration=mmmojo_64_true.SetMMMojoConfiguration,@17")
+#pragma comment(linker, "/EXPORT:SetMMMojoEnvironmentCallbacks=mmmojo_64_true.SetMMMojoEnvironmentCallbacks,@18")
+#pragma comment(linker, "/EXPORT:SetMMMojoEnvironmentInitParams=mmmojo_64_true.SetMMMojoEnvironmentInitParams,@19")
+#pragma comment(linker, "/EXPORT:SetMMMojoWriteInfoMessagePipe=mmmojo_64_true.SetMMMojoWriteInfoMessagePipe,@20")
+#pragma comment(linker, "/EXPORT:SetMMMojoWriteInfoResponseSync=mmmojo_64_true.SetMMMojoWriteInfoResponseSync,@21")
+#pragma comment(linker, "/EXPORT:ShutdownMMMojo=mmmojo_64_true.ShutdownMMMojo,@22")
+#pragma comment(linker, "/EXPORT:StartMMMojoEnvironment=mmmojo_64_true.StartMMMojoEnvironment,@23")
+#pragma comment(linker, "/EXPORT:StopMMMojoEnvironment=mmmojo_64_true.StopMMMojoEnvironment,@24")
+#pragma comment(linker, "/EXPORT:SwapMMMojoWriteInfoCallback=mmmojo_64_true.SwapMMMojoWriteInfoCallback,@25")
+#pragma comment(linker, "/EXPORT:SwapMMMojoWriteInfoMessage=mmmojo_64_true.SwapMMMojoWriteInfoMessage,@26")
+
+extern "C" uint64_t HijackLogic(uint64_t key_class); //劫持逻辑
+extern "C" uint64_t g_imgbase = 0; //Weixin.dll的基址
+extern "C" uint64_t g_hook_offset = 0; //要hook的偏移
+extern "C" uint8_t * g_transfer_zone = 0; //中转指令内存
+
+struct OrgInfo
+{
+ uint64_t addr; //地址
+ size_t org_size; //原始机器码长度
+ uint8_t org_opcodes[256]; //被HOOK之前原始的机器码
+};
+std::vector g_org_info;
+
+void OutputDebugPrintf(const char* strOutputString, ...)
+{
+#define OUT_DEBUG_BUF_LEN 512
+ char strBuffer[OUT_DEBUG_BUF_LEN] = { 0 };
+ va_list vlArgs;
+ va_start(vlArgs, strOutputString);
+ _vsnprintf_s(strBuffer, sizeof(strBuffer) - 1, strOutputString, vlArgs); //_vsnprintf_s _vsnprintf
+ va_end(vlArgs);
+ OutputDebugStringA(strBuffer); //OutputDebugString // OutputDebugStringW
+}
+
+
+std::string toHexString(const uint8_t* data, size_t size) {
+ std::stringstream ss;
+ ss << std::hex << std::setfill('0');
+ for (size_t i = 0; i < size; ++i) {
+ ss << std::setw(2) << static_cast(data[i]);
+ }
+ return ss.str();
+}
+
+/**
+ * @brief 恢复HOOK写入的字节.
+ */
+void HookEnd(uint8_t type)
+{
+ //写入原机器码
+ if (g_org_info.size() != 0) {
+ for (auto& org_info : g_org_info)
+ {
+ if (org_info.addr == 0) {
+ OutputDebugString(TEXT("[DbkeyHook] Hook Addr is 0"));
+ continue;
+ }
+ BOOL bRet = WriteProcessMemory(GetCurrentProcess(), (LPVOID)org_info.addr, org_info.org_opcodes, org_info.org_size, NULL);
+ if (bRet == NULL)
+ OutputDebugPrintf("[DbkeyHook] Write Hook Org Bytes Failed! [%d]", GetLastError());
+ }
+ }
+ if (type == 2) {
+ if (g_transfer_zone) {
+ if (!VirtualFree(g_transfer_zone, 0, MEM_RELEASE)) {
+ OutputDebugPrintf("[DbkeyHook] Free Transfer Mem Failed! [%d]", GetLastError());
+ return;
+ }
+ }
+ }
+}
+
+
+uint64_t HijackLogic(uint64_t a4/*r9*/)
+{
+
+ uint64_t key_class = a4;
+ uint64_t DbkeyLength_addr = key_class + 0x18, DbkeyLength = 0;
+ uint64_t Dbkey_addr_offet = key_class + 0x8, DbkeyAddr = 0;
+
+
+ ReadProcessMemory(GetCurrentProcess(), (LPCVOID)DbkeyLength_addr, &DbkeyLength, 4, NULL); //
+ ReadProcessMemory(GetCurrentProcess(), (LPCVOID)Dbkey_addr_offet, &DbkeyAddr, 8, NULL); //
+
+ OutputDebugPrintf("[DbkeyHook] DbkeyLength = [%d],DbkeyAddr = 0x%llX", DbkeyLength, DbkeyAddr);
+
+ if (!DbkeyAddr || DbkeyLength != 32) {
+ return 0;
+ }
+
+ uint8_t db_key[32];
+
+ BOOL bRet = ReadProcessMemory(GetCurrentProcess(), (LPCVOID)DbkeyAddr, db_key, 32, NULL);
+ if (!bRet)
+ {
+ OutputDebugPrintf("[DbkeyHook] Read db_key Bytes Failed! [%d]", GetLastError());
+ return 0;
+ }
+
+ std::string db_key_Str = toHexString(db_key, sizeof(db_key));
+ OutputDebugPrintf("[DbkeyHook] GET DBkey String [%s]", db_key_Str.c_str());
+
+ std::ofstream file("dbkey.txt"); // 默认覆盖模式
+ if (file.is_open()) {
+ file << db_key_Str; // 写入文本
+ file.close(); // 显式关闭文件(可选,析构时会自动关闭)
+ //获取到dbkey就取消hook
+ HookEnd(1);
+ OutputDebugPrintf("[DbkeyHook] Write dbkey to dbkey.txt");
+ }
+ else {
+
+ OutputDebugPrintf("[DbkeyHook] Write dbkey.txt Failed! [%d]", GetLastError());
+ }
+
+
+ return 0;
+
+}
+
+
+void HookStart(HMODULE hModule)
+{
+ HMODULE weixin_dll_base = GetModuleHandle(_T("Weixin.dll"));
+ if (weixin_dll_base == NULL)
+ {
+ OutputDebugPrintf("[DbkeyHook] Get Weixin.dll's ImgBase Failed! [%d]", GetLastError());
+ return;
+ }
+ g_imgbase = (uint64_t)weixin_dll_base;
+ g_hook_offset = 0x0C0A9A6;// 这个是4.0.5.7的 4.0.3.43 = 0x0BC91A6
+
+ //读取Hook点原机器码
+ uint64_t hook_addr = g_imgbase + g_hook_offset;
+ uint8_t hook_opcode[] = {/*mov rax, 地址*/0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*jmp rax*/0xFF, 0xE0 };
+ size_t hook_size = sizeof(hook_opcode); //12个字节
+
+ OrgInfo hook_org_info;// 记录原始字节信息
+ hook_org_info.addr = hook_addr; //记录地址
+ hook_org_info.org_size = hook_size; //记录要写多少个字节
+ BOOL bRet = ReadProcessMemory(GetCurrentProcess(), (LPCVOID)hook_addr, hook_org_info.org_opcodes, hook_size, NULL);
+ if (!bRet)
+ {
+ OutputDebugPrintf("[DbkeyHook] Read Hook Org Bytes Failed! [%d]", GetLastError());
+ return;
+ }
+ g_org_info.push_back(hook_org_info); //记录
+
+
+
+ //构造中转区机器码 原指令 + jmp far
+ size_t org_insns_len = hook_size; //暂时先写死
+ g_transfer_zone = (uint8_t*)VirtualAlloc(NULL, 64, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if (!g_transfer_zone) {
+ OutputDebugPrintf("[DbkeyHook] Alloc Transfer Mem Failed! [%d]", GetLastError());
+ return;
+ }
+
+ bRet = ReadProcessMemory(GetCurrentProcess(), (LPCVOID)hook_addr, g_transfer_zone, org_insns_len, NULL);
+ if (!bRet)
+ {
+ OutputDebugPrintf("[DbkeyHook] Read Transfer Zone Org Bytes Failed! [%d]", GetLastError());
+ return;
+ }
+
+ uint8_t jmp_org_opcode[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0 };
+ uint64_t next_insn_addr = hook_addr + org_insns_len;
+ for (size_t i = 0; i < sizeof(uint64_t); i++) //跳回去
+ jmp_org_opcode[i + 2] = *((uint8_t*)(&next_insn_addr) + i);
+ memcpy(g_transfer_zone + org_insns_len, jmp_org_opcode, sizeof(jmp_org_opcode));
+ OutputDebugPrintf("[DbkeyHook] g_transfer_zone Addr: 0x%llX", g_transfer_zone);
+
+
+
+ //写入劫持机器码 跳转到HijackLogicWarpper函数处
+ uint64_t hijacklogic_addr = (uint64_t)(&HijackLogicWarpper);
+ for (size_t i = 0; i < sizeof(uint64_t); i++)
+ {
+ hook_opcode[i + 2] = *((uint8_t*)(&hijacklogic_addr) + i);
+ }
+ bRet = WriteProcessMemory(GetCurrentProcess(), (LPVOID)hook_addr, hook_opcode, hook_size, NULL);
+ if (bRet == NULL)
+ {
+ OutputDebugPrintf("[DbkeyHook] Write Hook Bytes Failed! [%d]", GetLastError());
+ return;
+ }
+
+
+}
+
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule); //防止多次调用
+ //不知道为什么不会自动加载mmmojo_64_true.dll 直接手动加载
+ OutputDebugPrintf("[DbkeyHook] Load mmmojo_64_true.dll: 0x%llX", LoadLibrary(TEXT("mmmojo_64_true.dll")));
+ OutputDebugString(TEXT("[DbkeyHook] Begin Hook and Hijack!"));
+ HookStart(hModule);
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ OutputDebugString(TEXT("[DbkeyHook] Restore Hook Bytes!"));
+ HookEnd(2);
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/framework.h b/framework.h
new file mode 100644
index 0000000..3f0fc4a
--- /dev/null
+++ b/framework.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
+// Windows 头文件
+#include
diff --git a/pch.cpp b/pch.cpp
new file mode 100644
index 0000000..db1a479
--- /dev/null
+++ b/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: 与预编译标头对应的源文件
+
+#include "pch.h"
+
+// 当使用预编译的头时,需要使用此源文件,编译才能成功。
diff --git a/pch.h b/pch.h
new file mode 100644
index 0000000..aa4549e
--- /dev/null
+++ b/pch.h
@@ -0,0 +1,13 @@
+// pch.h: 这是预编译标头文件。
+// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
+// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
+// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
+// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
+
+#ifndef PCH_H
+#define PCH_H
+
+// 添加要在此处预编译的标头
+#include "framework.h"
+
+#endif //PCH_H
diff --git a/wrapper.asm b/wrapper.asm
new file mode 100644
index 0000000..a6c5594
--- /dev/null
+++ b/wrapper.asm
@@ -0,0 +1,50 @@
+EXTERN HijackLogic: PROC ; ⲿ
+
+EXTERN g_transfer_zone: QWORD ; ⲿ
+
+.CODE
+
+; ջ룺 64 λģʽ£úʱջ 16 ֽڶ
+HijackLogicWarpper PROC
+ push rbx ; ѹͨüĴ
+ push rcx
+ push rdx
+ push rsi
+ push rdi
+ push rbp
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+ pushfq ; ѹeflags
+
+ sub rsp, 28h ; ջ
+ mov rcx, r9 ; Ϊarg4
+ call HijackLogic ; HijackLogic KeyClassڴ
+ add rsp, 28h ; ָջ
+
+ popfq ; ָeflags
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rbp
+ pop rdi
+ pop rsi
+ pop rdx
+ pop rcx
+ pop rbx ; ָͨüĴ
+
+ mov rax, qword ptr [g_transfer_zone] ; raxֵg_transfer_zone
+ jmp rax ; תתڴִԭָ
+HijackLogicWarpper ENDP
+
+END
\ No newline at end of file
diff --git a/wrapper.h b/wrapper.h
new file mode 100644
index 0000000..bab621c
--- /dev/null
+++ b/wrapper.h
@@ -0,0 +1,4 @@
+#pragma once
+#include
+
+extern "C" uint64_t HijackLogicWarpper(uint64_t PixCloudInstance);
\ No newline at end of file