mirror of
https://github.com/huiyiruciduojiao/FuckScreenCap.git
synced 2026-01-28 03:54:37 +08:00
添加了简单的图形化界面操作和配置文件的支持
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.31702.278
|
VisualStudioVersion = 17.14.36221.1 d17.14
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RtlHide", "RtlHook\RtlHook.vcxproj", "{E91231DC-E9CF-4E12-B0E4-A0C63F7A7E69}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RtlHide", "RtlHook\RtlHook.vcxproj", "{E91231DC-E9CF-4E12-B0E4-A0C63F7A7E69}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -10,6 +10,14 @@ EndProject
|
|||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnHide", "UnHide\UnHide.vcxproj", "{3566D20B-6C53-4B3B-BC9C-A252486789D5}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnHide", "UnHide\UnHide.vcxproj", "{3566D20B-6C53-4B3B-BC9C-A252486789D5}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AntiScreenCap", "AntiScreenCap\AntiScreenCap.vcxproj", "{EC0D81D9-E367-4307-925F-2CF1149B5E57}"
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
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|x64.Build.0 = Release|x64
|
||||||
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x86.ActiveCfg = Release|Win32
|
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{EC0D81D9-E367-4307-925F-2CF1149B5E57}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -19,10 +19,12 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="config_manager.h" />
|
||||||
<ClInclude Include="hook_current.h" />
|
<ClInclude Include="hook_current.h" />
|
||||||
<ClInclude Include="main.h" />
|
<ClInclude Include="main.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="config_manager.cpp" />
|
||||||
<ClCompile Include="hook_current.cpp" />
|
<ClCompile Include="hook_current.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -37,26 +39,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -129,7 +131,7 @@
|
|||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@@ -144,7 +146,7 @@
|
|||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
<ClInclude Include="main.h">
|
<ClInclude Include="main.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="config_manager.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="hook_current.cpp">
|
<ClCompile Include="hook_current.cpp">
|
||||||
@@ -29,5 +32,8 @@
|
|||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="config_manager.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
377
AntiScreenCap/config_manager.cpp
Normal file
377
AntiScreenCap/config_manager.cpp
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
#include "config_manager.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
#pragma comment(lib,"shlwapi.lib")
|
||||||
|
|
||||||
|
namespace ConfigManager {
|
||||||
|
|
||||||
|
// ProcessFilterConfig ʵ<><CAB5>
|
||||||
|
void ProcessFilterConfig::clear() {
|
||||||
|
processList.clear();
|
||||||
|
mode = WHITELIST;
|
||||||
|
caseSensitive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config <20><>ʵ<EFBFBD><CAB5>
|
||||||
|
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: <20><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>: " << configPath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
bool inProcessSection = false;
|
||||||
|
|
||||||
|
std::cout << "Info: <20><>ʼ<EFBFBD><CABC>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>: " << configPath << std::endl;
|
||||||
|
|
||||||
|
while (std::getline(configFile, line)) {
|
||||||
|
line = trim(line);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD>ע<EFBFBD><D7A2>
|
||||||
|
if (line.empty() || line.front() == '#' || line.front() == ';') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ǽڱ<C7BD><DAB1><EFBFBD>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
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: <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ" << std::endl;
|
||||||
|
}
|
||||||
|
else if (value == "blacklist" || value == "black") {
|
||||||
|
m_filterConfig.mode = ProcessFilterConfig::BLACKLIST;
|
||||||
|
std::cout << "Info: <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (key == "casesensitive") {
|
||||||
|
value = toLowerCase(value);
|
||||||
|
m_filterConfig.caseSensitive = (value == "true" || value == "1" || value == "yes");
|
||||||
|
std::cout << "Info: <20><>Сд<D0A1><D0B4><EFBFBD><EFBFBD>: " << (m_filterConfig.caseSensitive ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD>ر<EFBFBD>") << std::endl;
|
||||||
|
}
|
||||||
|
else if (key == "list") {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>֧<EFBFBD>ֶ<EFBFBD><D6B6>ŷָ<C5B7>
|
||||||
|
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: <20><><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>: " << processName << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
std::cout << "Info: <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " << m_filterConfig.processList.size() << " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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: <20><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>: " << configPath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
configFile << "# <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>\n";
|
||||||
|
configFile << "# ֧<>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n";
|
||||||
|
configFile << "# mode: whitelist(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><> blacklist(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)\n";
|
||||||
|
configFile << "# casesensitive: true(<28><>Сд<D0A1><D0B4><EFBFBD><EFBFBD>) <20><> false(<28><>Сд<D0A1><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)\n";
|
||||||
|
configFile << "# list: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>ŷָ<C5B7>\n\n";
|
||||||
|
|
||||||
|
configFile << "[Process]\n";
|
||||||
|
configFile << "# <20><><EFBFBD><EFBFBD>ģʽ: whitelist(ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>еĽ<D0B5><C4BD><EFBFBD>) <20><> blacklist(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>)\n";
|
||||||
|
configFile << "mode = whitelist\n\n";
|
||||||
|
|
||||||
|
configFile << "# <20>Ƿ<EFBFBD><C7B7><EFBFBD>Сд<D0A1><D0B4><EFBFBD><EFBFBD>\n";
|
||||||
|
configFile << "casesensitive = false\n\n";
|
||||||
|
|
||||||
|
configFile << "# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.exe<78><65><EFBFBD><D7BA><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>ŷָ<C5B7>\n";
|
||||||
|
configFile << "list = chrome.exe, msedge.exe, mstsc.exe, notepad.exe, calc.exe\n\n";
|
||||||
|
|
||||||
|
configFile << "# ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>\n";
|
||||||
|
configFile << "# mode = blacklist\n";
|
||||||
|
configFile << "# list = explorer.exe, winlogon.exe, csrss.exe, smss.exe\n";
|
||||||
|
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
std::cout << "Info: Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>Ѵ<EFBFBD><D1B4><EFBFBD>: " << configPath << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Config::reloadConfig() {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (!fileExists(m_configFilePath)) {
|
||||||
|
std::cout << "Warning: <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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()) {
|
||||||
|
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>ʹ<EFBFBD><CAB9>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD>Ϊ
|
||||||
|
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; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>еĽ<D0B5><C4BD><EFBFBD>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return !inList; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<std::string> Config::getProcessList() const {
|
||||||
|
std::vector<std::string> 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 << "=== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ ===" << std::endl;
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD>: " << m_configFilePath << std::endl;
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ: " << (m_filterConfig.mode == ProcessFilterConfig::WHITELIST ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>") << std::endl;
|
||||||
|
std::cout << "<EFBFBD><EFBFBD>Сд<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: " << (m_filterConfig.caseSensitive ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>") << std::endl;
|
||||||
|
std::cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD> (" << m_filterConfig.processList.size() << "<EFBFBD><EFBFBD>):" << std::endl;
|
||||||
|
for (const auto& process : m_filterConfig.processList) {
|
||||||
|
std::cout << " - " << process << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "================" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalConfig <20><>̬<EFBFBD><CCAC>Ա<EFBFBD><D4B1>ʼ<EFBFBD><CABC>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD>ʵ<EFBFBD><CAB5>
|
||||||
|
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; // Ĭ<><C4AC><EFBFBD><EFBFBD>Ϊ
|
||||||
|
}
|
||||||
|
return config->shouldProcessBeHooked(processName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reloadGlobalConfig() {
|
||||||
|
Config* config = GlobalConfig::getInstance();
|
||||||
|
if (!config) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return config->reloadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ConfigManager
|
||||||
106
AntiScreenCap/config_manager.h
Normal file
106
AntiScreenCap/config_manager.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD><CCB9>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
||||||
|
*/
|
||||||
|
namespace ConfigManager {
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ýṹ
|
||||||
|
struct ProcessFilterConfig {
|
||||||
|
enum FilterMode {
|
||||||
|
WHITELIST, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>еĽ<D0B5><C4BD><EFBFBD>
|
||||||
|
BLACKLIST // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterMode mode = WHITELIST;
|
||||||
|
std::unordered_set<std::string> processList;
|
||||||
|
bool caseSensitive = false;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
class Config {
|
||||||
|
private:
|
||||||
|
ProcessFilterConfig m_filterConfig;
|
||||||
|
std::string m_configFilePath;
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ߺ<EFBFBD><DFBA><EFBFBD>
|
||||||
|
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;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void setConfigPath(const std::string& configPath);
|
||||||
|
std::string getConfigPath() const;
|
||||||
|
std::string getDefaultConfigPath() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ü<EFBFBD><C3BC>غͱ<D8BA><CDB1><EFBFBD>
|
||||||
|
bool loadConfig();
|
||||||
|
bool loadConfig(const std::string& configPath);
|
||||||
|
bool saveDefaultConfig() const;
|
||||||
|
bool saveDefaultConfig(const std::string& configPath) const;
|
||||||
|
bool reloadConfig();
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
|
||||||
|
const ProcessFilterConfig& getProcessFilterConfig() const;
|
||||||
|
ProcessFilterConfig& getProcessFilterConfig();
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><D8B7><EFBFBD>
|
||||||
|
bool shouldProcessBeHooked(const std::string& processName) const;
|
||||||
|
void setFilterMode(ProcessFilterConfig::FilterMode mode);
|
||||||
|
ProcessFilterConfig::FilterMode getFilterMode() const;
|
||||||
|
void setCaseSensitive(bool sensitive);
|
||||||
|
bool isCaseSensitive() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void addProcess(const std::string& processName);
|
||||||
|
void removeProcess(const std::string& processName);
|
||||||
|
void clearProcessList();
|
||||||
|
std::vector<std::string> getProcessList() const;
|
||||||
|
size_t getProcessCount() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||||
|
bool isConfigValid() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
void printConfig() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD>
|
||||||
|
bool initializeGlobalConfig();
|
||||||
|
bool initializeGlobalConfig(const std::string& configPath);
|
||||||
|
Config* getGlobalConfig();
|
||||||
|
void cleanupGlobalConfig();
|
||||||
|
|
||||||
|
// ֱ<>Ӳ<EFBFBD><D3B2><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>õı<C3B5><C4B1>ݺ<EFBFBD><DDBA><EFBFBD>
|
||||||
|
bool shouldProcessBeHooked(const std::string& processName);
|
||||||
|
bool reloadGlobalConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Ժ궨<D4BA><EAB6A8>
|
||||||
|
#define PROCESS_FILTER_WHITELIST ConfigManager::ProcessFilterConfig::WHITELIST
|
||||||
|
#define PROCESS_FILTER_BLACKLIST ConfigManager::ProcessFilterConfig::BLACKLIST
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "config_manager.h"
|
||||||
#include "hook_current.h"
|
#include "hook_current.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -10,12 +11,15 @@
|
|||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <Winternl.h>
|
#include <Winternl.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#pragma comment(lib,"shlwapi.lib")
|
#pragma comment(lib,"shlwapi.lib")
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool Is64BitOS()
|
bool Is64BitOS()
|
||||||
{
|
{
|
||||||
SYSTEM_INFO sysInfo = { 0 };
|
SYSTEM_INFO sysInfo = { 0 };
|
||||||
@@ -52,11 +56,11 @@ unordered_map<DWORD, string> getSuspendProcess()
|
|||||||
);
|
);
|
||||||
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
|
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
|
||||||
|
|
||||||
LPVOID dwBufferProcess = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĻ<DDB5><C4BB><EFBFBD><EFBFBD><EFBFBD>
|
LPVOID dwBufferProcess = 0;
|
||||||
DWORD dwBufferProcessSize = 0; //<2F><>Ҫ<EFBFBD><D2AA><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݵĻ<DDB5><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
DWORD dwBufferProcessSize = 0;
|
||||||
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
|
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
|
||||||
dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000](); //Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>/<2F>߳<EFBFBD><DFB3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ͻ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x10000<30>ڴ<EFBFBD>(64K)
|
dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000]();
|
||||||
LPVOID dwOldBufferProcess = dwBufferProcess; //<2F><><EFBFBD>滺<EFBFBD><E6BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
LPVOID dwOldBufferProcess = dwBufferProcess;
|
||||||
NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
|
NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
@@ -68,87 +72,29 @@ unordered_map<DWORD, string> getSuspendProcess()
|
|||||||
int suspendThreads = 0;
|
int suspendThreads = 0;
|
||||||
for (DWORD i = 0; i < processInfo->NumberOfThreads; i++)
|
for (DWORD i = 0; i < processInfo->NumberOfThreads; i++)
|
||||||
{
|
{
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>͵<EFBFBD><CDB5>´<EFBFBD>״̬<D7B4><CCAC>ԭ<EFBFBD><D4AD>
|
|
||||||
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
|
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
|
||||||
{
|
{
|
||||||
suspendThreads++;
|
suspendThreads++;
|
||||||
}
|
}
|
||||||
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION); //ָ<><D6B8><EFBFBD>˽<EFBFBD><CBBD>̵<EFBFBD><CCB5><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>߳̽ṹ
|
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION);
|
||||||
}
|
}
|
||||||
if (suspendThreads == processInfo->NumberOfThreads)
|
if (suspendThreads == processInfo->NumberOfThreads)
|
||||||
{
|
{
|
||||||
wstring wstrName{ processInfo->ImageName.Buffer };
|
wstring wstrName{ processInfo->ImageName.Buffer };
|
||||||
suspendProcess[(DWORD)(processInfo->UniqueProcessId)] = string(wstrName.begin(), wstrName.end());
|
suspendProcess[(DWORD)(processInfo->UniqueProcessId)] = string(wstrName.begin(), wstrName.end());
|
||||||
}
|
}
|
||||||
dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset); //ָ<><D6B8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset);
|
||||||
if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><C9BD><EFBFBD>
|
if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete[] dwOldBufferProcess; //<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
delete[] dwOldBufferProcess;
|
||||||
return suspendProcess;
|
return suspendProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProcessInfo
|
|
||||||
{
|
|
||||||
string name;
|
|
||||||
bool isSuspend;
|
|
||||||
};
|
|
||||||
|
|
||||||
unordered_map<DWORD, ProcessInfo> getProcessInfo()
|
|
||||||
{
|
|
||||||
unordered_map<DWORD, ProcessInfo> 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; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĻ<DDB5><C4BB><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
DWORD dwBufferProcessSize = 0; //<2F><>Ҫ<EFBFBD><D2AA><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݵĻ<DDB5><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
||||||
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
|
|
||||||
dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000](); //Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>/<2F>߳<EFBFBD><DFB3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ͻ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x10000<30>ڴ<EFBFBD>(64K)
|
|
||||||
LPVOID dwOldBufferProcess = dwBufferProcess; //<2F><><EFBFBD>滺<EFBFBD><E6BBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>͵<EFBFBD><CDB5>´<EFBFBD>״̬<D7B4><CCAC>ԭ<EFBFBD><D4AD>
|
|
||||||
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
|
|
||||||
{
|
|
||||||
suspendThreads++;
|
|
||||||
}
|
|
||||||
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION); //ָ<><D6B8><EFBFBD>˽<EFBFBD><CBBD>̵<EFBFBD><CCB5><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>߳̽ṹ
|
|
||||||
}
|
|
||||||
|
|
||||||
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); //ָ<><D6B8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɽ<EFBFBD><C9BD><EFBFBD>
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
delete[] dwOldBufferProcess; //<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
|
|
||||||
return processInfoMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
||||||
{
|
{
|
||||||
int pathSize = (wcslen(pszDllFileName) + 1) * sizeof(wchar_t);
|
int pathSize = (wcslen(pszDllFileName) + 1) * sizeof(wchar_t);
|
||||||
|
|
||||||
// 2.<2E><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
|
|
||||||
LPVOID lpPathAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
LPVOID lpPathAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
if (NULL == lpPathAddr)
|
if (NULL == lpPathAddr)
|
||||||
{
|
{
|
||||||
@@ -156,14 +102,14 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
|||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 3.<2E><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>Dll·<6C><C2B7>
|
|
||||||
if (FALSE == WriteProcessMemory(hProcess, lpPathAddr, pszDllFileName, pathSize, NULL)) // ʵ<><CAB5>д<EFBFBD><D0B4><EFBFBD><EFBFBD>С
|
if (FALSE == WriteProcessMemory(hProcess, lpPathAddr, pszDllFileName, pathSize, NULL))
|
||||||
{
|
{
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>Dll·<EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
|
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>Dll·<EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 4.<2E><><EFBFBD><EFBFBD>ntdll.dll
|
|
||||||
HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
|
HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
|
||||||
if (NULL == hNtdll)
|
if (NULL == hNtdll)
|
||||||
{
|
{
|
||||||
@@ -171,8 +117,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
|||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 5.<2E><>ȡLoadLibraryA<79>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
||||||
// FARPROC<4F><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ32λ<32><CEBB>64λ
|
|
||||||
HMODULE hmKernel32 = LoadLibrary(_T("Kernel32.dll"));
|
HMODULE hmKernel32 = LoadLibrary(_T("Kernel32.dll"));
|
||||||
if (NULL == hmKernel32)
|
if (NULL == hmKernel32)
|
||||||
{
|
{
|
||||||
@@ -187,8 +132,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
|||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 6.<2E><>ȡZwCreateThreadEx<45><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ,<2C>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>32λ<32><CEBB>64λ<34><CEBB>ԭ<EFBFBD>Ͳ<EFBFBD>ͬ
|
|
||||||
// _WIN64<36><34><EFBFBD><EFBFBD><EFBFBD>жϱ<D0B6><CFB1>뻷<EFBFBD><EBBBB7><EFBFBD><EFBFBD>_WIN32<33><32><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Windowsϵͳ
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
|
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
|
||||||
PHANDLE ThreadHandle,
|
PHANDLE ThreadHandle,
|
||||||
@@ -225,7 +169,7 @@ bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
|
|||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 7.<2E><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>Զ<EFBFBD>߳<EFBFBD>
|
|
||||||
HANDLE hRemoteThread = NULL;
|
HANDLE hRemoteThread = NULL;
|
||||||
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
|
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
|
||||||
hProcess, (LPTHREAD_START_ROUTINE)pFuncProcAddr, lpPathAddr, 0, 0, 0, 0, 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);
|
CloseHandle(hProcess);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 8.<2E>ȴ<EFBFBD><C8B4>߳̽<DFB3><CCBD><EFBFBD>
|
|
||||||
DWORD reason = WaitForSingleObject(hRemoteThread, INFINITE);
|
DWORD reason = WaitForSingleObject(hRemoteThread, INFINITE);
|
||||||
/*if (reason == WAIT_TIMEOUT)
|
|
||||||
{
|
VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
|
||||||
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.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE); //MEM_RELEASE
|
|
||||||
CloseHandle(hRemoteThread);
|
CloseHandle(hRemoteThread);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
FreeLibrary(hNtdll);
|
FreeLibrary(hNtdll);
|
||||||
return true;
|
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<DWORD, ProcessInfo> 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.<2E><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ø<C3B8><DFBC><EFBFBD>OpenProcess API, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CSRSS<53><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
// 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__, "<22>ж<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>64λϵͳ<CFB5>е<EFBFBD>32λ<32><CEBB><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>: %d", GetLastError());
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// Log(LogLevel::LOG_WARN, __LINE__, "<22><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %s, ʧ<><CAA7>: %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)
|
bool HookCurWindow(const std::wstring& dllPath)
|
||||||
{
|
{
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOWS<<<<<<<<<<<<<<<<");
|
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOWS<<<<<<<<<<<<<<<<");
|
||||||
std::wstring DllPath{ getFullFilePath(dllPath) };
|
|
||||||
COND_LOG_RET(!DllPath.empty(), __LINE__, "DllPath.empty(): %d", GetLastError(), false);
|
|
||||||
|
|
||||||
|
|
||||||
|
// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||||
|
if (!ConfigManager::reloadGlobalConfig()) {
|
||||||
|
Log(LogLevel::LOG_WARN, __LINE__, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>ʹ<EFBFBD><EFBFBD>Ĭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ӡ<EFBFBD><D3A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||||
|
ConfigManager::Config* config = ConfigManager::getGlobalConfig();
|
||||||
|
if (config) {
|
||||||
|
config->printConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring DllPath{ getFullFilePath(dllPath) };
|
||||||
|
if (DllPath.empty()) {
|
||||||
|
Log(LogLevel::LOG_ERROR, __LINE__, "DLL·<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡʧ<EFBFBD><EFBFBD>: %d", GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unordered_map<DWORD, string> suspendProc = getSuspendProcess();
|
unordered_map<DWORD, string> suspendProc = getSuspendProcess();
|
||||||
for (auto i : suspendProc)
|
for (auto i : suspendProc)
|
||||||
{
|
{
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, "suspend process: %s", i.second.c_str());
|
Log(LogLevel::LOG_INFO, __LINE__, "suspend process: %s", i.second.c_str());
|
||||||
}
|
}
|
||||||
unordered_map<DWORD, char> tryHookedProc;//<2F><><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PID
|
|
||||||
vector<string> goodHookedProc;//<2F><><EFBFBD>ɹ<EFBFBD>hook<6F>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>
|
unordered_map<DWORD, char> tryHookedProc;
|
||||||
|
vector<string> goodHookedProc;
|
||||||
|
vector<string> filteredProc; // <20><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
|
||||||
HWND windowHandle = NULL;
|
HWND windowHandle = NULL;
|
||||||
do {
|
do {
|
||||||
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
|
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
|
||||||
@@ -335,23 +229,30 @@ bool HookCurWindow(const std::wstring& dllPath)
|
|||||||
if (GetWindowThreadProcessId(windowHandle, &dwPid)) {
|
if (GetWindowThreadProcessId(windowHandle, &dwPid)) {
|
||||||
if (tryHookedProc.find(dwPid) == tryHookedProc.end()) {
|
if (tryHookedProc.find(dwPid) == tryHookedProc.end()) {
|
||||||
tryHookedProc[dwPid] = 1;
|
tryHookedProc[dwPid] = 1;
|
||||||
|
|
||||||
if (suspendProc.find(dwPid) != suspendProc.end())
|
if (suspendProc.find(dwPid) != suspendProc.end())
|
||||||
{
|
{
|
||||||
Log(LogLevel::LOG_WARN, __LINE__, "This is a suspend process: %s", suspendProc[dwPid].c_str());
|
Log(LogLevel::LOG_WARN, __LINE__, "This is a suspend process: %s", suspendProc[dwPid].c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 0.<2E><>Ȩ
|
|
||||||
// 1.<2E><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ø<C3B8><DFBC><EFBFBD>OpenProcess API
|
|
||||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
|
||||||
if (hProcess) {
|
if (hProcess) {
|
||||||
string exeName = getProcNameByHandle(hProcess);
|
string exeName = getProcNameByHandle(hProcess);
|
||||||
exeName = (!exeName.empty() ? exeName : "Unknow ProcName");
|
exeName = (!exeName.empty() ? exeName : "Unknown ProcName");
|
||||||
|
|
||||||
|
// ʹ<><CAB9><EFBFBD>µĹ<C2B5><C4B9><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (!ConfigManager::shouldProcessBeHooked(exeName)) {
|
||||||
|
ConfigManager::Config* cfg = ConfigManager::getGlobalConfig();
|
||||||
|
Log(LogLevel::LOG_INFO, __LINE__, "<EFBFBD><EFBFBD><EFBFBD>̱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %s (ģʽ: %s)",
|
||||||
|
exeName.c_str(),
|
||||||
|
cfg && cfg->getFilterMode() == ConfigManager::ProcessFilterConfig::WHITELIST ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||||
|
filteredProc.push_back(exeName);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL procIs32bit;
|
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)) {
|
if (IsWow64Process(hProcess, &procIs32bit)) {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (!procIs32bit && is64BitOS) {
|
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());
|
Log(LogLevel::LOG_WARN, __LINE__, "It's a 64 app: %s", exeName.c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD>ж<EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>64λϵͳ<EFBFBD>е<EFBFBD>32λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>: %d", GetLastError());
|
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD>ж<EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>64λϵͳ<EFBFBD>е<EFBFBD>32λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>: %d", GetLastError());
|
||||||
@@ -391,21 +291,24 @@ bool HookCurWindow(const std::wstring& dllPath)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//cout << "<22><>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>" << endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log(LogLevel::LOG_WARN, __LINE__, "GetWindowThreadProcessId Error<6F><72>%d, HWND: %x", GetLastError(), windowHandle);
|
Log(LogLevel::LOG_WARN, __LINE__, "GetWindowThreadProcessId Error<6F><72>%d, HWND: %x", GetLastError(), windowHandle);
|
||||||
}
|
}
|
||||||
} while (windowHandle);
|
} while (windowHandle);
|
||||||
|
|
||||||
//Summary
|
//Summary
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOW END<<<<<<<<<<<<<<<<<<");
|
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOW END<<<<<<<<<<<<<<<<<<");
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, "Summary:");
|
Log(LogLevel::LOG_INFO, __LINE__, "Summary:");
|
||||||
|
Log(LogLevel::LOG_INFO, __LINE__, "<EFBFBD>ɹ<EFBFBD>Hook<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> (%zu<7A><75>):", goodHookedProc.size());
|
||||||
for (auto& i : goodHookedProc)
|
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__, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵Ľ<EFBFBD><EFBFBD><EFBFBD> (%zu<7A><75>):", filteredProc.size());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,40 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
#include "config_manager.h"
|
||||||
#pragma comment(lib,"shlwapi.lib")
|
#pragma comment(lib,"shlwapi.lib")
|
||||||
|
#pragma comment(lib,"comctl32.lib")
|
||||||
using namespace std;
|
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);
|
typedef BOOL(WINAPI* pfnSetHook) (BOOL);
|
||||||
pfnSetHook SetHook = NULL;
|
pfnSetHook SetHook = NULL;
|
||||||
|
|
||||||
@@ -19,14 +47,11 @@ const int LOG_SIZE = 512;
|
|||||||
//for ipc
|
//for ipc
|
||||||
char* pBuf;
|
char* pBuf;
|
||||||
HANDLE hServerEvent, hClientEvent, hFileMap;
|
HANDLE hServerEvent, hClientEvent, hFileMap;
|
||||||
//for save console origin color
|
|
||||||
WORD wOldColorAttrs;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
const std::wstring hideDllName{ L"Hide.dll" };
|
const std::wstring hideDllName{ L"Hide.dll" };
|
||||||
const std::wstring unhideDllName{ L"Unhide.dll" };
|
const std::wstring unhideDllName{ L"Unhide.dll" };
|
||||||
const std::wstring RtlHideDllName{L"RtlHide.dll"};
|
const std::wstring RtlHideDllName{ L"RtlHide.dll" };
|
||||||
#else
|
#else
|
||||||
const std::wstring hideDllName{ L"Hide32.dll" };
|
const std::wstring hideDllName{ L"Hide32.dll" };
|
||||||
const std::wstring unhideDllName{ L"Unhide32.dll" };
|
const std::wstring unhideDllName{ L"Unhide32.dll" };
|
||||||
@@ -34,8 +59,8 @@ const std::wstring RtlHideDllName{ L"RtlHide32.dll" };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//添加MessageBoxTimeout支持
|
//添加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* 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* MessageBoxTimeoutW)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
|
||||||
|
|
||||||
HMODULE hUser32 = LoadLibraryA("user32.dll");
|
HMODULE hUser32 = LoadLibraryA("user32.dll");
|
||||||
#ifdef UNICODE
|
#ifdef UNICODE
|
||||||
@@ -44,395 +69,451 @@ HMODULE hUser32 = LoadLibraryA("user32.dll");
|
|||||||
#define MessageBoxTimeout ((MessageBoxTimeoutA)(GetProcAddress(hUser32, "MessageBoxTimeoutA")))
|
#define MessageBoxTimeout ((MessageBoxTimeoutA)(GetProcAddress(hUser32, "MessageBoxTimeoutA")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOL WINAPI ConsoleHandler(DWORD CEvent)
|
bool g_bSelfHidden = false;
|
||||||
{
|
bool g_bHotkeyRegistered = false; // 新增:跟踪快捷键注册状态
|
||||||
switch (CEvent)
|
|
||||||
{
|
|
||||||
case CTRL_CLOSE_EVENT://close消息有限时机制
|
// 日志函数
|
||||||
HookRtlWindow(false);
|
void Log(LogLevel level, int line, const char* format, ...) {
|
||||||
MessageBoxTimeout(NULL, L"关闭实时窗口注入", L"step 1", MB_OK, 0, 1000);//MessageBox(NULL, L"关闭实时窗口注入", L"step 1", MB_OK);
|
if (!g_hLogListBox) return;
|
||||||
Sleep(1500);
|
|
||||||
HookCurWindow(unhideDllName);
|
char msg[LOG_SIZE] = { 0 };
|
||||||
MessageBox(NULL, L"还原当前所有窗口", L"step 2", MB_OK);//MessageBoxTimeout(NULL, L"还原当前所有窗口", L"step 2", MB_OK, 0, 1500);
|
char finalMsg[LOG_SIZE + 50] = { 0 };
|
||||||
break;
|
|
||||||
case CTRL_C_EVENT:
|
va_list ap;
|
||||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
va_start(ap, format);
|
||||||
break;
|
vsprintf(msg, format, ap);
|
||||||
case CTRL_BREAK_EVENT:
|
va_end(ap);
|
||||||
case CTRL_LOGOFF_EVENT:
|
|
||||||
case CTRL_SHUTDOWN_EVENT:
|
const char* levelStr = "";
|
||||||
default:
|
switch (level) {
|
||||||
return FALSE;
|
case LogLevel::LOG_INFO:
|
||||||
}
|
levelStr = "[INFO] ";
|
||||||
return TRUE;
|
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()
|
// 更新状态文本
|
||||||
{
|
void UpdateStatus(const wchar_t* status) {
|
||||||
HANDLE hToken;
|
if (g_hStatusText) {
|
||||||
TOKEN_PRIVILEGES NewState;
|
SetWindowText(g_hStatusText, status);
|
||||||
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 initFoundSet()
|
bool SetPrivilege() {
|
||||||
{
|
HANDLE hToken;
|
||||||
SetPrivilege();
|
TOKEN_PRIVILEGES NewState;
|
||||||
|
LUID luidPrivilegeLUID;
|
||||||
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) ||
|
||||||
HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE);
|
!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidPrivilegeLUID)) {
|
||||||
HANDLE_LOG_RET(hStd, __LINE__, "GetStdHandle: %x", hStd, false);
|
Log(LogLevel::LOG_WARN, __LINE__, "SetPrivilege Error: %d", GetLastError());
|
||||||
COND_LOG_RET(GetConsoleScreenBufferInfo(hStd, &csbiInfo), __LINE__, "GetConsoleScreenBufferInfo: %x", csbiInfo.wAttributes, false);
|
return false;
|
||||||
wOldColorAttrs = csbiInfo.wAttributes;
|
}
|
||||||
|
NewState.PrivilegeCount = 1;
|
||||||
COND_LOG_RET(SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE), __LINE__, "SetConsoleCtrlHandler: %x", ConsoleHandler, false);
|
NewState.Privileges[0].Luid = luidPrivilegeLUID;
|
||||||
return true;
|
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)
|
bool FileExists(std::wstring& filePath) {
|
||||||
{
|
DWORD dwAttrib = GetFileAttributes(filePath.c_str());
|
||||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //获取缓冲区句柄
|
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||||
if (wAttributes == 0)
|
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring getFullFilePath(const std::wstring& filename) {
|
std::wstring getFullFilePath(const std::wstring& filename) {
|
||||||
wchar_t fullPath[MAX_PATH] = {0};
|
wchar_t fullPath[MAX_PATH] = { 0 };
|
||||||
GetModuleFileName(NULL, fullPath, MAX_PATH);
|
GetModuleFileName(NULL, fullPath, MAX_PATH);
|
||||||
PathRemoveFileSpec(fullPath);
|
PathRemoveFileSpec(fullPath);
|
||||||
PathAppend(fullPath, filename.c_str());
|
PathAppend(fullPath, filename.c_str());
|
||||||
std::wstring strFullPath{ fullPath };
|
std::wstring strFullPath{ fullPath };
|
||||||
COND_LOG_RET(FileExists(strFullPath), __LINE__, "FileExists: %S", strFullPath.c_str(), std::wstring{});
|
if (!FileExists(strFullPath)) {
|
||||||
return 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
|
#ifdef _WIN64
|
||||||
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "SetHook");
|
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "SetHook");
|
||||||
#else
|
#else
|
||||||
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "_SetHook@4");
|
SetHook = (pfnSetHook)GetProcAddress(RtlHideDll, "_SetHook@4");
|
||||||
#endif
|
#endif
|
||||||
if (SetHook)
|
|
||||||
{
|
if (!SetHook) {
|
||||||
if (hook)
|
Log(LogLevel::LOG_ERROR, __LINE__, "GetProcAddress SetHook Error: %d", GetLastError());
|
||||||
{
|
return false;
|
||||||
if (SetHook(TRUE))
|
}
|
||||||
{
|
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, "Set Hook Success");
|
if (hook) {
|
||||||
return true;
|
if (SetHook(TRUE)) {
|
||||||
}
|
Log(LogLevel::LOG_INFO, __LINE__, "Set Hook Success");
|
||||||
else
|
g_bRtlHookEnabled = true;
|
||||||
{
|
UpdateStatus(L"状态: 实时钩子已启用");
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "Set Hook Error. See More in DebugView");
|
return true;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else
|
Log(LogLevel::LOG_ERROR, __LINE__, "Set Hook Error. See More in DebugView");
|
||||||
{
|
}
|
||||||
if (SetHook(FALSE))
|
}
|
||||||
{
|
else {
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, "Set Unhook Success");
|
if (SetHook(FALSE)) {
|
||||||
return true;
|
Log(LogLevel::LOG_INFO, __LINE__, "Set Unhook Success");
|
||||||
}
|
g_bRtlHookEnabled = false;
|
||||||
else
|
UpdateStatus(L"状态: 实时钩子已禁用");
|
||||||
{
|
return true;
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "Set Unhook Error. See More in DebugView");
|
}
|
||||||
}
|
else {
|
||||||
}
|
Log(LogLevel::LOG_ERROR, __LINE__, "Set Unhook Error. See More in DebugView");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
{
|
}
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "GetProcAddress SetHook Error: %d", GetLastError());
|
// 修改HideSelf函数:只有快捷键注册成功时才允许隐藏
|
||||||
}
|
void HideSelf() {
|
||||||
}
|
if (!g_bHotkeyRegistered) {
|
||||||
else
|
Log(LogLevel::LOG_ERROR, __LINE__, "无法隐藏:全局快捷键未注册");
|
||||||
{
|
return;
|
||||||
Log(LogLevel::LOG_ERROR, __LINE__, "LoadLibrary %S Error: %d", RtlHideDllName.c_str(), GetLastError());
|
}
|
||||||
}
|
|
||||||
return false;
|
if (g_hMainWnd) {
|
||||||
|
ShowWindow(g_hMainWnd, SW_HIDE);
|
||||||
|
g_bSelfHidden = true;
|
||||||
|
UpdateStatus(L"状态: 程序已隐藏");
|
||||||
|
Log(LogLevel::LOG_INFO, __LINE__, "程序窗口已隐藏");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HandleName
|
HANDLE CreateGlobalEvent(string& eventName) {
|
||||||
{
|
SECURITY_ATTRIBUTES sa;
|
||||||
HANDLE handle;
|
sa.bInheritHandle = FALSE;
|
||||||
string name;
|
sa.lpSecurityDescriptor = NULL;
|
||||||
};
|
sa.nLength = sizeof(sa);
|
||||||
struct ShareMemory {
|
if (eventName.find("Global\\") == eventName.npos) {
|
||||||
HANDLE hFileMap;
|
eventName = "Global\\" + eventName;
|
||||||
char* pShareBuf;
|
}
|
||||||
void clear() {
|
return CreateEventA(&sa, FALSE, FALSE, eventName.c_str());
|
||||||
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)
|
HANDLE CreateGlobalFileMap(string& fileMapName) {
|
||||||
{
|
if (fileMapName.find("Global\\") == fileMapName.npos) {
|
||||||
SECURITY_ATTRIBUTES sa;
|
fileMapName = "Global\\" + fileMapName;
|
||||||
sa.bInheritHandle = FALSE;
|
}
|
||||||
sa.lpSecurityDescriptor = NULL;
|
return CreateFileMappingA(
|
||||||
sa.nLength = sizeof(sa);
|
INVALID_HANDLE_VALUE,
|
||||||
if (eventName.find("Global\\") == eventName.npos)
|
NULL,
|
||||||
{
|
PAGE_READWRITE,
|
||||||
eventName = "Global\\" + eventName;
|
0,
|
||||||
}
|
FILEMAP_BUF,
|
||||||
return CreateEventA(&sa, FALSE, FALSE, eventName.c_str());
|
fileMapName.c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE CreateGlobalFileMap(string& fileMapName)
|
bool initIPCEnvironment() {
|
||||||
{
|
string baseName = to_string(GetCurrentProcessId());
|
||||||
if (fileMapName.find("Global\\") == fileMapName.npos)
|
string serverEventName = baseName + "-ServerEvent";
|
||||||
{
|
string clientEventName = baseName + "-ClientEvent";
|
||||||
fileMapName = "Global\\" + fileMapName;
|
string fileMapName = baseName + "-FileMap";
|
||||||
}
|
|
||||||
return CreateFileMappingA(
|
hServerEvent = CreateGlobalEvent(serverEventName);
|
||||||
INVALID_HANDLE_VALUE, //物理文件句柄,设为INVALID_HANDLE_VALUE(无效句柄)以创建一个进程间共享的对象
|
if (!hServerEvent) {
|
||||||
NULL, //默认安全级别
|
Log(LogLevel::LOG_ERROR, __LINE__, "CreateGlobalEvent: %s failed", serverEventName.c_str());
|
||||||
PAGE_READWRITE, //权限可读可写
|
return false;
|
||||||
0, //高位文件大小
|
}
|
||||||
FILEMAP_BUF, //低位文件大小
|
|
||||||
fileMapName.c_str() //共享内存名
|
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()
|
void CleanupIPC() {
|
||||||
{
|
if (pBuf) {
|
||||||
string baseName = to_string(GetCurrentProcessId());
|
UnmapViewOfFile(pBuf);
|
||||||
string serverEventName = baseName + "-ServerEvent";
|
pBuf = NULL;
|
||||||
string clientEventName = baseName + "-ClientEvent";
|
}
|
||||||
string fileMapName = baseName + "-FileMap";
|
if (hFileMap) {
|
||||||
//服务端信号
|
CloseHandle(hFileMap);
|
||||||
hServerEvent = CreateGlobalEvent(serverEventName);
|
hFileMap = NULL;
|
||||||
COND_LOG_RET(hServerEvent, __LINE__, "CreateGlobalEvent: %s", serverEventName.c_str(), 1);
|
}
|
||||||
//客户端信号
|
if (hServerEvent) {
|
||||||
hClientEvent = CreateGlobalEvent(clientEventName);
|
CloseHandle(hServerEvent);
|
||||||
COND_LOG_RET(hClientEvent, __LINE__, "CreateGlobalEvent: %s", clientEventName.c_str(), 1);
|
hServerEvent = NULL;
|
||||||
|
}
|
||||||
//1.创建共享文件句柄 hMapFile,CreateFileMapping()函数创建一个文件映射内核对象
|
if (hClientEvent) {
|
||||||
hFileMap = CreateGlobalFileMap(fileMapName);
|
CloseHandle(hClientEvent);
|
||||||
COND_LOG_RET(hFileMap, __LINE__, "CreateGlobalFileMap: %s", fileMapName.c_str(), 1);
|
hClientEvent = NULL;
|
||||||
|
}
|
||||||
//2.获取指向文件视图的指针 pBuf,MapViewOfFile()函数负责把文件数据映射到进程的地址空间
|
g_bIPCInitialized = false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
// 处理按钮点击事件
|
||||||
{
|
void OnButtonClick(int buttonId) {
|
||||||
COND_LOG_RET(initFoundSet(), __LINE__, "initFoundSet()(ZeroSuccess): %d", GetLastError(), 1);
|
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);
|
case IDC_BUTTON_SHOW:
|
||||||
|
Log(LogLevel::LOG_INFO, __LINE__, "执行显示窗口操作...");
|
||||||
COND_LOG_RET(HookCurWindow(hideDllName), __LINE__, "HookCurWindow(hideDllName)(ZeroSuccess): %d", GetLastError(), 1);
|
if (HookCurWindow(unhideDllName)) {
|
||||||
|
Log(LogLevel::LOG_INFO, __LINE__, "窗口显示操作完成");
|
||||||
|
UpdateStatus(L"状态: 窗口已显示");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
COND_LOG_RET(HookRtlWindow(true), __LINE__, "HookRtlWindow(true)(ZeroSuccess): %d", GetLastError(), 1);
|
case IDC_BUTTON_HOOK_RTL:
|
||||||
|
if (!g_bRtlHookEnabled) {
|
||||||
strcpy_s(pBuf, FILEMAP_BUF, "hello");
|
Log(LogLevel::LOG_INFO, __LINE__, "启用实时钩子...");
|
||||||
COND_LOG_RET(SetEvent(hServerEvent), __LINE__, "SetEvent: %x", hServerEvent, 1);
|
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)
|
case IDC_BUTTON_DEBUG:
|
||||||
{
|
if (g_bIPCInitialized && pBuf) {
|
||||||
__GetEvent(hClientEvent, INFINITE);
|
strcpy_s(pBuf, FILEMAP_BUF, "debug");
|
||||||
if (pBuf)
|
SetEvent(hServerEvent);
|
||||||
{
|
Log(LogLevel::LOG_INFO, __LINE__, "发送调试命令");
|
||||||
Log(LogLevel::LOG_INFO, __LINE__, "收到控制信息: %s", pBuf);
|
}
|
||||||
if (string(pBuf) == "stop")
|
else {
|
||||||
{
|
Log(LogLevel::LOG_ERROR, __LINE__, "IPC未初始化,无法发送命令");
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
else if (string(pBuf) == "debug")//显示本身控制台程序
|
|
||||||
{
|
case IDC_BUTTON_STOP:
|
||||||
ShowWindow(GetConsoleWindow(), SW_SHOWNA);
|
if (g_bIPCInitialized && pBuf) {
|
||||||
/*DWORD lasterror = GetLastError();
|
strcpy_s(pBuf, FILEMAP_BUF, "stop");
|
||||||
auto getLogDir = []() ->string {
|
SetEvent(hServerEvent);
|
||||||
char dir[MAX_PATH];
|
Log(LogLevel::LOG_INFO, __LINE__, "发送停止命令");
|
||||||
GetModuleFileNameA(NULL, dir, MAX_PATH);
|
}
|
||||||
PathRemoveFileSpecA(dir);
|
break;
|
||||||
#ifdef _WIN64
|
|
||||||
PathAppendA(dir, "log.txt");
|
case IDC_BUTTON_CLEAR_LOG:
|
||||||
#else
|
SendMessage(g_hLogListBox, LB_RESETCONTENT, 0, 0);
|
||||||
PathAppendA(dir, "log32.txt");
|
Log(LogLevel::LOG_INFO, __LINE__, "日志已清空");
|
||||||
#endif
|
break;
|
||||||
return string{ dir };
|
|
||||||
};
|
case IDC_BUTTON_VISBLE_SELF:
|
||||||
auto dir = getLogDir();
|
Log(LogLevel::LOG_INFO, __LINE__, "执行隐藏自身操作...");
|
||||||
if (!dir.empty())
|
HideSelf();
|
||||||
{
|
break;
|
||||||
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);
|
// 窗口过程函数
|
||||||
}
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch (msg) {
|
||||||
}*/
|
case WM_CREATE:
|
||||||
__SetEvent(hServerEvent);
|
{
|
||||||
}
|
// 创建控件
|
||||||
}
|
CreateWindow(L"BUTTON", L"隐藏窗口", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
|
||||||
}
|
10, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_HIDE, g_hInst, NULL);
|
||||||
COND_LOG_RET(HookRtlWindow(false), __LINE__, "HookRtlWindow(false)(ZeroSuccess): %d", GetLastError(), 1);
|
|
||||||
Sleep(1500);
|
CreateWindow(L"BUTTON", L"显示窗口", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
|
||||||
COND_LOG_RET(HookCurWindow(unhideDllName), __LINE__, "HookCurWindow(unhideDllName)(ZeroSuccess): %d", GetLastError(), 1);
|
120, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_SHOW, g_hInst, NULL);
|
||||||
__SetEvent(hServerEvent);
|
|
||||||
//释放资源
|
CreateWindow(L"BUTTON", L"启用实时钩子", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
|
||||||
CloseHandle(hServerEvent);
|
230, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_HOOK_RTL, g_hInst, NULL);
|
||||||
CloseHandle(hClientEvent);
|
|
||||||
if (pBuf) UnmapViewOfFile(pBuf);
|
CreateWindow(L"BUTTON", L"禁用实时钩子", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
|
||||||
CloseHandle(hFileMap);
|
340, 10, 100, 30, hwnd, (HMENU)IDC_BUTTON_UNHOOK_RTL, g_hInst, NULL);
|
||||||
return 0;
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
385
ConfigManager/ConfigManager.cpp
Normal file
385
ConfigManager/ConfigManager.cpp
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
// ConfigManager.cpp : 定义静态库的函数。
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "framework.h"
|
||||||
|
#include "ConfigManager.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
#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<std::string> Config::getProcessList() const {
|
||||||
|
std::vector<std::string> 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
|
||||||
107
ConfigManager/ConfigManager.h
Normal file
107
ConfigManager/ConfigManager.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
#pragma once
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̹<EFBFBD><CCB9>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
||||||
|
*/
|
||||||
|
namespace ConfigManager {
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ýṹ
|
||||||
|
struct ProcessFilterConfig {
|
||||||
|
enum FilterMode {
|
||||||
|
WHITELIST, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>еĽ<D0B5><C4BD><EFBFBD>
|
||||||
|
BLACKLIST // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterMode mode = WHITELIST;
|
||||||
|
std::unordered_set<std::string> processList;
|
||||||
|
bool caseSensitive = false;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
class Config {
|
||||||
|
private:
|
||||||
|
ProcessFilterConfig m_filterConfig;
|
||||||
|
std::string m_configFilePath;
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ߺ<EFBFBD><DFBA><EFBFBD>
|
||||||
|
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;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void setConfigPath(const std::string& configPath);
|
||||||
|
std::string getConfigPath() const;
|
||||||
|
std::string getDefaultConfigPath() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ü<EFBFBD><C3BC>غͱ<D8BA><CDB1><EFBFBD>
|
||||||
|
bool loadConfig();
|
||||||
|
bool loadConfig(const std::string& configPath);
|
||||||
|
bool saveDefaultConfig() const;
|
||||||
|
bool saveDefaultConfig(const std::string& configPath) const;
|
||||||
|
bool reloadConfig();
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
|
||||||
|
const ProcessFilterConfig& getProcessFilterConfig() const;
|
||||||
|
ProcessFilterConfig& getProcessFilterConfig();
|
||||||
|
|
||||||
|
// <20><><EFBFBD>̹<EFBFBD><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><D8B7><EFBFBD>
|
||||||
|
bool shouldProcessBeHooked(const std::string& processName) const;
|
||||||
|
void setFilterMode(ProcessFilterConfig::FilterMode mode);
|
||||||
|
ProcessFilterConfig::FilterMode getFilterMode() const;
|
||||||
|
void setCaseSensitive(bool sensitive);
|
||||||
|
bool isCaseSensitive() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void addProcess(const std::string& processName);
|
||||||
|
void removeProcess(const std::string& processName);
|
||||||
|
void clearProcessList();
|
||||||
|
std::vector<std::string> getProcessList() const;
|
||||||
|
size_t getProcessCount() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||||
|
bool isConfigValid() const;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
void printConfig() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD>
|
||||||
|
bool initializeGlobalConfig();
|
||||||
|
bool initializeGlobalConfig(const std::string& configPath);
|
||||||
|
Config* getGlobalConfig();
|
||||||
|
void cleanupGlobalConfig();
|
||||||
|
|
||||||
|
// ֱ<>Ӳ<EFBFBD><D3B2><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>õı<C3B5><C4B1>ݺ<EFBFBD><DDBA><EFBFBD>
|
||||||
|
bool shouldProcessBeHooked(const std::string& processName);
|
||||||
|
bool reloadGlobalConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Ժ궨<D4BA><EAB6A8>
|
||||||
|
#define PROCESS_FILTER_WHITELIST ConfigManager::ProcessFilterConfig::WHITELIST
|
||||||
|
#define PROCESS_FILTER_BLACKLIST ConfigManager::ProcessFilterConfig::BLACKLIST
|
||||||
155
ConfigManager/ConfigManager.vcxproj
Normal file
155
ConfigManager/ConfigManager.vcxproj
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{b5afeb98-c976-4839-9a8e-4f48b057d7fd}</ProjectGuid>
|
||||||
|
<RootNamespace>ConfigManager</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>
|
||||||
|
</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>
|
||||||
|
</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>
|
||||||
|
</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>
|
||||||
|
</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ConfigManager.h" />
|
||||||
|
<ClInclude Include="framework.h" />
|
||||||
|
<ClInclude Include="pch.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ConfigManager.cpp" />
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
36
ConfigManager/ConfigManager.vcxproj.filters
Normal file
36
ConfigManager/ConfigManager.vcxproj.filters
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="源文件">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="头文件">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="资源文件">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="framework.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="pch.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ConfigManager.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ConfigManager.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
3
ConfigManager/framework.h
Normal file
3
ConfigManager/framework.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
|
||||||
5
ConfigManager/pch.cpp
Normal file
5
ConfigManager/pch.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// pch.cpp: 与预编译标头对应的源文件
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
|
||||||
13
ConfigManager/pch.h
Normal file
13
ConfigManager/pch.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// pch.h: 这是预编译标头文件。
|
||||||
|
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
|
||||||
|
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
|
||||||
|
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
|
||||||
|
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
|
||||||
|
|
||||||
|
#ifndef PCH_H
|
||||||
|
#define PCH_H
|
||||||
|
|
||||||
|
// 添加要在此处预编译的标头
|
||||||
|
#include "framework.h"
|
||||||
|
|
||||||
|
#endif //PCH_H
|
||||||
@@ -29,26 +29,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
|
|||||||
GetWindowThreadProcessId(hwnd, &processId);
|
GetWindowThreadProcessId(hwnd, &processId);
|
||||||
if (processId == GetCurrentProcessId())
|
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 };
|
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);
|
haveRect = (rect.right - rect.left > 0) && (rect.bottom - rect.top > 0);
|
||||||
isMinimized = !haveRect;
|
isMinimized = !haveRect;
|
||||||
}
|
}
|
||||||
|
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
|
||||||
|
& ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
|
||||||
|
|
||||||
|
|
||||||
//summary
|
//summary
|
||||||
char summary[512] = { 0 };
|
char summary[512] = { 0 };
|
||||||
@@ -66,7 +69,7 @@ void setDAForWindows() {
|
|||||||
HWND windowHandle = NULL;
|
HWND windowHandle = NULL;
|
||||||
do {
|
do {
|
||||||
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
|
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 };
|
char title[MAX_PATH] = { 0 };
|
||||||
@@ -81,6 +84,9 @@ void setDAForWindows() {
|
|||||||
isMinimized = !haveRect;
|
isMinimized = !haveRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetWindowLong(windowHandle, GWL_EXSTYLE, GetWindowLong(windowHandle, GWL_EXSTYLE)
|
||||||
|
& ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
|
||||||
|
|
||||||
//summary
|
//summary
|
||||||
char summary[512] = { 0 };
|
char summary[512] = { 0 };
|
||||||
sprintf(summary, "进程名:%s, 窗口句柄:%x, 标题:%s, 最小化:%d, 状态:隐藏", procName.c_str(), windowHandle, title, isMinimized);//bool isMinimized不能转成%s
|
sprintf(summary, "进程名:%s, 窗口句柄:%x, 标题:%s, 最小化:%d, 状态:隐藏", procName.c_str(), windowHandle, title, isMinimized);//bool isMinimized不能转成%s
|
||||||
|
|||||||
@@ -30,26 +30,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -168,6 +168,11 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\ConfigManager\ConfigManager.vcxproj">
|
||||||
|
<Project>{b5afeb98-c976-4839-9a8e-4f48b057d7fd}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -4,29 +4,62 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
#include "../ConfigManager/ConfigManager.h"
|
||||||
|
#include <psapi.h> // 必须
|
||||||
|
#pragma comment(lib, "psapi.lib")
|
||||||
#pragma comment(lib,"shlwapi.lib")
|
#pragma comment(lib,"shlwapi.lib")
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void OutputErrorString(const char* text, const char* file, int line)
|
void OutputErrorString(const char* text, const char* file, int line)
|
||||||
{
|
{
|
||||||
char msg[512] = { 0 };
|
char msg[512] = { 0 };
|
||||||
sprintf(msg, "[%s:%d] %s:%d", file, line, text, GetLastError());
|
sprintf(msg, "[%s:%d] %s:%d", file, line, text, GetLastError());
|
||||||
OutputDebugStringA(msg);
|
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()
|
string getProcName()
|
||||||
{
|
{
|
||||||
char szProcName[MAX_PATH] = { 0 };
|
char szProcName[MAX_PATH] = { 0 };
|
||||||
if (GetModuleFileNameA(NULL, szProcName, MAX_PATH))
|
if (GetModuleFileNameA(NULL, szProcName, MAX_PATH))
|
||||||
{
|
{
|
||||||
PathStripPathA(szProcName);
|
PathStripPathA(szProcName);
|
||||||
return szProcName;
|
return szProcName;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OutputErrorString("GetModuleFileNameA failed", __FILE__, __LINE__);
|
OutputErrorString("GetModuleFileNameA failed", __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
return string{ "false" };
|
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();
|
string procName = getProcName();
|
||||||
@@ -35,101 +68,118 @@ unordered_map<HWND, char> hastryHookedProc;
|
|||||||
|
|
||||||
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
// 一般来说,所有运行的进程(有窗口过程的)都会加载这个钩子过程了
|
// 一般来说,所有运行的进程(有窗口过程的)都会加载这个钩子过程了
|
||||||
CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
|
CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
|
||||||
switch (pCwp->message)
|
|
||||||
{
|
switch (pCwp->message)
|
||||||
case WM_CREATE:
|
{
|
||||||
{
|
case WM_CREATE:
|
||||||
if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
|
{
|
||||||
{
|
if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
|
||||||
if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_MONITOR))
|
{
|
||||||
{
|
|
||||||
char title[MAX_PATH] = { 0 };
|
DWORD dwPid;
|
||||||
GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
|
GetWindowThreadProcessId(pCwp->hwnd, &dwPid); // Change windowHandle to pCwp->hwnd
|
||||||
char msg[512] = { 0 };
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
|
||||||
if (title[0] != '\0')
|
if (!hProcess) return CallNextHookEx(hHook, nCode, wParam, lParam);
|
||||||
sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), title);
|
string exeName = getProcNameByHandle(hProcess);
|
||||||
else
|
if (ConfigManager::shouldProcessBeHooked(exeName)) {
|
||||||
sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), "NoTitle");
|
if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_EXCLUDEFROMCAPTURE))
|
||||||
OutputDebugStringA(msg);
|
{
|
||||||
}
|
|
||||||
hastryHookedProc[pCwp->hwnd] = 1;
|
SetWindowLong(pCwp->hwnd, GWL_EXSTYLE, GetWindowLong(pCwp->hwnd, GWL_EXSTYLE)
|
||||||
}
|
& ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
|
||||||
break;
|
|
||||||
}
|
char title[MAX_PATH] = { 0 };
|
||||||
case WM_SHOWWINDOW:
|
GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
|
||||||
{
|
char msg[512] = { 0 };
|
||||||
if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
|
if (title[0] != '\0')
|
||||||
{
|
sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), title);
|
||||||
if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_MONITOR))
|
else
|
||||||
{
|
sprintf(msg, "WM_CREATE[%s]:%s", procName.c_str(), "NoTitle");
|
||||||
char title[MAX_PATH] = { 0 };
|
OutputDebugStringA(msg);
|
||||||
GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
|
}
|
||||||
char msg[512] = { 0 };
|
}
|
||||||
if (title[0] != '\0')
|
CloseHandle(hProcess);
|
||||||
sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), title);
|
hastryHookedProc[pCwp->hwnd] = 1;
|
||||||
else
|
}
|
||||||
sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), "NoTitle");
|
break;
|
||||||
OutputDebugStringA(msg);
|
}
|
||||||
}
|
case WM_SHOWWINDOW:
|
||||||
hastryHookedProc[pCwp->hwnd] = 1;
|
{
|
||||||
}
|
if (hastryHookedProc.find(pCwp->hwnd) == hastryHookedProc.end())
|
||||||
break;
|
{
|
||||||
}
|
if (SetWindowDisplayAffinity(pCwp->hwnd, WDA_EXCLUDEFROMCAPTURE))
|
||||||
/*case WM_CLOSE:
|
{
|
||||||
{
|
SetWindowLong(pCwp->hwnd, GWL_EXSTYLE, GetWindowLong(pCwp->hwnd, GWL_EXSTYLE)
|
||||||
char title[MAX_PATH] = { 0 };
|
& ~WS_EX_APPWINDOW | WS_EX_TOOLWINDOW);
|
||||||
GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
|
|
||||||
OutputDebugStringA((string(pname) + title + " close").c_str());
|
char title[MAX_PATH] = { 0 };
|
||||||
break;
|
GetWindowTextA(pCwp->hwnd, title, MAX_PATH);
|
||||||
}*/
|
char msg[512] = { 0 };
|
||||||
|
if (title[0] != '\0')
|
||||||
default:
|
sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), title);
|
||||||
break;
|
else
|
||||||
}
|
sprintf(msg, "WM_SHOWWINDOW[%s]:%s", procName.c_str(), "NoTitle");
|
||||||
return CallNextHookEx(hHook, nCode, wParam, lParam);
|
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)
|
EXPORT BOOL WINAPI SetHook(BOOL isInstall)
|
||||||
{
|
{
|
||||||
if (isInstall)
|
if (isInstall)
|
||||||
{
|
{
|
||||||
hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);
|
hHook = SetWindowsHookEx(WH_CALLWNDPROC, HookProc, hInstance, 0);
|
||||||
if (hHook) OutputDebugStringA("SetWindowsHookEx Success");
|
if (hHook) OutputDebugStringA("SetWindowsHookEx Success");
|
||||||
return hHook != NULL;
|
return hHook != NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (UnhookWindowsHookEx(hHook))
|
if (UnhookWindowsHookEx(hHook))
|
||||||
{
|
{
|
||||||
OutputDebugStringA("UnhookWindowsHookEx Success");
|
OutputDebugStringA("UnhookWindowsHookEx Success");
|
||||||
hHook = NULL;
|
hHook = NULL;
|
||||||
hInstance = NULL;
|
hInstance = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
DWORD ul_reason_for_call,
|
DWORD ul_reason_for_call,
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch (ul_reason_for_call)
|
switch (ul_reason_for_call)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
//OutputDebugStringA(("进入:" + procName).c_str());
|
//OutputDebugStringA(("进入:" + procName).c_str());
|
||||||
hInstance = (HINSTANCE)hModule;
|
hInstance = (HINSTANCE)hModule;
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
//OutputDebugStringA(("离开:" + procName).c_str());
|
//OutputDebugStringA(("离开:" + procName).c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,26 +29,26 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v142</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
|
|||||||
char title[MAX_PATH] = { 0 };
|
char title[MAX_PATH] = { 0 };
|
||||||
GetWindowTextA(hwnd, title, MAX_PATH);
|
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;
|
RECT rect;
|
||||||
bool haveRect = false, isMinimized = false;
|
bool haveRect = false, isMinimized = false;
|
||||||
@@ -72,6 +78,12 @@ void setDAForWindows() {
|
|||||||
char title[MAX_PATH] = { 0 };
|
char title[MAX_PATH] = { 0 };
|
||||||
GetWindowTextA(windowHandle, title, MAX_PATH);
|
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;
|
RECT rect;
|
||||||
bool haveRect = false, isMinimized = false;
|
bool haveRect = false, isMinimized = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user