From 261c585be99142ade144ca68586db232463a8724 Mon Sep 17 00:00:00 2001
From: huiyiruciduojiao <17870108997>
Date: Thu, 9 Oct 2025 10:13:44 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=AE=80=E5=8D=95?=
=?UTF-8?q?=E7=9A=84=E5=9B=BE=E5=BD=A2=E5=8C=96=E7=95=8C=E9=9D=A2=E6=93=8D?=
=?UTF-8?q?=E4=BD=9C=E5=92=8C=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=9A=84?=
=?UTF-8?q?=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
AntiScreenCap.sln | 20 +-
AntiScreenCap/AntiScreenCap.vcxproj | 14 +-
AntiScreenCap/AntiScreenCap.vcxproj.filters | 6 +
AntiScreenCap/config_manager.cpp | 377 +++++++++
AntiScreenCap/config_manager.h | 106 +++
AntiScreenCap/hook_current.cpp | 235 ++----
AntiScreenCap/main.cpp | 823 +++++++++++---------
ConfigManager/ConfigManager.cpp | 385 +++++++++
ConfigManager/ConfigManager.h | 107 +++
ConfigManager/ConfigManager.vcxproj | 155 ++++
ConfigManager/ConfigManager.vcxproj.filters | 36 +
ConfigManager/framework.h | 3 +
ConfigManager/pch.cpp | 5 +
ConfigManager/pch.h | 13 +
Hide/Hide.vcxproj | 8 +-
Hide/dllmain.cpp | 12 +-
RtlHook/RtlHook.vcxproj | 13 +-
RtlHook/dllmain.cpp | 250 +++---
UnHide/UnHide.vcxproj | 8 +-
UnHide/dllmain.cpp | 12 +
20 files changed, 1928 insertions(+), 660 deletions(-)
create mode 100644 AntiScreenCap/config_manager.cpp
create mode 100644 AntiScreenCap/config_manager.h
create mode 100644 ConfigManager/ConfigManager.cpp
create mode 100644 ConfigManager/ConfigManager.h
create mode 100644 ConfigManager/ConfigManager.vcxproj
create mode 100644 ConfigManager/ConfigManager.vcxproj.filters
create mode 100644 ConfigManager/framework.h
create mode 100644 ConfigManager/pch.cpp
create mode 100644 ConfigManager/pch.h
diff --git a/AntiScreenCap.sln b/AntiScreenCap.sln
index bc85b5b..30a9200 100644
--- a/AntiScreenCap.sln
+++ b/AntiScreenCap.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.31702.278
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.36221.1 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RtlHide", "RtlHook\RtlHook.vcxproj", "{E91231DC-E9CF-4E12-B0E4-A0C63F7A7E69}"
EndProject
@@ -10,6 +10,14 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnHide", "UnHide\UnHide.vcxproj", "{3566D20B-6C53-4B3B-BC9C-A252486789D5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AntiScreenCap", "AntiScreenCap\AntiScreenCap.vcxproj", "{EC0D81D9-E367-4307-925F-2CF1149B5E57}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3566D20B-6C53-4B3B-BC9C-A252486789D5} = {3566D20B-6C53-4B3B-BC9C-A252486789D5}
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD} = {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}
+ {E91231DC-E9CF-4E12-B0E4-A0C63F7A7E69} = {E91231DC-E9CF-4E12-B0E4-A0C63F7A7E69}
+ {F161A811-6CDA-44DA-8A9E-E463E92A4B80} = {F161A811-6CDA-44DA-8A9E-E463E92A4B80}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConfigManager", "ConfigManager\ConfigManager.vcxproj", "{B5AFEB98-C976-4839-9A8E-4F48B057D7FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -51,6 +59,14 @@ Global
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x64.Build.0 = Release|x64
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x86.ActiveCfg = Release|Win32
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x86.Build.0 = Release|Win32
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Debug|x64.ActiveCfg = Debug|x64
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Debug|x64.Build.0 = Debug|x64
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Debug|x86.ActiveCfg = Debug|Win32
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Debug|x86.Build.0 = Debug|Win32
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Release|x64.ActiveCfg = Release|x64
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Release|x64.Build.0 = Release|x64
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Release|x86.ActiveCfg = Release|Win32
+ {B5AFEB98-C976-4839-9A8E-4F48B057D7FD}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/AntiScreenCap/AntiScreenCap.vcxproj b/AntiScreenCap/AntiScreenCap.vcxproj
index 764d64a..9cb1a30 100644
--- a/AntiScreenCap/AntiScreenCap.vcxproj
+++ b/AntiScreenCap/AntiScreenCap.vcxproj
@@ -19,10 +19,12 @@
+
+
@@ -37,26 +39,26 @@
Application
true
- v142
+ v143
Unicode
Application
false
- v142
+ v143
true
Unicode
Application
true
- v142
+ v143
Unicode
Application
false
- v142
+ v143
true
Unicode
@@ -129,7 +131,7 @@
true
- Console
+ Windows
true
@@ -144,7 +146,7 @@
stdcpp17
- Console
+ Windows
true
true
true
diff --git a/AntiScreenCap/AntiScreenCap.vcxproj.filters b/AntiScreenCap/AntiScreenCap.vcxproj.filters
index 2fd2011..5047139 100644
--- a/AntiScreenCap/AntiScreenCap.vcxproj.filters
+++ b/AntiScreenCap/AntiScreenCap.vcxproj.filters
@@ -21,6 +21,9 @@
头文件
+
+ 头文件
+
@@ -29,5 +32,8 @@
源文件
+
+ 源文件
+
\ No newline at end of file
diff --git a/AntiScreenCap/config_manager.cpp b/AntiScreenCap/config_manager.cpp
new file mode 100644
index 0000000..68af4aa
--- /dev/null
+++ b/AntiScreenCap/config_manager.cpp
@@ -0,0 +1,377 @@
+#include "config_manager.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#pragma comment(lib,"shlwapi.lib")
+
+namespace ConfigManager {
+
+ // ProcessFilterConfig ʵ
+ void ProcessFilterConfig::clear() {
+ processList.clear();
+ mode = WHITELIST;
+ caseSensitive = false;
+ }
+
+ // Config ʵ
+ Config::Config() {
+ m_configFilePath = getDefaultConfigPath();
+ }
+
+ Config::Config(const std::string& configPath) : m_configFilePath(configPath) {
+ }
+
+ std::string Config::toLowerCase(const std::string& str) const {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), ::tolower);
+ return result;
+ }
+
+ std::string Config::trim(const std::string& str) const {
+ size_t start = str.find_first_not_of(" \t\r\n");
+ if (start == std::string::npos) return "";
+ size_t end = str.find_last_not_of(" \t\r\n");
+ return str.substr(start, end - start + 1);
+ }
+
+ bool Config::fileExists(const std::string& filePath) const {
+ return GetFileAttributesA(filePath.c_str()) != INVALID_FILE_ATTRIBUTES;
+ }
+
+ void Config::setConfigPath(const std::string& configPath) {
+ m_configFilePath = configPath;
+ }
+
+ std::string Config::getConfigPath() const {
+ return m_configFilePath;
+ }
+
+ std::string Config::getDefaultConfigPath() const {
+ char exePath[MAX_PATH] = { 0 };
+ GetModuleFileNameA(NULL, exePath, MAX_PATH);
+ PathRemoveFileSpecA(exePath);
+ PathAppendA(exePath, "process_filter.ini");
+ return std::string(exePath);
+ }
+
+ bool Config::loadConfig() {
+ return loadConfig(m_configFilePath);
+ }
+
+ bool Config::loadConfig(const std::string& configPath) {
+ m_filterConfig.clear();
+
+ std::ifstream configFile(configPath);
+ if (!configFile.is_open()) {
+ std::cerr << "Warning: ļ: " << configPath << std::endl;
+ return false;
+ }
+
+ std::string line;
+ bool inProcessSection = false;
+
+ std::cout << "Info: ʼȡļ: " << configPath << std::endl;
+
+ while (std::getline(configFile, line)) {
+ line = trim(line);
+
+ // кע
+ if (line.empty() || line.front() == '#' || line.front() == ';') {
+ continue;
+ }
+
+ // Ƿǽڱ
+ if (line.front() == '[' && line.back() == ']') {
+ std::string section = line.substr(1, line.length() - 2);
+ section = trim(section);
+ inProcessSection = (toLowerCase(section) == "process");
+ continue;
+ }
+
+ if (!inProcessSection) {
+ continue;
+ }
+
+ //
+ size_t equalPos = line.find('=');
+ if (equalPos == std::string::npos) {
+ continue;
+ }
+
+ std::string key = trim(line.substr(0, equalPos));
+ std::string value = trim(line.substr(equalPos + 1));
+
+ key = toLowerCase(key);
+
+ if (key == "mode") {
+ value = toLowerCase(value);
+ if (value == "whitelist" || value == "white") {
+ m_filterConfig.mode = ProcessFilterConfig::WHITELIST;
+ std::cout << "Info: Ϊģʽ" << std::endl;
+ }
+ else if (value == "blacklist" || value == "black") {
+ m_filterConfig.mode = ProcessFilterConfig::BLACKLIST;
+ std::cout << "Info: Ϊģʽ" << std::endl;
+ }
+ }
+ else if (key == "casesensitive") {
+ value = toLowerCase(value);
+ m_filterConfig.caseSensitive = (value == "true" || value == "1" || value == "yes");
+ std::cout << "Info: Сд: " << (m_filterConfig.caseSensitive ? "" : "ر") << std::endl;
+ }
+ else if (key == "list") {
+ // бֶ֧ŷָ
+ std::stringstream ss(value);
+ std::string processName;
+ while (std::getline(ss, processName, ',')) {
+ processName = trim(processName);
+ if (!processName.empty()) {
+ if (!m_filterConfig.caseSensitive) {
+ processName = toLowerCase(processName);
+ }
+ m_filterConfig.processList.insert(processName);
+ std::cout << "Info: ӽ: " << processName << std::endl;
+ }
+ }
+ }
+ }
+
+ configFile.close();
+
+ std::cout << "Info: ļɣ " << m_filterConfig.processList.size() << " " << std::endl;
+ return true;
+ }
+
+ bool Config::saveDefaultConfig() const {
+ return saveDefaultConfig(m_configFilePath);
+ }
+
+ bool Config::saveDefaultConfig(const std::string& configPath) const {
+ std::ofstream configFile(configPath);
+ if (!configFile.is_open()) {
+ std::cerr << "Error: ļ: " << configPath << std::endl;
+ return false;
+ }
+
+ configFile << "# ̹ļ\n";
+ configFile << "# ֵ֧\n";
+ configFile << "# mode: whitelist() blacklist()\n";
+ configFile << "# casesensitive: true(Сд) false(Сд)\n";
+ configFile << "# list: бöŷָ\n\n";
+
+ configFile << "[Process]\n";
+ configFile << "# ģʽ: whitelist(ֻбеĽ) blacklist(бĽ)\n";
+ configFile << "mode = whitelist\n\n";
+
+ configFile << "# ǷСд\n";
+ configFile << "casesensitive = false\n\n";
+
+ configFile << "# б.exeöŷָ\n";
+ configFile << "list = chrome.exe, msedge.exe, mstsc.exe, notepad.exe, calc.exe\n\n";
+
+ configFile << "# ʾã\n";
+ configFile << "# mode = blacklist\n";
+ configFile << "# list = explorer.exe, winlogon.exe, csrss.exe, smss.exe\n";
+
+ configFile.close();
+
+ std::cout << "Info: ĬļѴ: " << configPath << std::endl;
+ return true;
+ }
+
+ bool Config::reloadConfig() {
+ // ļڣĬ
+ if (!fileExists(m_configFilePath)) {
+ std::cout << "Warning: ļڣĬ" << std::endl;
+ if (!saveDefaultConfig()) {
+ return false;
+ }
+ }
+
+ return loadConfig();
+ }
+
+ const ProcessFilterConfig& Config::getProcessFilterConfig() const {
+ return m_filterConfig;
+ }
+
+ ProcessFilterConfig& Config::getProcessFilterConfig() {
+ return m_filterConfig;
+ }
+
+ bool Config::shouldProcessBeHooked(const std::string& processName) const {
+ if (m_filterConfig.processList.empty()) {
+ // ûãʹĬΪ
+ return true;
+ }
+
+ std::string nameToCheck = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToCheck = toLowerCase(processName);
+ }
+
+ bool inList = m_filterConfig.processList.find(nameToCheck) != m_filterConfig.processList.end();
+
+ if (m_filterConfig.mode == ProcessFilterConfig::WHITELIST) {
+ return inList; // ģʽֻбеĽ
+ }
+ else {
+ return !inList; // ģʽбĽ
+ }
+ }
+
+ void Config::setFilterMode(ProcessFilterConfig::FilterMode mode) {
+ m_filterConfig.mode = mode;
+ }
+
+ ProcessFilterConfig::FilterMode Config::getFilterMode() const {
+ return m_filterConfig.mode;
+ }
+
+ void Config::setCaseSensitive(bool sensitive) {
+ m_filterConfig.caseSensitive = sensitive;
+ }
+
+ bool Config::isCaseSensitive() const {
+ return m_filterConfig.caseSensitive;
+ }
+
+ void Config::addProcess(const std::string& processName) {
+ std::string nameToAdd = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToAdd = toLowerCase(processName);
+ }
+ m_filterConfig.processList.insert(nameToAdd);
+ }
+
+ void Config::removeProcess(const std::string& processName) {
+ std::string nameToRemove = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToRemove = toLowerCase(processName);
+ }
+ m_filterConfig.processList.erase(nameToRemove);
+ }
+
+ void Config::clearProcessList() {
+ m_filterConfig.processList.clear();
+ }
+
+ std::vector Config::getProcessList() const {
+ std::vector result;
+ result.reserve(m_filterConfig.processList.size());
+ for (const auto& process : m_filterConfig.processList) {
+ result.push_back(process);
+ }
+ return result;
+ }
+
+ size_t Config::getProcessCount() const {
+ return m_filterConfig.processList.size();
+ }
+
+ bool Config::isConfigValid() const {
+ return !m_configFilePath.empty();
+ }
+
+ void Config::printConfig() const {
+ std::cout << "=== Ϣ ===" << std::endl;
+ std::cout << "ļ·: " << m_configFilePath << std::endl;
+ std::cout << "ģʽ: " << (m_filterConfig.mode == ProcessFilterConfig::WHITELIST ? "" : "") << std::endl;
+ std::cout << "Сд: " << (m_filterConfig.caseSensitive ? "" : "") << std::endl;
+ std::cout << "б (" << m_filterConfig.processList.size() << "):" << std::endl;
+ for (const auto& process : m_filterConfig.processList) {
+ std::cout << " - " << process << std::endl;
+ }
+ std::cout << "================" << std::endl;
+ }
+
+ // GlobalConfig ̬Աʼ
+ Config* GlobalConfig::s_instance = nullptr;
+ bool GlobalConfig::s_initialized = false;
+
+ bool GlobalConfig::initialize() {
+ if (s_initialized) {
+ return true;
+ }
+
+ s_instance = new Config();
+ s_initialized = s_instance->reloadConfig();
+
+ if (!s_initialized) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+
+ return s_initialized;
+ }
+
+ bool GlobalConfig::initialize(const std::string& configPath) {
+ if (s_initialized) {
+ return true;
+ }
+
+ s_instance = new Config(configPath);
+ s_initialized = s_instance->reloadConfig();
+
+ if (!s_initialized) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+
+ return s_initialized;
+ }
+
+ void GlobalConfig::cleanup() {
+ if (s_instance) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+ s_initialized = false;
+ }
+
+ Config* GlobalConfig::getInstance() {
+ return s_instance;
+ }
+
+ bool GlobalConfig::isInitialized() {
+ return s_initialized;
+ }
+
+ // ݺʵ
+ bool initializeGlobalConfig() {
+ return GlobalConfig::initialize();
+ }
+
+ bool initializeGlobalConfig(const std::string& configPath) {
+ return GlobalConfig::initialize(configPath);
+ }
+
+ Config* getGlobalConfig() {
+ return GlobalConfig::getInstance();
+ }
+
+ void cleanupGlobalConfig() {
+ GlobalConfig::cleanup();
+ }
+
+ bool shouldProcessBeHooked(const std::string& processName) {
+ Config* config = GlobalConfig::getInstance();
+ if (!config) {
+ return true; // ĬΪ
+ }
+ return config->shouldProcessBeHooked(processName);
+ }
+
+ bool reloadGlobalConfig() {
+ Config* config = GlobalConfig::getInstance();
+ if (!config) {
+ return false;
+ }
+ return config->reloadConfig();
+ }
+
+} // namespace ConfigManager
\ No newline at end of file
diff --git a/AntiScreenCap/config_manager.h b/AntiScreenCap/config_manager.h
new file mode 100644
index 0000000..96718e3
--- /dev/null
+++ b/AntiScreenCap/config_manager.h
@@ -0,0 +1,106 @@
+#pragma once
+
+#include
+#include
+#include
+
+/**
+ * ù - ڹ̹˺ѡ
+ */
+namespace ConfigManager {
+
+ // ̹ýṹ
+ struct ProcessFilterConfig {
+ enum FilterMode {
+ WHITELIST, // ģʽֻбеĽ
+ BLACKLIST // ģʽбĽ
+ };
+
+ FilterMode mode = WHITELIST;
+ std::unordered_set processList;
+ bool caseSensitive = false;
+
+ void clear();
+ };
+
+ // ù
+ class Config {
+ private:
+ ProcessFilterConfig m_filterConfig;
+ std::string m_configFilePath;
+
+ // ߺ
+ std::string toLowerCase(const std::string& str) const;
+ std::string trim(const std::string& str) const;
+ bool fileExists(const std::string& filePath) const;
+
+ public:
+ Config();
+ explicit Config(const std::string& configPath);
+ ~Config() = default;
+
+ // ļ·
+ void setConfigPath(const std::string& configPath);
+ std::string getConfigPath() const;
+ std::string getDefaultConfigPath() const;
+
+ // üغͱ
+ bool loadConfig();
+ bool loadConfig(const std::string& configPath);
+ bool saveDefaultConfig() const;
+ bool saveDefaultConfig(const std::string& configPath) const;
+ bool reloadConfig();
+
+ // ̹÷
+ const ProcessFilterConfig& getProcessFilterConfig() const;
+ ProcessFilterConfig& getProcessFilterConfig();
+
+ // ̹ط
+ bool shouldProcessBeHooked(const std::string& processName) const;
+ void setFilterMode(ProcessFilterConfig::FilterMode mode);
+ ProcessFilterConfig::FilterMode getFilterMode() const;
+ void setCaseSensitive(bool sensitive);
+ bool isCaseSensitive() const;
+
+ // б
+ void addProcess(const std::string& processName);
+ void removeProcess(const std::string& processName);
+ void clearProcessList();
+ std::vector getProcessList() const;
+ size_t getProcessCount() const;
+
+ // ֤
+ bool isConfigValid() const;
+
+ // Ϣ
+ void printConfig() const;
+ };
+
+ // ȫʵ
+ class GlobalConfig {
+ private:
+ static Config* s_instance;
+ static bool s_initialized;
+
+ public:
+ static bool initialize();
+ static bool initialize(const std::string& configPath);
+ static void cleanup();
+ static Config* getInstance();
+ static bool isInitialized();
+ };
+
+ // ݺ
+ bool initializeGlobalConfig();
+ bool initializeGlobalConfig(const std::string& configPath);
+ Config* getGlobalConfig();
+ void cleanupGlobalConfig();
+
+ // ֱӲȫõıݺ
+ bool shouldProcessBeHooked(const std::string& processName);
+ bool reloadGlobalConfig();
+}
+
+// Ժ궨
+#define PROCESS_FILTER_WHITELIST ConfigManager::ProcessFilterConfig::WHITELIST
+#define PROCESS_FILTER_BLACKLIST ConfigManager::ProcessFilterConfig::BLACKLIST
\ No newline at end of file
diff --git a/AntiScreenCap/hook_current.cpp b/AntiScreenCap/hook_current.cpp
index 43372f3..a4122f7 100644
--- a/AntiScreenCap/hook_current.cpp
+++ b/AntiScreenCap/hook_current.cpp
@@ -1,6 +1,7 @@
#define _CRT_SECURE_NO_WARNINGS
#include "main.h"
+#include "config_manager.h"
#include "hook_current.h"
#include
#include
@@ -10,12 +11,15 @@
#include
#include
#include
+#include
#include
#include
+#include
+#include
+#include
#pragma comment(lib,"shlwapi.lib")
using namespace std;
-
bool Is64BitOS()
{
SYSTEM_INFO sysInfo = { 0 };
@@ -52,11 +56,11 @@ unordered_map getSuspendProcess()
);
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
- LPVOID dwBufferProcess = 0; //ݵĻ
- DWORD dwBufferProcessSize = 0; //ҪյݵĻС
+ LPVOID dwBufferProcess = 0;
+ DWORD dwBufferProcessSize = 0;
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
- dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000](); //Ϊ˷ֹ/߳Ϣͻ䣬0x10000ڴ(64K)
- LPVOID dwOldBufferProcess = dwBufferProcess; //滺ַ
+ dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000]();
+ LPVOID dwOldBufferProcess = dwBufferProcess;
NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
while (TRUE)
@@ -68,87 +72,29 @@ unordered_map getSuspendProcess()
int suspendThreads = 0;
for (DWORD i = 0; i < processInfo->NumberOfThreads; i++)
{
- //״̬͵´״̬ԭ
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
{
suspendThreads++;
}
- dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION); //ָ˽̵һ߳̽ṹ
+ dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION);
}
if (suspendThreads == processInfo->NumberOfThreads)
{
wstring wstrName{ processInfo->ImageName.Buffer };
suspendProcess[(DWORD)(processInfo->UniqueProcessId)] = string(wstrName.begin(), wstrName.end());
}
- dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset); //ָһ
- if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0) //ɽ
+ dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset);
+ if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0)
break;
}
- delete[] dwOldBufferProcess; //ͷڴ
+ delete[] dwOldBufferProcess;
return suspendProcess;
}
-struct ProcessInfo
-{
- string name;
- bool isSuspend;
-};
-
-unordered_map getProcessInfo()
-{
- unordered_map processInfoMap;
- typedef NTSTATUS(NTAPI* pfnNtQuerySystemInformation)(
- IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength OPTIONAL
- );
- pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
-
- LPVOID dwBufferProcess = 0; //ݵĻ
- DWORD dwBufferProcessSize = 0; //ҪյݵĻС
- NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
- dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000](); //Ϊ˷ֹ/߳Ϣͻ䣬0x10000ڴ(64K)
- LPVOID dwOldBufferProcess = dwBufferProcess; //滺ַ
- NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
-
- while (TRUE)
- {
- LPVOID dwAddress = dwBufferProcess;
- dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_PROCESS_INFORMATION);
- PSYSTEM_PROCESS_INFORMATION processInfo = (PSYSTEM_PROCESS_INFORMATION)dwAddress;
-
- int suspendThreads = 0;
- for (DWORD i = 0; i < processInfo->NumberOfThreads; i++)
- {
- //״̬͵´״̬ԭ
- if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
- {
- suspendThreads++;
- }
- dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION); //ָ˽̵һ߳̽ṹ
- }
-
- if ((DWORD)(processInfo->UniqueProcessId) > 0)
- {
- wstring wstrName = processInfo->ImageName.Buffer;
- bool isSuspend = (suspendThreads == processInfo->NumberOfThreads);
- processInfoMap[(DWORD)(processInfo->UniqueProcessId)] = { string(wstrName.begin(), wstrName.end()), isSuspend };
- }
-
- dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset); //ָһ
- if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0) //ɽ
- break;
- }
- delete[] dwOldBufferProcess; //ͷڴ
- return processInfoMap;
-}
-
bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
{
int pathSize = (wcslen(pszDllFileName) + 1) * sizeof(wchar_t);
- // 2.Ŀռ
LPVOID lpPathAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (NULL == lpPathAddr)
{
@@ -156,14 +102,14 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
CloseHandle(hProcess);
return false;
}
- // 3.ĿдDll·
- if (FALSE == WriteProcessMemory(hProcess, lpPathAddr, pszDllFileName, pathSize, NULL)) // ʵдС
+
+ if (FALSE == WriteProcessMemory(hProcess, lpPathAddr, pszDllFileName, pathSize, NULL))
{
Log(LogLevel::LOG_ERROR, __LINE__, "ĿдDll·ʧܣ%d", GetLastError());
CloseHandle(hProcess);
return false;
}
- // 4.ntdll.dll
+
HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
if (NULL == hNtdll)
{
@@ -171,8 +117,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
CloseHandle(hProcess);
return false;
}
- // 5.ȡLoadLibraryAĺַ
- // FARPROCӦ32λ64λ
+
HMODULE hmKernel32 = LoadLibrary(_T("Kernel32.dll"));
if (NULL == hmKernel32)
{
@@ -187,8 +132,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
CloseHandle(hProcess);
return false;
}
- // 6.ȡZwCreateThreadExַ,ú32λ64λԭͲͬ
- // _WIN64жϱ뻷_WIN32жǷWindowsϵͳ
+
#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
@@ -225,7 +169,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
CloseHandle(hProcess);
return false;
}
- // 7.ĿдԶ߳
+
HANDLE hRemoteThread = NULL;
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
hProcess, (LPTHREAD_START_ROUTINE)pFuncProcAddr, lpPathAddr, 0, 0, 0, 0, NULL);
@@ -235,99 +179,49 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
CloseHandle(hProcess);
return false;
}
- // 8.ȴ߳̽
+
DWORD reason = WaitForSingleObject(hRemoteThread, INFINITE);
- /*if (reason == WAIT_TIMEOUT)
- {
- if (string name = getProcNameByHandle(hProcess); !name.empty())
- Log(LogLevel::LOG_WARN, __LINE__, "WaitForRemoteThreadExit TIMEOUT(2s), Process May Be Suspend: %s", name.c_str());
- else
- Log(LogLevel::LOG_WARN, __LINE__, "WaitForRemoteThreadExit TIMEOUT(2s), Process May Be Suspend: %d", GetProcessId(hProcess));
- }*/
- // 9.
- VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE); //MEM_RELEASE
+
+ VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
FreeLibrary(hNtdll);
return true;
}
-//bool HookCurWindow(const std::wstring& dllPath)
-//{
-// Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOWS<<<<<<<<<<<<<<<<");
-// std::wstring DllPath{ getFullFilePath(dllPath) };
-// COND_LOG_RET(!DllPath.empty(), __LINE__, "DllPath.empty(): %d", GetLastError(), false);
-//
-// unordered_map processInfoMap = getProcessInfo();
-// for (auto i : processInfoMap)
-// {
-// Log(LogLevel::LOG_INFO, __LINE__, "Ready To Inject: %s", i.second.name.c_str());
-// if (i.second.isSuspend)
-// {
-// Log(LogLevel::LOG_WARN, __LINE__, "This is a suspend process: %s", i.second.name.c_str());
-// continue;
-// }
-// // 1.Ŀ, øOpenProcess API, CSRSS
-// HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, i.first);
-// if (hProcess) {
-// BOOL procIs32bit;
-// /*64-bit process on 64-bit Windows : FALSE
-// 32-bit process on 64-bit Windows : TRUE
-// 32-bit process on 32-bit Windows : FALSE*/
-// if (IsWow64Process(hProcess, &procIs32bit)) {
-//#ifdef _WIN64
-// if (!procIs32bit && is64BitOS) {
-// if (ZwCreateThreadExInjectDll(hProcess, DllPath.c_str())) {
-// Log(LogLevel::LOG_INFO, __LINE__, "Hook Window Success: %s", i.second.name.c_str());
-// }
-// else {
-// Log(LogLevel::LOG_WARN, __LINE__, "Hook Window Failed: %s", i.second.name.c_str());
-// }
-// }
-// else {
-// Log(LogLevel::LOG_WARN, __LINE__, "It's a 32 app: %s", i.second.name.c_str());
-// }
-//#else
-// if (procIs32bit || (!procIs32bit && !is64BitOS)) {
-// if (ZwCreateThreadExInjectDll(hProcess, DllPath.c_str())) {
-// Log(LogLevel::LOG_INFO, __LINE__, "Hook Window Success: %s", i.second.name.c_str());
-// }
-// else {
-// Log(LogLevel::LOG_WARN, __LINE__, "Hook Window Failed: %s", i.second.name.c_str());
-// }
-// }
-// else {
-// Log(LogLevel::LOG_WARN, __LINE__, "It's a 64 app: %s", i.second.name.c_str());
-// }
-//#endif
-// }
-// else {
-// Log(LogLevel::LOG_ERROR, __LINE__, "жĿǷ64λϵͳе32λʧ: %d", GetLastError());
-// continue;
-// }
-// }
-// else {
-// Log(LogLevel::LOG_WARN, __LINE__, "Ŀ: %s, ʧ: %d", i.second.name.c_str(), GetLastError());
-// continue;
-// }
-// }
-// Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOW END<<<<<<<<<<<<<<<<<<");
-// return true;
-//}
-
bool HookCurWindow(const std::wstring& dllPath)
{
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOWS<<<<<<<<<<<<<<<<");
- std::wstring DllPath{ getFullFilePath(dllPath) };
- COND_LOG_RET(!DllPath.empty(), __LINE__, "DllPath.empty(): %d", GetLastError(), false);
+
+
+ // ¼ļ
+ if (!ConfigManager::reloadGlobalConfig()) {
+ Log(LogLevel::LOG_WARN, __LINE__, "ļʧܣʹĬ");
+ }
+
+ // ӡǰϢã
+ ConfigManager::Config* config = ConfigManager::getGlobalConfig();
+ if (config) {
+ config->printConfig();
+ }
+
+ std::wstring DllPath{ getFullFilePath(dllPath) };
+ if (DllPath.empty()) {
+ Log(LogLevel::LOG_ERROR, __LINE__, "DLL·ȡʧ: %d", GetLastError());
+ return false;
+ }
+
unordered_map suspendProc = getSuspendProcess();
for (auto i : suspendProc)
{
Log(LogLevel::LOG_INFO, __LINE__, "suspend process: %s", i.second.c_str());
}
- unordered_map tryHookedProc;//עPID
- vector goodHookedProc;//ɹhookĽ
+
+ unordered_map tryHookedProc;
+ vector goodHookedProc;
+ vector filteredProc; // ˵Ľ
+
HWND windowHandle = NULL;
do {
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
@@ -335,23 +229,30 @@ bool HookCurWindow(const std::wstring& dllPath)
if (GetWindowThreadProcessId(windowHandle, &dwPid)) {
if (tryHookedProc.find(dwPid) == tryHookedProc.end()) {
tryHookedProc[dwPid] = 1;
-
+
if (suspendProc.find(dwPid) != suspendProc.end())
{
Log(LogLevel::LOG_WARN, __LINE__, "This is a suspend process: %s", suspendProc[dwPid].c_str());
continue;
}
- // 0.Ȩ
- // 1.Ŀ, øOpenProcess API
+
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess) {
string exeName = getProcNameByHandle(hProcess);
- exeName = (!exeName.empty() ? exeName : "Unknow ProcName");
-
+ exeName = (!exeName.empty() ? exeName : "Unknown ProcName");
+
+ // ʹµĹ
+ if (!ConfigManager::shouldProcessBeHooked(exeName)) {
+ ConfigManager::Config* cfg = ConfigManager::getGlobalConfig();
+ Log(LogLevel::LOG_INFO, __LINE__, "̱: %s (ģʽ: %s)",
+ exeName.c_str(),
+ cfg && cfg->getFilterMode() == ConfigManager::ProcessFilterConfig::WHITELIST ? "" : "");
+ filteredProc.push_back(exeName);
+ CloseHandle(hProcess);
+ continue;
+ }
+
BOOL procIs32bit;
- /*64-bit process on 64-bit Windows : FALSE
- 32-bit process on 64-bit Windows : TRUE
- 32-bit process on 32-bit Windows : FALSE*/
if (IsWow64Process(hProcess, &procIs32bit)) {
#ifdef _WIN64
if (!procIs32bit && is64BitOS) {
@@ -379,7 +280,6 @@ bool HookCurWindow(const std::wstring& dllPath)
Log(LogLevel::LOG_WARN, __LINE__, "It's a 64 app: %s", exeName.c_str());
}
#endif
-
}
else {
Log(LogLevel::LOG_ERROR, __LINE__, "жĿǷ64λϵͳе32λʧ: %d", GetLastError());
@@ -391,21 +291,24 @@ bool HookCurWindow(const std::wstring& dllPath)
continue;
}
}
- else {
- //cout << "ע" << endl;
- continue;
- }
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "GetWindowThreadProcessId Error%d, HWND: %x", GetLastError(), windowHandle);
}
} while (windowHandle);
+
//Summary
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOW END<<<<<<<<<<<<<<<<<<");
Log(LogLevel::LOG_INFO, __LINE__, "Summary:");
+ Log(LogLevel::LOG_INFO, __LINE__, "ɹHookĽ (%zu):", goodHookedProc.size());
for (auto& i : goodHookedProc)
{
- Log(LogLevel::LOG_INFO, __LINE__, i.c_str());
+ Log(LogLevel::LOG_INFO, __LINE__, " - %s", i.c_str());
}
+
+ if (!filteredProc.empty()) {
+ Log(LogLevel::LOG_INFO, __LINE__, "˵Ľ (%zu):", filteredProc.size());
+ }
+
return true;
}
\ No newline at end of file
diff --git a/AntiScreenCap/main.cpp b/AntiScreenCap/main.cpp
index 637751e..5bcf941 100644
--- a/AntiScreenCap/main.cpp
+++ b/AntiScreenCap/main.cpp
@@ -4,12 +4,40 @@
#include "main.h"
#include
#include
-#include
#include
#include
+#include
+#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;
@@ -19,14 +47,11 @@ const int LOG_SIZE = 512;
//for ipc
char* pBuf;
HANDLE hServerEvent, hClientEvent, hFileMap;
-//for save console origin color
-WORD wOldColorAttrs;
-
#ifdef _WIN64
const std::wstring hideDllName{ L"Hide.dll" };
const std::wstring unhideDllName{ L"Unhide.dll" };
-const std::wstring RtlHideDllName{L"RtlHide.dll"};
+const std::wstring RtlHideDllName{ L"RtlHide.dll" };
#else
const std::wstring hideDllName{ L"Hide32.dll" };
const std::wstring unhideDllName{ L"Unhide32.dll" };
@@ -34,8 +59,8 @@ 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);
+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
@@ -44,395 +69,451 @@ HMODULE hUser32 = LoadLibraryA("user32.dll");
#define MessageBoxTimeout ((MessageBoxTimeoutA)(GetProcAddress(hUser32, "MessageBoxTimeoutA")))
#endif
-BOOL WINAPI ConsoleHandler(DWORD CEvent)
-{
- switch (CEvent)
- {
- case CTRL_CLOSE_EVENT://close消息有限时机制
- HookRtlWindow(false);
- MessageBoxTimeout(NULL, L"关闭实时窗口注入", L"step 1", MB_OK, 0, 1000);//MessageBox(NULL, L"关闭实时窗口注入", L"step 1", MB_OK);
- Sleep(1500);
- HookCurWindow(unhideDllName);
- MessageBox(NULL, L"还原当前所有窗口", L"step 2", MB_OK);//MessageBoxTimeout(NULL, L"还原当前所有窗口", L"step 2", MB_OK, 0, 1500);
- break;
- case CTRL_C_EVENT:
- ShowWindow(GetConsoleWindow(), SW_HIDE);
- break;
- case CTRL_BREAK_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- default:
- return FALSE;
- }
- return TRUE;
+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);
}
-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;
+// 更新状态文本
+void UpdateStatus(const wchar_t* status) {
+ if (g_hStatusText) {
+ SetWindowText(g_hStatusText, status);
+ }
}
-bool initFoundSet()
-{
- SetPrivilege();
-
- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
- HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE);
- HANDLE_LOG_RET(hStd, __LINE__, "GetStdHandle: %x", hStd, false);
- COND_LOG_RET(GetConsoleScreenBufferInfo(hStd, &csbiInfo), __LINE__, "GetConsoleScreenBufferInfo: %x", csbiInfo.wAttributes, false);
- wOldColorAttrs = csbiInfo.wAttributes;
-
- COND_LOG_RET(SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE), __LINE__, "SetConsoleCtrlHandler: %x", ConsoleHandler, false);
- return true;
+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;
}
-void SetConsoleColor(WORD wAttributes)
-{
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //获取缓冲区句柄
- if (wAttributes == 0)
- SetConsoleTextAttribute(hCon, wOldColorAttrs);
- else
- SetConsoleTextAttribute(hCon, wAttributes);
-}
-
-void Log(LogLevel level, int line, const char* format, ...)
-{
- char msg[LOG_SIZE] = {0};
-
- va_list ap;
- int ret = -1;
- va_start(ap, format);
- ret = vsprintf(msg, format, ap);
- va_end(ap);
-
- switch (level)
- {
- case LogLevel::LOG_INFO:
- cout << msg << endl;
- break;
- case LogLevel::LOG_WARN:
- SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- cout << "[Line " << line << "] " << msg << endl;
- SetConsoleColor(0);
- break;
- case LogLevel::LOG_ERROR:
- SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY);
- cout << "[Line " << line << "] " << msg << endl;
- SetConsoleColor(0);
- break;
-
- default:
- SetConsoleColor(FOREGROUND_BLUE | FOREGROUND_INTENSITY);
- cout << "No this LOG_LEVEL" << endl;
- SetConsoleColor(0);
- break;
- }
-}
-
-//bool Exec(const wstring& fullPath, const wstring& param, DWORD dwMilliseconds)
-//{
-// SHELLEXECUTEINFO ShExecInfo = { 0 };
-// {
-// ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI | SEE_MASK_NO_CONSOLE;
-// ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); //结构大小
-// ShExecInfo.lpVerb = _T("runas"); //指定该函数的执行动作,以管理员方式运行
-// ShExecInfo.nShow = SW_HIDE; //隐藏窗口
-// ShExecInfo.lpFile = fullPath.c_str(); //卸载程序路径
-// ShExecInfo.lpParameters = param.c_str(); //卸载程序参数
-// }
-// if (ShellExecuteEx(&ShExecInfo))
-// {
-// if (ShExecInfo.hProcess)
-// {
-// switch (WaitForSingleObject(ShExecInfo.hProcess, dwMilliseconds))
-// {
-// case WAIT_OBJECT_0: //The state of the specified object is signaled.
-// LogW(LogLevel::LOG_INFO, __LINE__, L"执行程序%s成功", fullPath);
-// return true;
-// case WAIT_TIMEOUT: //The time-out interval elapsed, and the object's state is nonsignaled.
-// LogW(LogLevel::LOG_ERROR, __LINE__, L"执行程序%s超时", fullPath);
-// break;
-// case WAIT_FAILED: //Waiting on an invalid handle causes WaitForSingleObject to return WAIT_FAILED.
-// LogW(LogLevel::LOG_ERROR, __LINE__, L"执行程序%s错误: %d", fullPath, GetLastError());
-// break;
-// }
-// }
-// else
-// {
-// LogW(LogLevel::LOG_ERROR, __LINE__, L"执行程序%s句柄异常: %d", fullPath, GetLastError());
-// }
-// }
-// else
-// {
-// LogW(LogLevel::LOG_ERROR, __LINE__, L"执行程序%s失败: %d", fullPath, GetLastError());
-// }
-// return false;
-//}
-
-bool FileExists(std::wstring& filePath)
-{
- DWORD dwAttrib = GetFileAttributes(filePath.c_str());
- return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
- !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
+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 };
- COND_LOG_RET(FileExists(strFullPath), __LINE__, "FileExists: %S", strFullPath.c_str(), std::wstring{});
- return strFullPath;
-};
+ 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;
+ }
-bool HookRtlWindow(bool hook)
-{
- if (HMODULE RtlHideDll = LoadLibrary(RtlHideDllName.c_str()); RtlHideDll)
- {
#ifdef _WIN64
- SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "SetHook");
+ SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "SetHook");
#else
- SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "_SetHook@4");
+ SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "_SetHook@4");
#endif
- if (SetHook)
- {
- if (hook)
- {
- if (SetHook(TRUE))
- {
- Log(LogLevel::LOG_INFO, __LINE__, "Set Hook Success");
- 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");
- return true;
- }
- else
- {
- Log(LogLevel::LOG_ERROR, __LINE__, "Set Unhook Error. See More in DebugView");
- }
- }
-
- }
- else
- {
- Log(LogLevel::LOG_ERROR, __LINE__, "GetProcAddress SetHook Error: %d", GetLastError());
- }
- }
- else
- {
- Log(LogLevel::LOG_ERROR, __LINE__, "LoadLibrary %S Error: %d", RtlHideDllName.c_str(), GetLastError());
- }
- return false;
+
+ 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__, "程序窗口已隐藏");
+ }
}
-struct HandleName
-{
- HANDLE handle;
- string name;
-};
-struct ShareMemory {
- HANDLE hFileMap;
- char* pShareBuf;
- void clear() {
- if (pShareBuf) UnmapViewOfFile(pShareBuf);
- CloseHandle(hFileMap);
- }
-};
-struct IPC {
- IPC(string fullName, int bufSize = 32, DWORD ms = 5000) :
- sFullExeName(fullName), iBufSize(bufSize), dwMilliseconds(ms) {}
- void clear() {
- fileMap.clear();
- CloseHandle(serverEvent.handle);
- CloseHandle(clientEvent.handle);
- }
- const string sFullExeName;
- HandleName serverEvent, clientEvent;
- //HandleName fileMap;
- ShareMemory fileMap;
- DWORD dwMilliseconds;
- const int iBufSize;
- string sCmd;
-};
-
-bool __SetEvent(HANDLE hEvent)
-{
- return SetEvent(hEvent);
-}
-bool __SetEvent(const string& eventName)
-{
- HANDLE hEvent = OpenEventA(SYNCHRONIZE, FALSE, eventName.c_str());
- return hEvent && __SetEvent(hEvent);
-}
-bool __GetEvent(HANDLE hEvent, DWORD dwMilliseconds)
-{
- switch (WaitForSingleObject(hEvent, dwMilliseconds)) //同步等待事件受信
- {
- case WAIT_OBJECT_0: //The state of the specified object is signaled.
- Log(LogLevel::LOG_INFO, __LINE__, "等待事件受信成功(lim:%dms): %x", dwMilliseconds, hEvent);
- return true;
- case WAIT_TIMEOUT: //The time-out interval elapsed, and the object's state is nonsignaled.
- Log(LogLevel::LOG_INFO, __LINE__, "等待事件受信超时(lim:%dms): %x", dwMilliseconds, hEvent);
- return false;
- case WAIT_FAILED: //Waiting on an invalid handle causes WaitForSingleObject to return WAIT_FAILED.
- Log(LogLevel::LOG_INFO, __LINE__, "等待事件受信失败: %d", GetLastError());
- return false;
- default:
- break;
- }
- return false;
-}
-bool __GetEvent(const string& eventName, DWORD dwMilliseconds)
-{
- HANDLE hEvent = OpenEventA(SYNCHRONIZE, FALSE, eventName.c_str());
- return hEvent && __GetEvent(hEvent, dwMilliseconds);
+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 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()
+ );
}
-HANDLE CreateGlobalFileMap(string& fileMapName)
-{
- if (fileMapName.find("Global\\") == fileMapName.npos)
- {
- fileMapName = "Global\\" + fileMapName;
- }
- return CreateFileMappingA(
- INVALID_HANDLE_VALUE, //物理文件句柄,设为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;
}
-bool initIPCEnvironment()
-{
- string baseName = to_string(GetCurrentProcessId());
- string serverEventName = baseName + "-ServerEvent";
- string clientEventName = baseName + "-ClientEvent";
- string fileMapName = baseName + "-FileMap";
- //服务端信号
- hServerEvent = CreateGlobalEvent(serverEventName);
- COND_LOG_RET(hServerEvent, __LINE__, "CreateGlobalEvent: %s", serverEventName.c_str(), 1);
- //客户端信号
- hClientEvent = CreateGlobalEvent(clientEventName);
- COND_LOG_RET(hClientEvent, __LINE__, "CreateGlobalEvent: %s", clientEventName.c_str(), 1);
-
- //1.创建共享文件句柄 hMapFile,CreateFileMapping()函数创建一个文件映射内核对象
- hFileMap = CreateGlobalFileMap(fileMapName);
- COND_LOG_RET(hFileMap, __LINE__, "CreateGlobalFileMap: %s", fileMapName.c_str(), 1);
-
- //2.获取指向文件视图的指针 pBuf,MapViewOfFile()函数负责把文件数据映射到进程的地址空间
- pBuf = (char*)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, FILEMAP_BUF);
- COND_LOG_RET(pBuf, __LINE__, "MapViewOfFile: %x", pBuf, 1);
-
- /*strcpy_s(pBuf, FILEMAP_BUF, "hello");
- COND_LOG_RET(SetEvent(hServerEvent), __LINE__, "SetEvent: %s", serverEventName.c_str(), 1);*/
-
- 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;
}
-int main()
-{
- COND_LOG_RET(initFoundSet(), __LINE__, "initFoundSet()(ZeroSuccess): %d", GetLastError(), 1);
+// 处理按钮点击事件
+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;
- COND_LOG_RET(initIPCEnvironment(), __LINE__, "initIPCEnvironment()(ZeroSuccess): %d", GetLastError(), 1);
-
- COND_LOG_RET(HookCurWindow(hideDllName), __LINE__, "HookCurWindow(hideDllName)(ZeroSuccess): %d", GetLastError(), 1);
+ case IDC_BUTTON_SHOW:
+ Log(LogLevel::LOG_INFO, __LINE__, "执行显示窗口操作...");
+ if (HookCurWindow(unhideDllName)) {
+ Log(LogLevel::LOG_INFO, __LINE__, "窗口显示操作完成");
+ UpdateStatus(L"状态: 窗口已显示");
+ }
+ break;
- COND_LOG_RET(HookRtlWindow(true), __LINE__, "HookRtlWindow(true)(ZeroSuccess): %d", GetLastError(), 1);
-
- strcpy_s(pBuf, FILEMAP_BUF, "hello");
- COND_LOG_RET(SetEvent(hServerEvent), __LINE__, "SetEvent: %x", hServerEvent, 1);
+ case IDC_BUTTON_HOOK_RTL:
+ if (!g_bRtlHookEnabled) {
+ Log(LogLevel::LOG_INFO, __LINE__, "启用实时钩子...");
+ HookRtlWindow(true);
+ }
+ else {
+ Log(LogLevel::LOG_WARN, __LINE__, "实时钩子已经启用");
+ }
+ break;
- Log(LogLevel::LOG_INFO, __LINE__, "主线程开始监听与Service通信...");
+ case IDC_BUTTON_UNHOOK_RTL:
+ if (g_bRtlHookEnabled) {
+ Log(LogLevel::LOG_INFO, __LINE__, "禁用实时钩子...");
+ HookRtlWindow(false);
+ }
+ else {
+ Log(LogLevel::LOG_WARN, __LINE__, "实时钩子已经禁用");
+ }
+ break;
- while (1)
- {
- __GetEvent(hClientEvent, INFINITE);
- if (pBuf)
- {
- Log(LogLevel::LOG_INFO, __LINE__, "收到控制信息: %s", pBuf);
- if (string(pBuf) == "stop")
- {
- break;
- }
- else if (string(pBuf) == "debug")//显示本身控制台程序
- {
- ShowWindow(GetConsoleWindow(), SW_SHOWNA);
- /*DWORD lasterror = GetLastError();
- auto getLogDir = []() ->string {
- char dir[MAX_PATH];
- GetModuleFileNameA(NULL, dir, MAX_PATH);
- PathRemoveFileSpecA(dir);
-#ifdef _WIN64
- PathAppendA(dir, "log.txt");
-#else
- PathAppendA(dir, "log32.txt");
-#endif
- return string{ dir };
- };
- auto dir = getLogDir();
- if (!dir.empty())
- {
- FILE* fp = NULL;
- if ((fp = fopen(dir.c_str(), "a+")) != NULL)
- {
- fprintf(fp, "ShowWindow %x ret[%d]: %d\n", (DWORD)consoleWindow, lasterror, ret);
- fclose(fp);
- }
-
- }*/
- __SetEvent(hServerEvent);
- }
- }
- }
- COND_LOG_RET(HookRtlWindow(false), __LINE__, "HookRtlWindow(false)(ZeroSuccess): %d", GetLastError(), 1);
- Sleep(1500);
- COND_LOG_RET(HookCurWindow(unhideDllName), __LINE__, "HookCurWindow(unhideDllName)(ZeroSuccess): %d", GetLastError(), 1);
- __SetEvent(hServerEvent);
- //释放资源
- CloseHandle(hServerEvent);
- CloseHandle(hClientEvent);
- if (pBuf) UnmapViewOfFile(pBuf);
- CloseHandle(hFileMap);
- return 0;
+ 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;
}
\ No newline at end of file
diff --git a/ConfigManager/ConfigManager.cpp b/ConfigManager/ConfigManager.cpp
new file mode 100644
index 0000000..e87e631
--- /dev/null
+++ b/ConfigManager/ConfigManager.cpp
@@ -0,0 +1,385 @@
+// ConfigManager.cpp : 定义静态库的函数。
+//
+
+#include "pch.h"
+#include "framework.h"
+#include "ConfigManager.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#pragma comment(lib,"shlwapi.lib")
+
+// TODO: 这是一个库函数示例
+namespace ConfigManager {
+
+ // ProcessFilterConfig 实现
+ void ProcessFilterConfig::clear() {
+ processList.clear();
+ mode = WHITELIST;
+ caseSensitive = false;
+ }
+
+ // Config 类实现
+ Config::Config() {
+ m_configFilePath = getDefaultConfigPath();
+ }
+
+ Config::Config(const std::string& configPath) : m_configFilePath(configPath) {
+ }
+
+ std::string Config::toLowerCase(const std::string& str) const {
+ std::string result = str;
+ std::transform(result.begin(), result.end(), result.begin(), ::tolower);
+ return result;
+ }
+
+ std::string Config::trim(const std::string& str) const {
+ size_t start = str.find_first_not_of(" \t\r\n");
+ if (start == std::string::npos) return "";
+ size_t end = str.find_last_not_of(" \t\r\n");
+ return str.substr(start, end - start + 1);
+ }
+
+ bool Config::fileExists(const std::string& filePath) const {
+ return GetFileAttributesA(filePath.c_str()) != INVALID_FILE_ATTRIBUTES;
+ }
+
+ void Config::setConfigPath(const std::string& configPath) {
+ m_configFilePath = configPath;
+ }
+
+ std::string Config::getConfigPath() const {
+ return m_configFilePath;
+ }
+
+ std::string Config::getDefaultConfigPath() const {
+ char exePath[MAX_PATH] = { 0 };
+ GetModuleFileNameA(NULL, exePath, MAX_PATH);
+ PathRemoveFileSpecA(exePath);
+ PathAppendA(exePath, "process_filter.ini");
+ return std::string(exePath);
+ }
+
+ bool Config::loadConfig() {
+ return loadConfig(m_configFilePath);
+ }
+
+ bool Config::loadConfig(const std::string& configPath) {
+ m_filterConfig.clear();
+
+ std::ifstream configFile(configPath);
+ if (!configFile.is_open()) {
+ std::cerr << "Warning: 无法打开配置文件: " << configPath << std::endl;
+ return false;
+ }
+
+ std::string line;
+ bool inProcessSection = false;
+
+ std::cout << "Info: 开始读取配置文件: " << configPath << std::endl;
+
+ while (std::getline(configFile, line)) {
+ line = trim(line);
+
+ // 跳过空行和注释
+ if (line.empty() || line.front() == '#' || line.front() == ';') {
+ continue;
+ }
+
+ // 检查是否是节标题
+ if (line.front() == '[' && line.back() == ']') {
+ std::string section = line.substr(1, line.length() - 2);
+ section = trim(section);
+ inProcessSection = (toLowerCase(section) == "process");
+ continue;
+ }
+
+ if (!inProcessSection) {
+ continue;
+ }
+
+ // 解析配置项
+ size_t equalPos = line.find('=');
+ if (equalPos == std::string::npos) {
+ continue;
+ }
+
+ std::string key = trim(line.substr(0, equalPos));
+ std::string value = trim(line.substr(equalPos + 1));
+
+ key = toLowerCase(key);
+
+ if (key == "mode") {
+ value = toLowerCase(value);
+ if (value == "whitelist" || value == "white") {
+ m_filterConfig.mode = ProcessFilterConfig::WHITELIST;
+ std::cout << "Info: 设置为白名单模式" << std::endl;
+ }
+ else if (value == "blacklist" || value == "black") {
+ m_filterConfig.mode = ProcessFilterConfig::BLACKLIST;
+ std::cout << "Info: 设置为黑名单模式" << std::endl;
+ }
+ }
+ else if (key == "casesensitive") {
+ value = toLowerCase(value);
+ m_filterConfig.caseSensitive = (value == "true" || value == "1" || value == "yes");
+ std::cout << "Info: 大小写敏感: " << (m_filterConfig.caseSensitive ? "开启" : "关闭") << std::endl;
+ }
+ else if (key == "list") {
+ // 解析进程列表,支持逗号分隔
+ std::stringstream ss(value);
+ std::string processName;
+ while (std::getline(ss, processName, ',')) {
+ processName = trim(processName);
+ if (!processName.empty()) {
+ if (!m_filterConfig.caseSensitive) {
+ processName = toLowerCase(processName);
+ }
+ m_filterConfig.processList.insert(processName);
+ std::cout << "Info: 添加进程: " << processName << std::endl;
+ }
+ }
+ }
+ }
+
+ configFile.close();
+
+ std::cout << "Info: 配置文件加载完成,共加载 " << m_filterConfig.processList.size() << " 个进程名" << std::endl;
+ return true;
+ }
+
+ bool Config::saveDefaultConfig() const {
+ return saveDefaultConfig(m_configFilePath);
+ }
+
+ bool Config::saveDefaultConfig(const std::string& configPath) const {
+ std::ofstream configFile(configPath);
+ if (!configFile.is_open()) {
+ std::cerr << "Error: 无法创建配置文件: " << configPath << std::endl;
+ return false;
+ }
+
+ configFile << "# 进程过滤配置文件\n";
+ configFile << "# 支持的配置项:\n";
+ configFile << "# mode: whitelist(白名单) 或 blacklist(黑名单)\n";
+ configFile << "# casesensitive: true(大小写敏感) 或 false(大小写不敏感)\n";
+ configFile << "# list: 进程名列表,用逗号分隔\n\n";
+
+ configFile << "[Process]\n";
+ configFile << "# 过滤模式: whitelist(只处理列表中的进程) 或 blacklist(处理除列表外的进程)\n";
+ configFile << "mode = whitelist\n\n";
+
+ configFile << "# 是否大小写敏感\n";
+ configFile << "casesensitive = false\n\n";
+
+ configFile << "# 进程名列表(包含.exe后缀),用逗号分隔\n";
+ configFile << "list = chrome.exe, msedge.exe, mstsc.exe, notepad.exe, calc.exe\n\n";
+
+ configFile << "# 示例黑名单配置:\n";
+ configFile << "# mode = blacklist\n";
+ configFile << "# list = explorer.exe, winlogon.exe, csrss.exe, smss.exe\n";
+
+ configFile.close();
+
+ std::cout << "Info: 默认配置文件已创建: " << configPath << std::endl;
+ return true;
+ }
+
+ bool Config::reloadConfig() {
+ // 如果配置文件不存在,创建默认配置
+ if (!fileExists(m_configFilePath)) {
+ std::cout << "Warning: 配置文件不存在,创建默认配置" << std::endl;
+ if (!saveDefaultConfig()) {
+ return false;
+ }
+ }
+
+ return loadConfig();
+ }
+
+ const ProcessFilterConfig& Config::getProcessFilterConfig() const {
+ return m_filterConfig;
+ }
+
+ ProcessFilterConfig& Config::getProcessFilterConfig() {
+ return m_filterConfig;
+ }
+
+ bool Config::shouldProcessBeHooked(const std::string& processName) const {
+ if (m_filterConfig.processList.empty()) {
+ // 如果没有配置,使用默认行为
+ return true;
+ }
+
+ std::string nameToCheck = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToCheck = toLowerCase(processName);
+ }
+
+ bool inList = m_filterConfig.processList.find(nameToCheck) != m_filterConfig.processList.end();
+
+ if (m_filterConfig.mode == ProcessFilterConfig::WHITELIST) {
+ return inList; // 白名单模式:只处理列表中的进程
+ }
+ else {
+ return !inList; // 黑名单模式:处理列表外的进程
+ }
+ }
+
+ void Config::setFilterMode(ProcessFilterConfig::FilterMode mode) {
+ m_filterConfig.mode = mode;
+ }
+
+ ProcessFilterConfig::FilterMode Config::getFilterMode() const {
+ return m_filterConfig.mode;
+ }
+
+ void Config::setCaseSensitive(bool sensitive) {
+ m_filterConfig.caseSensitive = sensitive;
+ }
+
+ bool Config::isCaseSensitive() const {
+ return m_filterConfig.caseSensitive;
+ }
+
+ void Config::addProcess(const std::string& processName) {
+ std::string nameToAdd = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToAdd = toLowerCase(processName);
+ }
+ m_filterConfig.processList.insert(nameToAdd);
+ }
+
+ void Config::removeProcess(const std::string& processName) {
+ std::string nameToRemove = processName;
+ if (!m_filterConfig.caseSensitive) {
+ nameToRemove = toLowerCase(processName);
+ }
+ m_filterConfig.processList.erase(nameToRemove);
+ }
+
+ void Config::clearProcessList() {
+ m_filterConfig.processList.clear();
+ }
+
+ std::vector Config::getProcessList() const {
+ std::vector result;
+ result.reserve(m_filterConfig.processList.size());
+ for (const auto& process : m_filterConfig.processList) {
+ result.push_back(process);
+ }
+ return result;
+ }
+
+ size_t Config::getProcessCount() const {
+ return m_filterConfig.processList.size();
+ }
+
+ bool Config::isConfigValid() const {
+ return !m_configFilePath.empty();
+ }
+
+ void Config::printConfig() const {
+ std::cout << "=== 配置信息 ===" << std::endl;
+ std::cout << "配置文件路径: " << m_configFilePath << std::endl;
+ std::cout << "过滤模式: " << (m_filterConfig.mode == ProcessFilterConfig::WHITELIST ? "白名单" : "黑名单") << std::endl;
+ std::cout << "大小写敏感: " << (m_filterConfig.caseSensitive ? "是" : "否") << std::endl;
+ std::cout << "进程列表 (" << m_filterConfig.processList.size() << "个):" << std::endl;
+ for (const auto& process : m_filterConfig.processList) {
+ std::cout << " - " << process << std::endl;
+ }
+ std::cout << "================" << std::endl;
+ }
+
+ // GlobalConfig 静态成员初始化
+ Config* GlobalConfig::s_instance = nullptr;
+ bool GlobalConfig::s_initialized = false;
+
+ bool GlobalConfig::initialize() {
+ if (s_initialized) {
+ return true;
+ }
+
+ s_instance = new Config();
+ s_initialized = s_instance->reloadConfig();
+
+ if (!s_initialized) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+
+ return s_initialized;
+ }
+
+ bool GlobalConfig::initialize(const std::string& configPath) {
+ if (s_initialized) {
+ return true;
+ }
+
+ s_instance = new Config(configPath);
+ s_initialized = s_instance->reloadConfig();
+
+ if (!s_initialized) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+
+ return s_initialized;
+ }
+
+ void GlobalConfig::cleanup() {
+ if (s_instance) {
+ delete s_instance;
+ s_instance = nullptr;
+ }
+ s_initialized = false;
+ }
+
+ Config* GlobalConfig::getInstance() {
+ return s_instance;
+ }
+
+ bool GlobalConfig::isInitialized() {
+ return s_initialized;
+ }
+
+ // 便捷函数实现
+ bool initializeGlobalConfig() {
+ return GlobalConfig::initialize();
+ }
+
+ bool initializeGlobalConfig(const std::string& configPath) {
+ return GlobalConfig::initialize(configPath);
+ }
+
+ Config* getGlobalConfig() {
+ return GlobalConfig::getInstance();
+ }
+
+ void cleanupGlobalConfig() {
+ GlobalConfig::cleanup();
+ }
+
+ bool shouldProcessBeHooked(const std::string& processName) {
+
+ Config* config = GlobalConfig::getInstance();
+ if (!config) {
+ initializeGlobalConfig();
+ config = GlobalConfig::getInstance();
+ }
+ return config->shouldProcessBeHooked(processName);
+ }
+
+ bool reloadGlobalConfig() {
+ Config* config = GlobalConfig::getInstance();
+ if (!config) {
+ return false;
+ }
+ return config->reloadConfig();
+ }
+
+} // namespace ConfigManager
diff --git a/ConfigManager/ConfigManager.h b/ConfigManager/ConfigManager.h
new file mode 100644
index 0000000..793a645
--- /dev/null
+++ b/ConfigManager/ConfigManager.h
@@ -0,0 +1,107 @@
+#pragma once
+#pragma once
+
+#include
+#include
+#include
+
+/**
+ * ù - ڹ̹˺ѡ
+ */
+namespace ConfigManager {
+
+ // ̹ýṹ
+ struct ProcessFilterConfig {
+ enum FilterMode {
+ WHITELIST, // ģʽֻбеĽ
+ BLACKLIST // ģʽбĽ
+ };
+
+ FilterMode mode = WHITELIST;
+ std::unordered_set processList;
+ bool caseSensitive = false;
+
+ void clear();
+ };
+
+ // ù
+ class Config {
+ private:
+ ProcessFilterConfig m_filterConfig;
+ std::string m_configFilePath;
+
+ // ߺ
+ std::string toLowerCase(const std::string& str) const;
+ std::string trim(const std::string& str) const;
+ bool fileExists(const std::string& filePath) const;
+
+ public:
+ Config();
+ explicit Config(const std::string& configPath);
+ ~Config() = default;
+
+ // ļ·
+ void setConfigPath(const std::string& configPath);
+ std::string getConfigPath() const;
+ std::string getDefaultConfigPath() const;
+
+ // üغͱ
+ bool loadConfig();
+ bool loadConfig(const std::string& configPath);
+ bool saveDefaultConfig() const;
+ bool saveDefaultConfig(const std::string& configPath) const;
+ bool reloadConfig();
+
+ // ̹÷
+ const ProcessFilterConfig& getProcessFilterConfig() const;
+ ProcessFilterConfig& getProcessFilterConfig();
+
+ // ̹ط
+ bool shouldProcessBeHooked(const std::string& processName) const;
+ void setFilterMode(ProcessFilterConfig::FilterMode mode);
+ ProcessFilterConfig::FilterMode getFilterMode() const;
+ void setCaseSensitive(bool sensitive);
+ bool isCaseSensitive() const;
+
+ // б
+ void addProcess(const std::string& processName);
+ void removeProcess(const std::string& processName);
+ void clearProcessList();
+ std::vector getProcessList() const;
+ size_t getProcessCount() const;
+
+ // ֤
+ bool isConfigValid() const;
+
+ // Ϣ
+ void printConfig() const;
+ };
+
+ // ȫʵ
+ class GlobalConfig {
+ private:
+ static Config* s_instance;
+ static bool s_initialized;
+
+ public:
+ static bool initialize();
+ static bool initialize(const std::string& configPath);
+ static void cleanup();
+ static Config* getInstance();
+ static bool isInitialized();
+ };
+
+ // ݺ
+ bool initializeGlobalConfig();
+ bool initializeGlobalConfig(const std::string& configPath);
+ Config* getGlobalConfig();
+ void cleanupGlobalConfig();
+
+ // ֱӲȫõıݺ
+ bool shouldProcessBeHooked(const std::string& processName);
+ bool reloadGlobalConfig();
+}
+
+// Ժ궨
+#define PROCESS_FILTER_WHITELIST ConfigManager::ProcessFilterConfig::WHITELIST
+#define PROCESS_FILTER_BLACKLIST ConfigManager::ProcessFilterConfig::BLACKLIST
\ No newline at end of file
diff --git a/ConfigManager/ConfigManager.vcxproj b/ConfigManager/ConfigManager.vcxproj
new file mode 100644
index 0000000..8ad0690
--- /dev/null
+++ b/ConfigManager/ConfigManager.vcxproj
@@ -0,0 +1,155 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 17.0
+ Win32Proj
+ {b5afeb98-c976-4839-9a8e-4f48b057d7fd}
+ ConfigManager
+ 10.0
+
+
+
+ StaticLibrary
+ true
+ v143
+ Unicode
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v143
+ Unicode
+
+
+ StaticLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ ProgramDatabase
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ConfigManager/ConfigManager.vcxproj.filters b/ConfigManager/ConfigManager.vcxproj.filters
new file mode 100644
index 0000000..3c24fa5
--- /dev/null
+++ b/ConfigManager/ConfigManager.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {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/ConfigManager/framework.h b/ConfigManager/framework.h
new file mode 100644
index 0000000..d2d95bd
--- /dev/null
+++ b/ConfigManager/framework.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
diff --git a/ConfigManager/pch.cpp b/ConfigManager/pch.cpp
new file mode 100644
index 0000000..b6fb8f4
--- /dev/null
+++ b/ConfigManager/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: 与预编译标头对应的源文件
+
+#include "pch.h"
+
+// 当使用预编译的头时,需要使用此源文件,编译才能成功。
diff --git a/ConfigManager/pch.h b/ConfigManager/pch.h
new file mode 100644
index 0000000..9660927
--- /dev/null
+++ b/ConfigManager/pch.h
@@ -0,0 +1,13 @@
+// pch.h: 这是预编译标头文件。
+// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
+// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
+// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
+// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
+
+#ifndef PCH_H
+#define PCH_H
+
+// 添加要在此处预编译的标头
+#include "framework.h"
+
+#endif //PCH_H
diff --git a/Hide/Hide.vcxproj b/Hide/Hide.vcxproj
index 7202141..e81823c 100644
--- a/Hide/Hide.vcxproj
+++ b/Hide/Hide.vcxproj
@@ -29,26 +29,26 @@
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
diff --git a/Hide/dllmain.cpp b/Hide/dllmain.cpp
index 1ce831d..7e6cba2 100644
--- a/Hide/dllmain.cpp
+++ b/Hide/dllmain.cpp
@@ -36,7 +36,7 @@ BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
GetWindowThreadProcessId(hwnd, &processId);
if (processId == GetCurrentProcessId())
{
- if ((GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE && SetWindowDisplayAffinity(hwnd, WDA_MONITOR))
+ if ((GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE && SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE))
{
//获取窗口标题
char title[MAX_PATH] = { 0 };
@@ -49,7 +49,10 @@ BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
{
haveRect = (rect.right - rect.left > 0) && (rect.bottom - rect.top > 0);
isMinimized = !haveRect;
- }
+ }
+ SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
+ & ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
+
//summary
char summary[512] = { 0 };
@@ -66,7 +69,7 @@ void setDAForWindows() {
HWND windowHandle = NULL;
do {
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
- if ((GetWindowLong(windowHandle, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE && SetWindowDisplayAffinity(windowHandle, WDA_MONITOR))
+ if ((GetWindowLong(windowHandle, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE && SetWindowDisplayAffinity(windowHandle, WDA_EXCLUDEFROMCAPTURE))
{
//获取窗口标题
char title[MAX_PATH] = { 0 };
@@ -81,6 +84,9 @@ void setDAForWindows() {
isMinimized = !haveRect;
}
+ SetWindowLong(windowHandle, GWL_EXSTYLE, GetWindowLong(windowHandle, GWL_EXSTYLE)
+ & ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
+
//summary
char summary[512] = { 0 };
sprintf(summary, "进程名:%s, 窗口句柄:%x, 标题:%s, 最小化:%d, 状态:隐藏", procName.c_str(), windowHandle, title, isMinimized);//bool isMinimized不能转成%s
diff --git a/RtlHook/RtlHook.vcxproj b/RtlHook/RtlHook.vcxproj
index 77896cc..8d29965 100644
--- a/RtlHook/RtlHook.vcxproj
+++ b/RtlHook/RtlHook.vcxproj
@@ -30,26 +30,26 @@
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
@@ -168,6 +168,11 @@
Create
+
+
+ {b5afeb98-c976-4839-9a8e-4f48b057d7fd}
+
+
diff --git a/RtlHook/dllmain.cpp b/RtlHook/dllmain.cpp
index bbd6337..bab066e 100644
--- a/RtlHook/dllmain.cpp
+++ b/RtlHook/dllmain.cpp
@@ -4,29 +4,62 @@
#include
#include
#include
+#include "../ConfigManager/ConfigManager.h"
+#include // 必须
+#pragma comment(lib, "psapi.lib")
#pragma comment(lib,"shlwapi.lib")
using namespace std;
void OutputErrorString(const char* text, const char* file, int line)
{
- char msg[512] = { 0 };
- sprintf(msg, "[%s:%d] %s:%d", file, line, text, GetLastError());
- OutputDebugStringA(msg);
+ char msg[512] = { 0 };
+ sprintf(msg, "[%s:%d] %s:%d", file, line, text, GetLastError());
+ OutputDebugStringA(msg);
}
+std::string GetExeNameFromHwnd(HWND hwnd)
+{
+ DWORD pid = 0;
+ GetWindowThreadProcessId(hwnd, &pid);
+ if (pid == 0) return "unknown";
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (!hProcess) return "unknown";
+
+ char exePath[MAX_PATH] = { 0 };
+ if (GetModuleFileNameExA(hProcess, NULL, exePath, MAX_PATH) == 0)
+ {
+ CloseHandle(hProcess);
+ return "unknown";
+ }
+ CloseHandle(hProcess);
+
+ // 提取文件名部分
+ char* exeName = strrchr(exePath, '\\');
+ return (exeName ? exeName + 1 : exePath);
+}
string getProcName()
{
- char szProcName[MAX_PATH] = { 0 };
- if (GetModuleFileNameA(NULL, szProcName, MAX_PATH))
- {
- PathStripPathA(szProcName);
- return szProcName;
- }
- else
- {
- OutputErrorString("GetModuleFileNameA failed", __FILE__, __LINE__);
- }
- return string{ "false" };
+ char szProcName[MAX_PATH] = { 0 };
+ if (GetModuleFileNameA(NULL, szProcName, MAX_PATH))
+ {
+ PathStripPathA(szProcName);
+ return szProcName;
+ }
+ else
+ {
+ OutputErrorString("GetModuleFileNameA failed", __FILE__, __LINE__);
+ }
+ return string{ "false" };
+}
+string getProcNameByHandle(HANDLE hProcess)
+{
+ char exeName[MAX_PATH] = { 0 };
+ if (GetModuleFileNameExA(hProcess, NULL, exeName, MAX_PATH))
+ {
+ PathStripPathA(exeName);
+ return exeName;
+ }
+ return {};
}
string procName = getProcName();
@@ -35,101 +68,118 @@ unordered_map hastryHookedProc;
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
- // 一般来说,所有运行的进程(有窗口过程的)都会加载这个钩子过程了
- CWPSTRUCT* pCwp = reinterpret_cast(lParam);
- switch (pCwp->message)
- {
- case WM_CREATE:
- {
- if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
- {
- if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_MONITOR))
- {
- char title[MAX_PATH] = { 0 };
- GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
- char msg[512] = { 0 };
- if (title[0] != '\0')
- sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), title);
- else
- sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), "NoTitle");
- OutputDebugStringA(msg);
- }
- hastryHookedProc[pCwp->hwnd] = 1;
- }
- break;
- }
- case WM_SHOWWINDOW:
- {
- if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
- {
- if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_MONITOR))
- {
- char title[MAX_PATH] = { 0 };
- GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
- char msg[512] = { 0 };
- if (title[0] != '\0')
- sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), title);
- else
- sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), "NoTitle");
- OutputDebugStringA(msg);
- }
- hastryHookedProc[pCwp->hwnd] = 1;
- }
- break;
- }
- /*case WM_CLOSE:
- {
- char title[MAX_PATH] = { 0 };
- GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
- OutputDebugStringA((string(pname) + title + " close").c_str());
- break;
- }*/
-
- default:
- break;
- }
- return CallNextHookEx(hHook, nCode, wParam, lParam);
+ // 一般来说,所有运行的进程(有窗口过程的)都会加载这个钩子过程了
+ CWPSTRUCT* pCwp = reinterpret_cast(lParam);
+
+ switch (pCwp->message)
+ {
+ case WM_CREATE:
+ {
+ if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
+ {
+
+ DWORD dwPid;
+ GetWindowThreadProcessId(pCwp->hwnd, &dwPid); // Change windowHandle to pCwp->hwnd
+ HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
+ if (!hProcess) return CallNextHookEx(hHook, nCode, wParam, lParam);
+ string exeName = getProcNameByHandle(hProcess);
+ if (ConfigManager::shouldProcessBeHooked(exeName)) {
+ if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_EXCLUDEFROMCAPTURE))
+ {
+
+ SetWindowLong(pCwp->hwnd, GWL_EXSTYLE, GetWindowLong(pCwp->hwnd, GWL_EXSTYLE)
+ & ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
+
+ char title[MAX_PATH] = { 0 };
+ GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
+ char msg[512] = { 0 };
+ if (title[0] != '\0')
+ sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), title);
+ else
+ sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), "NoTitle");
+ OutputDebugStringA(msg);
+ }
+ }
+ CloseHandle(hProcess);
+ hastryHookedProc[pCwp->hwnd] = 1;
+ }
+ break;
+ }
+ case WM_SHOWWINDOW:
+ {
+ if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
+ {
+ if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_EXCLUDEFROMCAPTURE))
+ {
+ SetWindowLong(pCwp->hwnd, GWL_EXSTYLE, GetWindowLong(pCwp->hwnd, GWL_EXSTYLE)
+ & ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
+
+ char title[MAX_PATH] = { 0 };
+ GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
+ char msg[512] = { 0 };
+ if (title[0] != '\0')
+ sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), title);
+ else
+ sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), "NoTitle");
+ OutputDebugStringA(msg);
+ }
+ hastryHookedProc[pCwp->hwnd] = 1;
+ }
+ break;
+ }
+ /*case WM_CLOSE:
+ {
+ char title[MAX_PATH] = { 0 };
+ GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
+ OutputDebugStringA((string(pname) + title + " close").c_str());
+ break;
+ }*/
+
+ default:
+ break;
+ }
+ return CallNextHookEx(hHook, nCode, wParam, lParam);
}
EXPORT BOOL WINAPI SetHook(BOOL isInstall)
{
- if (isInstall)
- {
- hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);
- if (hHook) OutputDebugStringA("SetWindowsHookEx Success");
- return hHook != NULL;
- }
- else
- {
- if (UnhookWindowsHookEx(hHook))
- {
- OutputDebugStringA("UnhookWindowsHookEx Success");
- hHook = NULL;
- hInstance = NULL;
- return TRUE;
- }
- }
- return FALSE;
+ if (isInstall)
+ {
+ hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);
+ if (hHook) OutputDebugStringA("SetWindowsHookEx Success");
+ return hHook != NULL;
+ }
+ else
+ {
+ if (UnhookWindowsHookEx(hHook))
+ {
+ OutputDebugStringA("UnhookWindowsHookEx Success");
+ hHook = NULL;
+ hInstance = NULL;
+ return TRUE;
+ }
+ }
+ return FALSE;
}
BOOL APIENTRY DllMain(HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
)
{
- switch (ul_reason_for_call)
- {
- case DLL_PROCESS_ATTACH:
- //OutputDebugStringA(("进入:" + procName).c_str());
- hInstance = (HINSTANCE)hModule;
- break;
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- //OutputDebugStringA(("离开:" + procName).c_str());
- break;
- }
- return TRUE;
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ //OutputDebugStringA(("进入:" + procName).c_str());
+ hInstance = (HINSTANCE)hModule;
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ //OutputDebugStringA(("离开:" + procName).c_str());
+ break;
+ }
+ return TRUE;
}
diff --git a/UnHide/UnHide.vcxproj b/UnHide/UnHide.vcxproj
index 0b58806..51efe8e 100644
--- a/UnHide/UnHide.vcxproj
+++ b/UnHide/UnHide.vcxproj
@@ -29,26 +29,26 @@
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
DynamicLibrary
true
- v142
+ v143
Unicode
DynamicLibrary
false
- v142
+ v143
true
Unicode
diff --git a/UnHide/dllmain.cpp b/UnHide/dllmain.cpp
index 38a9adf..c457a5f 100644
--- a/UnHide/dllmain.cpp
+++ b/UnHide/dllmain.cpp
@@ -42,6 +42,12 @@ BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
char title[MAX_PATH] = { 0 };
GetWindowTextA(hwnd, title, MAX_PATH);
+
+ LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ exStyle |= WS_EX_APPWINDOW;
+ exStyle &= ~WS_EX_TOOLWINDOW;
+ SetWindowLong(hwnd, GWL_EXSTYLE, exStyle);
+
//判断最小化
RECT rect;
bool haveRect = false, isMinimized = false;
@@ -72,6 +78,12 @@ void setDAForWindows() {
char title[MAX_PATH] = { 0 };
GetWindowTextA(windowHandle, title, MAX_PATH);
+ LONG exStyle = GetWindowLong(windowHandle, GWL_EXSTYLE);
+ exStyle |= WS_EX_APPWINDOW;
+ exStyle &= ~WS_EX_TOOLWINDOW;
+ SetWindowLong(windowHandle, GWL_EXSTYLE, exStyle);
+
+
//判断最小化
RECT rect;
bool haveRect = false, isMinimized = false;