feat:初版

This commit is contained in:
2025-12-03 15:48:44 +08:00
commit b4df26f61d
199 changed files with 23434 additions and 0 deletions

311
WechatHook/loader.py Normal file
View File

@@ -0,0 +1,311 @@
"""
NoveLoader - DLL 加载器和函数封装
基于个微大客户版 Loader.dll 的 Python 封装
"""
import ctypes
import os
from ctypes import WinDLL, create_string_buffer, WINFUNCTYPE
from typing import Callable
from loguru import logger
def c_string(data: str) -> ctypes.c_char_p:
"""将 Python 字符串转换为 C 字符串"""
return ctypes.c_char_p(data.encode('utf-8'))
def create_shared_memory():
"""创建共享内存用于DLL通信"""
try:
kernel32 = ctypes.WinDLL('kernel32')
# 创建文件映射
file_handle = kernel32.CreateFileMappingA(
-1,
None,
4, # PAGE_READWRITE
0,
33,
"windows_shell_global__".encode('utf-8')
)
if not file_handle:
logger.warning("创建共享内存失败")
return None, None
# 映射到内存
data_address = kernel32.MapViewOfFile(
file_handle,
983071, # FILE_MAP_ALL_ACCESS
0,
0,
0
)
if not data_address:
logger.warning("映射共享内存失败")
kernel32.CloseHandle(file_handle)
return None, None
# 写入Key数据
key = "3101b223dca7715b0154924f0eeeee20".encode('utf-8')
kernel32.RtlMoveMemory(data_address, key, len(key))
logger.success("共享内存创建成功")
return file_handle, data_address
except Exception as e:
logger.warning(f"创建共享内存异常: {e}")
return None, None
class NoveLoader:
"""
Loader.dll 封装类
通过内存偏移调用 DLL 中的未导出函数
"""
# 加载器模块基址
loader_module_base: int = 0
# 函数偏移地址(基于 Loader.dll
_InitWeChatSocket: int = 0xB080
_GetUserWeChatVersion: int = 0xCB80
_InjectWeChat: int = 0xCC10
_SendWeChatData: int = 0xAF90
_DestroyWeChat: int = 0xC540
_UseUtf8: int = 0xC680
_InjectWeChat2: int = 0x14D7
_InjectWeChatPid: int = 0xB750
_InjectWeChatMultiOpen: int = 0x33B2
def __init__(self, loader_path: str):
"""
初始化 Loader
Args:
loader_path: Loader.dll 的路径
"""
loader_path = os.path.realpath(loader_path)
if not os.path.exists(loader_path):
logger.error(f'Loader.dll 不存在: {loader_path}')
raise FileNotFoundError(f'Loader.dll 不存在: {loader_path}')
logger.info(f"加载 Loader.dll: {loader_path}")
loader_module = WinDLL(loader_path)
self.loader_module_base = loader_module._handle
# 使用 UTF-8 编码
self.UseUtf8()
logger.success("Loader.dll 加载成功")
# 初始化回调
from WechatHook.callbacks import (
wechat_connect_callback,
wechat_recv_callback,
wechat_close_callback
)
self.InitWeChatSocket(
wechat_connect_callback,
wechat_recv_callback,
wechat_close_callback
)
def __get_non_exported_func(self, offset: int, arg_types, return_type):
"""
通过内存偏移获取未导出的函数
Args:
offset: 函数相对于模块基址的偏移
arg_types: 参数类型列表
return_type: 返回值类型
Returns:
可调用的函数对象
"""
func_addr = self.loader_module_base + offset
if arg_types:
func_type = ctypes.WINFUNCTYPE(return_type, *arg_types)
else:
func_type = ctypes.WINFUNCTYPE(return_type)
return func_type(func_addr)
def InitWeChatSocket(
self,
connect_callback: Callable,
recv_callback: Callable,
close_callback: Callable
) -> bool:
"""
初始化微信 Socket 回调
Args:
connect_callback: 连接回调函数
recv_callback: 接收消息回调函数
close_callback: 断开连接回调函数
Returns:
是否初始化成功
"""
func = self.__get_non_exported_func(
self._InitWeChatSocket,
[ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p],
ctypes.c_bool
)
result = func(connect_callback, recv_callback, close_callback)
logger.info(f"InitWeChatSocket: {result}")
return result
def GetUserWeChatVersion(self) -> str:
"""
获取用户电脑上安装的微信版本
Returns:
微信版本号,如 "3.9.10.19"
"""
func = self.__get_non_exported_func(
self._GetUserWeChatVersion,
[ctypes.c_char_p],
ctypes.c_bool
)
out = create_string_buffer(30)
if func(out):
version = out.value.decode('utf-8')
logger.info(f"微信版本: {version}")
return version
else:
logger.warning("获取微信版本失败")
return ''
def InjectWeChat(self, dll_path: str) -> int:
"""
注入微信(智能多开)
Args:
dll_path: Helper.dll 的路径
Returns:
客户端 ID进程 ID失败返回 0
"""
dll_path = os.path.realpath(dll_path)
if not os.path.exists(dll_path):
logger.error(f'Helper.dll 不存在: {dll_path}')
return 0
func = self.__get_non_exported_func(
self._InjectWeChat,
[ctypes.c_char_p],
ctypes.c_uint32
)
client_id = func(c_string(dll_path))
if client_id:
logger.success(f"注入微信成功,客户端 ID: {client_id}")
else:
logger.error("注入微信失败")
return client_id
def SendWeChatData(self, client_id: int, message: str) -> bool:
"""
向微信发送数据
Args:
client_id: 客户端 ID
message: JSON 格式的消息
Returns:
是否发送成功
"""
func = self.__get_non_exported_func(
self._SendWeChatData,
[ctypes.c_uint32, ctypes.c_char_p],
ctypes.c_bool
)
result = func(client_id, c_string(message))
return result
def DestroyWeChat(self) -> bool:
"""
销毁微信连接
Returns:
是否成功
"""
func = self.__get_non_exported_func(
self._DestroyWeChat,
None,
ctypes.c_bool
)
result = func()
logger.info(f"DestroyWeChat: {result}")
return result
def UseUtf8(self) -> bool:
"""
设置使用 UTF-8 编码
Returns:
是否成功
"""
func = self.__get_non_exported_func(
self._UseUtf8,
None,
ctypes.c_bool
)
return func()
def InjectWeChat2(self, dll_path: str, exe_path: str) -> int:
"""
注入微信(指定微信路径)
Args:
dll_path: Helper.dll 的路径
exe_path: WeChat.exe 的路径
Returns:
客户端 ID失败返回 0
"""
func = self.__get_non_exported_func(
self._InjectWeChat2,
[ctypes.c_char_p, ctypes.c_char_p],
ctypes.c_uint32
)
return func(c_string(dll_path), c_string(exe_path))
def InjectWeChatPid(self, pid: int, dll_path: str) -> int:
"""
注入指定的微信进程
Args:
pid: 微信进程 ID
dll_path: Helper.dll 的路径
Returns:
客户端 ID失败返回 0
"""
func = self.__get_non_exported_func(
self._InjectWeChatPid,
[ctypes.c_uint32, ctypes.c_char_p],
ctypes.c_uint32
)
return func(pid, c_string(dll_path))
def InjectWeChatMultiOpen(self, dll_path: str, exe_path: str = "") -> int:
"""
多开一个新的微信进程并注入
Args:
dll_path: Helper.dll 的路径
exe_path: WeChat.exe 的路径(可选)
Returns:
客户端 ID失败返回 0
"""
func = self.__get_non_exported_func(
self._InjectWeChatMultiOpen,
[ctypes.c_char_p, ctypes.c_char_p],
ctypes.c_uint32
)
return func(c_string(dll_path), c_string(exe_path) if exe_path else c_string(""))