Files
FuckScreenCap/AntiScreenCap/main.cpp

519 lines
14 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#define _CRT_SECURE_NO_WARNINGS
#include "hook_current.h"
#include "main.h"
#include <windows.h>
#include <tchar.h>
#include <string>
#include <Shlwapi.h>
#include <commctrl.h>
#include "config_manager.h"
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"comctl32.lib")
using namespace std;
// 窗口类名和标题
const wchar_t g_szClassName[] = L"WindowControlApp";
const wchar_t g_szTitle[] = L"窗口控制程序";
// 控件ID定义
#define IDC_BUTTON_HIDE 1001
#define IDC_BUTTON_SHOW 1002
#define IDC_BUTTON_HOOK_RTL 1003
#define IDC_BUTTON_UNHOOK_RTL 1004
#define IDC_BUTTON_DEBUG 1005
#define IDC_BUTTON_STOP 1006
#define IDC_LISTBOX_LOG 1007
#define IDC_BUTTON_CLEAR_LOG 1008
#define IDC_STATIC_STATUS 1009
// 控制程序自身可见性按钮
#define IDC_BUTTON_VISBLE_SELF 1010
#define HOTKEY_ID 1011
// 全局变量
HWND g_hMainWnd = NULL;
HWND g_hLogListBox = NULL;
HWND g_hStatusText = NULL;
HINSTANCE g_hInst = NULL;
bool g_bRtlHookEnabled = false;
bool g_bIPCInitialized = false;
typedef BOOL(WINAPI* pfnSetHook) (BOOL);
pfnSetHook SetHook = NULL;
const int FILEMAP_BUF = 64;
const int LOG_SIZE = 512;
//for ipc
char* pBuf;
HANDLE hServerEvent, hClientEvent, hFileMap;
#ifdef _WIN64
const std::wstring hideDllName{ L"Hide.dll" };
const std::wstring unhideDllName{ L"Unhide.dll" };
const std::wstring RtlHideDllName{ L"RtlHide.dll" };
#else
const std::wstring hideDllName{ L"Hide32.dll" };
const std::wstring unhideDllName{ L"Unhide32.dll" };
const std::wstring RtlHideDllName{ L"RtlHide32.dll" };
#endif
//添加MessageBoxTimeout支持
typedef int (WINAPI* MessageBoxTimeoutA)(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
typedef int (WINAPI* MessageBoxTimeoutW)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
HMODULE hUser32 = LoadLibraryA("user32.dll");
#ifdef UNICODE
#define MessageBoxTimeout ((MessageBoxTimeoutW)(GetProcAddress(hUser32, "MessageBoxTimeoutW")))
#else
#define MessageBoxTimeout ((MessageBoxTimeoutA)(GetProcAddress(hUser32, "MessageBoxTimeoutA")))
#endif
bool g_bSelfHidden = false;
bool g_bHotkeyRegistered = false; // 新增:跟踪快捷键注册状态
// 日志函数
void Log(LogLevel level, int line, const char* format, ...) {
if (!g_hLogListBox) return;
char msg[LOG_SIZE] = { 0 };
char finalMsg[LOG_SIZE + 50] = { 0 };
va_list ap;
va_start(ap, format);
vsprintf(msg, format, ap);
va_end(ap);
const char* levelStr = "";
switch (level) {
case LogLevel::LOG_INFO:
levelStr = "[INFO] ";
break;
case LogLevel::LOG_WARN:
levelStr = "[WARN] ";
sprintf(finalMsg, "%s[Line %d] %s", levelStr, line, msg);
break;
case LogLevel::LOG_ERROR:
levelStr = "[ERROR] ";
sprintf(finalMsg, "%s[Line %d] %s", levelStr, line, msg);
break;
}
if (level == LogLevel::LOG_INFO) {
strcpy(finalMsg, msg);
}
// 转换为宽字符并添加到列表框
wchar_t wMsg[LOG_SIZE + 50];
MultiByteToWideChar(CP_ACP, 0, finalMsg, -1, wMsg, LOG_SIZE + 50);
int index = SendMessage(g_hLogListBox, LB_ADDSTRING, 0, (LPARAM)wMsg);
SendMessage(g_hLogListBox, LB_SETCURSEL, index, 0);
}
// 更新状态文本
void UpdateStatus(const wchar_t* status) {
if (g_hStatusText) {
SetWindowText(g_hStatusText, status);
}
}
bool SetPrivilege() {
HANDLE hToken;
TOKEN_PRIVILEGES NewState;
LUID luidPrivilegeLUID;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) ||
!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidPrivilegeLUID)) {
Log(LogLevel::LOG_WARN, __LINE__, "SetPrivilege Error: %d", GetLastError());
return false;
}
NewState.PrivilegeCount = 1;
NewState.Privileges[0].Luid = luidPrivilegeLUID;
NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &NewState, NULL, NULL, NULL)) {
Log(LogLevel::LOG_WARN, __LINE__, "AdjustTokenPrivilege Error: %d", GetLastError());
return false;
}
return true;
}
bool FileExists(std::wstring& filePath) {
DWORD dwAttrib = GetFileAttributes(filePath.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
std::wstring getFullFilePath(const std::wstring& filename) {
wchar_t fullPath[MAX_PATH] = { 0 };
GetModuleFileName(NULL, fullPath, MAX_PATH);
PathRemoveFileSpec(fullPath);
PathAppend(fullPath, filename.c_str());
std::wstring strFullPath{ fullPath };
if (!FileExists(strFullPath)) {
Log(LogLevel::LOG_ERROR, __LINE__, "FileExists: %S", strFullPath.c_str());
return std::wstring{};
}
return strFullPath;
}
bool HookRtlWindow(bool hook) {
HMODULE RtlHideDll = LoadLibrary(RtlHideDllName.c_str());
if (!RtlHideDll) {
Log(LogLevel::LOG_ERROR, __LINE__, "LoadLibrary %S Error: %d", RtlHideDllName.c_str(), GetLastError());
return false;
}
#ifdef _WIN64
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "SetHook");
#else
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "_SetHook@4");
#endif
if (!SetHook) {
Log(LogLevel::LOG_ERROR, __LINE__, "GetProcAddress SetHook Error: %d", GetLastError());
return false;
}
if (hook) {
if (SetHook(TRUE)) {
Log(LogLevel::LOG_INFO, __LINE__, "Set Hook Success");
g_bRtlHookEnabled = true;
UpdateStatus(L"状态: 实时钩子已启用");
return true;
}
else {
Log(LogLevel::LOG_ERROR, __LINE__, "Set Hook Error. See More in DebugView");
}
}
else {
if (SetHook(FALSE)) {
Log(LogLevel::LOG_INFO, __LINE__, "Set Unhook Success");
g_bRtlHookEnabled = false;
UpdateStatus(L"状态: 实时钩子已禁用");
return true;
}
else {
Log(LogLevel::LOG_ERROR, __LINE__, "Set Unhook Error. See More in DebugView");
}
}
return false;
}
// 修改HideSelf函数只有快捷键注册成功时才允许隐藏
void HideSelf() {
if (!g_bHotkeyRegistered) {
Log(LogLevel::LOG_ERROR, __LINE__, "无法隐藏:全局快捷键未注册");
return;
}
if (g_hMainWnd) {
ShowWindow(g_hMainWnd, SW_HIDE);
g_bSelfHidden = true;
UpdateStatus(L"状态: 程序已隐藏");
Log(LogLevel::LOG_INFO, __LINE__, "程序窗口已隐藏");
}
}
HANDLE CreateGlobalEvent(string& eventName) {
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(sa);
if (eventName.find("Global\\") == eventName.npos) {
eventName = "Global\\" + eventName;
}
return CreateEventA(&sa, FALSE, FALSE, eventName.c_str());
}
HANDLE CreateGlobalFileMap(string& fileMapName) {
if (fileMapName.find("Global\\") == fileMapName.npos) {
fileMapName = "Global\\" + fileMapName;
}
return CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
FILEMAP_BUF,
fileMapName.c_str()
);
}
bool initIPCEnvironment() {
string baseName = to_string(GetCurrentProcessId());
string serverEventName = baseName + "-ServerEvent";
string clientEventName = baseName + "-ClientEvent";
string fileMapName = baseName + "-FileMap";
hServerEvent = CreateGlobalEvent(serverEventName);
if (!hServerEvent) {
Log(LogLevel::LOG_ERROR, __LINE__, "CreateGlobalEvent: %s failed", serverEventName.c_str());
return false;
}
hClientEvent = CreateGlobalEvent(clientEventName);
if (!hClientEvent) {
Log(LogLevel::LOG_ERROR, __LINE__, "CreateGlobalEvent: %s failed", clientEventName.c_str());
return false;
}
hFileMap = CreateGlobalFileMap(fileMapName);
if (!hFileMap) {
Log(LogLevel::LOG_ERROR, __LINE__, "CreateGlobalFileMap: %s failed", fileMapName.c_str());
return false;
}
pBuf = (char*)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, FILEMAP_BUF);
if (!pBuf) {
Log(LogLevel::LOG_ERROR, __LINE__, "MapViewOfFile failed");
return false;
}
g_bIPCInitialized = true;
Log(LogLevel::LOG_INFO, __LINE__, "IPC环境初始化成功");
return true;
}
void CleanupIPC() {
if (pBuf) {
UnmapViewOfFile(pBuf);
pBuf = NULL;
}
if (hFileMap) {
CloseHandle(hFileMap);
hFileMap = NULL;
}
if (hServerEvent) {
CloseHandle(hServerEvent);
hServerEvent = NULL;
}
if (hClientEvent) {
CloseHandle(hClientEvent);
hClientEvent = NULL;
}
g_bIPCInitialized = false;
}
// 处理按钮点击事件
void OnButtonClick(int buttonId) {
switch (buttonId) {
case IDC_BUTTON_HIDE:
Log(LogLevel::LOG_INFO, __LINE__, "执行隐藏窗口操作...");
if (HookCurWindow(hideDllName)) {
Log(LogLevel::LOG_INFO, __LINE__, "窗口隐藏操作完成");
UpdateStatus(L"状态: 窗口已隐藏");
}
break;
case IDC_BUTTON_SHOW:
Log(LogLevel::LOG_INFO, __LINE__, "执行显示窗口操作...");
if (HookCurWindow(unhideDllName)) {
Log(LogLevel::LOG_INFO, __LINE__, "窗口显示操作完成");
UpdateStatus(L"状态: 窗口已显示");
}
break;
case IDC_BUTTON_HOOK_RTL:
if (!g_bRtlHookEnabled) {
Log(LogLevel::LOG_INFO, __LINE__, "启用实时钩子...");
HookRtlWindow(true);
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "实时钩子已经启用");
}
break;
case IDC_BUTTON_UNHOOK_RTL:
if (g_bRtlHookEnabled) {
Log(LogLevel::LOG_INFO, __LINE__, "禁用实时钩子...");
HookRtlWindow(false);
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "实时钩子已经禁用");
}
break;
case IDC_BUTTON_DEBUG:
if (g_bIPCInitialized && pBuf) {
strcpy_s(pBuf, FILEMAP_BUF, "debug");
SetEvent(hServerEvent);
Log(LogLevel::LOG_INFO, __LINE__, "发送调试命令");
}
else {
Log(LogLevel::LOG_ERROR, __LINE__, "IPC未初始化无法发送命令");
}
break;
case IDC_BUTTON_STOP:
if (g_bIPCInitialized && pBuf) {
strcpy_s(pBuf, FILEMAP_BUF, "stop");
SetEvent(hServerEvent);
Log(LogLevel::LOG_INFO, __LINE__, "发送停止命令");
}
break;
case IDC_BUTTON_CLEAR_LOG:
SendMessage(g_hLogListBox, LB_RESETCONTENT, 0, 0);
Log(LogLevel::LOG_INFO, __LINE__, "日志已清空");
break;
case IDC_BUTTON_VISBLE_SELF:
Log(LogLevel::LOG_INFO, __LINE__, "执行隐藏自身操作...");
HideSelf();
break;
}
}
// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
{
// 创建控件
CreateWindow(L"BUTTON", L"隐藏窗口", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_HIDE, g_hInst, NULL);
CreateWindow(L"BUTTON", L"显示窗口", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
120, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_SHOW, g_hInst, NULL);
CreateWindow(L"BUTTON", L"启用实时钩子", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
230, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_HOOK_RTL, g_hInst, NULL);
CreateWindow(L"BUTTON", L"禁用实时钩子", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
340, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_UNHOOK_RTL, g_hInst, NULL);
CreateWindow(L"BUTTON", L"调试", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
450, 10, 60, 30, hwnd, (HMENU)IDC_BUTTON_DEBUG, g_hInst, NULL);
CreateWindow(L"BUTTON", L"停止", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
520, 10, 60, 30, hwnd, (HMENU)IDC_BUTTON_STOP, g_hInst, NULL);
CreateWindow(L"BUTTON", L"清空日志", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
590, 10, 80, 30, hwnd, (HMENU)IDC_BUTTON_CLEAR_LOG, g_hInst, NULL);
CreateWindow(L"BUTTON", L"隐藏自身", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
10, 375, 80, 30, hwnd, (HMENU)IDC_BUTTON_VISBLE_SELF, g_hInst, NULL);
// 状态文本
g_hStatusText = CreateWindow(L"STATIC", L"状态: 就绪", WS_VISIBLE | WS_CHILD | SS_LEFT,
10, 50, 660, 20, hwnd, (HMENU)IDC_STATIC_STATUS, g_hInst, NULL);
// 日志列表框
g_hLogListBox = CreateWindow(L"LISTBOX", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_NOTIFY,
10, 80, 660, 300, hwnd, (HMENU)IDC_LISTBOX_LOG, g_hInst, NULL);
// 初始化
SetPrivilege();
initIPCEnvironment();
Log(LogLevel::LOG_INFO, __LINE__, "窗口控制程序已启动");
UpdateStatus(L"状态: 程序已初始化");
}
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
OnButtonClick(LOWORD(wParam));
}
break;
case WM_HOTKEY:
if (wParam == HOTKEY_ID) {
Log(LogLevel::LOG_INFO, __LINE__, "全局快捷键 Ctrl+Alt+Z 被触发");
if (g_bSelfHidden) {
ShowWindow(g_hMainWnd, SW_SHOW);
g_bSelfHidden = false;
UpdateStatus(L"状态: 程序已显示");
Log(LogLevel::LOG_INFO, __LINE__, "程序窗口已显示");
}
else {
HideSelf();
}
}
break;
case WM_CLOSE:
UnregisterHotKey(hwnd, HOTKEY_ID); // 注销热键
Log(LogLevel::LOG_INFO, __LINE__, "已注销全局快捷键");
// 清理资源
if (g_bRtlHookEnabled) {
HookRtlWindow(false);
Sleep(500);
}
HookCurWindow(unhideDllName);
CleanupIPC();
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
g_hInst = hInstance;
// 注册窗口类
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = g_szClassName;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"窗口类注册失败!", L"错误", MB_ICONERROR);
return 0;
}
// 创建窗口
g_hMainWnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
g_szTitle,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 700, 450,
NULL, NULL, hInstance, NULL
);
if (!g_hMainWnd) {
MessageBox(NULL, L"窗口创建失败!", L"错误", MB_ICONERROR);
return 0;
}
if (RegisterHotKey(g_hMainWnd, HOTKEY_ID, MOD_CONTROL | MOD_ALT, 0x5A)) { // 0x5A是'Z'键
Log(LogLevel::LOG_INFO, __LINE__, "全局快捷键 Ctrl+Alt+Z 已注册");
g_bHotkeyRegistered = true;
}
else {
DWORD error = GetLastError();
Log(LogLevel::LOG_ERROR, __LINE__, "全局快捷键注册失败: %d", error);
}
ShowWindow(g_hMainWnd, nCmdShow);
UpdateWindow(g_hMainWnd);
// 初始化全局配置(程序启动时调用一次即可)
if (!ConfigManager::initializeGlobalConfig()) {
Log(LogLevel::LOG_WARN, __LINE__, "配置初始化失败,使用默认设置");
}
Log(LogLevel::LOG_INFO, __LINE__, "全局配置初始化完成");
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}