Files
FuckScreenCap/AntiScreenCap/hook_current.cpp

314 lines
9.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#define _CRT_SECURE_NO_WARNINGS
#include "main.h"
#include "config_manager.h"
#include "hook_current.h"
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
#include <psapi.h>
#include <Shlwapi.h>
#include <tchar.h>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <Winternl.h>
#include <fstream>
#include <sstream>
#include <algorithm>
#pragma comment(lib,"shlwapi.lib")
using namespace std;
bool Is64BitOS()
{
SYSTEM_INFO sysInfo = { 0 };
GetNativeSystemInfo(&sysInfo);
if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64
|| sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
{
return true;
}
return false;
}
bool is64BitOS = Is64BitOS();
string getProcNameByHandle(HANDLE hProcess)
{
char exeName[MAX_PATH] = { 0 };
if (GetModuleFileNameExA(hProcess, NULL, exeName, MAX_PATH))
{
PathStripPathA(exeName);
return exeName;
}
Log(LogLevel::LOG_WARN, __LINE__, "getProcNameByHandle GetModuleFileNameExA Error: %d", GetLastError());
return {};
}
unordered_map<DWORD, string> getSuspendProcess()
{
unordered_map<DWORD, string> suspendProcess;
typedef NTSTATUS(NTAPI* pfnNtQuerySystemInformation)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
pfnNtQuerySystemInformation NtQuerySystemInformation = (pfnNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
LPVOID dwBufferProcess = 0;
DWORD dwBufferProcessSize = 0;
NtQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwBufferProcessSize);
dwBufferProcess = new BYTE[dwBufferProcessSize + 0x10000]();
LPVOID dwOldBufferProcess = dwBufferProcess;
NtQuerySystemInformation(SystemProcessInformation, dwBufferProcess, dwBufferProcessSize + 0x10000, &dwBufferProcessSize);
while (TRUE)
{
LPVOID dwAddress = dwBufferProcess;
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_PROCESS_INFORMATION);
PSYSTEM_PROCESS_INFORMATION processInfo = (PSYSTEM_PROCESS_INFORMATION)dwAddress;
int suspendThreads = 0;
for (DWORD i = 0; i < processInfo->NumberOfThreads; i++)
{
if (((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->ThreadState == 5 && ((SYSTEM_THREAD_INFORMATION*)dwBufferProcess)->WaitReason == 5)
{
suspendThreads++;
}
dwBufferProcess = (BYTE*)dwBufferProcess + sizeof(SYSTEM_THREAD_INFORMATION);
}
if (suspendThreads == processInfo->NumberOfThreads)
{
wstring wstrName{ processInfo->ImageName.Buffer };
suspendProcess[(DWORD)(processInfo->UniqueProcessId)] = string(wstrName.begin(), wstrName.end());
}
dwBufferProcess = ((BYTE*)dwAddress + ((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset);
if (((SYSTEM_PROCESS_INFORMATION*)dwAddress)->NextEntryOffset == 0)
break;
}
delete[] dwOldBufferProcess;
return suspendProcess;
}
bool ZwCreateThreadExInjectDll(HANDLE hProcess, const wchar_t* pszDllFileName)
{
int pathSize = (wcslen(pszDllFileName) + 1) * sizeof(wchar_t);
LPVOID lpPathAddr = VirtualAllocEx(hProcess, 0, pathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (NULL == lpPathAddr)
{
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
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());
CloseHandle(hProcess);
return false;
}
HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
if (NULL == hNtdll)
{
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ntdll.dllʧ<6C>ܣ<EFBFBD><DCA3><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
HMODULE hmKernel32 = LoadLibrary(_T("Kernel32.dll"));
if (NULL == hmKernel32)
{
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Kernel32.dllʧ<6C>ܣ<EFBFBD><DCA3><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
FARPROC pFuncProcAddr = GetProcAddress(hmKernel32, "LoadLibraryW");
if (NULL == pFuncProcAddr)
{
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD>ȡLoadLibrary<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown
);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown
);
#endif
typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
if (NULL == ZwCreateThreadEx)
{
Log(LogLevel::LOG_ERROR, __LINE__, "<EFBFBD><EFBFBD>ȡZwCreateThreadEx<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
HANDLE hRemoteThread = NULL;
DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
hProcess, (LPTHREAD_START_ROUTINE)pFuncProcAddr, lpPathAddr, 0, 0, 0, 0, NULL);
if (NULL == hRemoteThread)
{
Log(LogLevel::LOG_ERROR, __LINE__, "Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>%d", GetLastError());
CloseHandle(hProcess);
return false;
}
DWORD reason = WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
FreeLibrary(hNtdll);
return true;
}
bool HookCurWindow(const std::wstring& dllPath)
{
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOWS<<<<<<<<<<<<<<<<");
// <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();
for (auto i : suspendProc)
{
Log(LogLevel::LOG_INFO, __LINE__, "suspend process: %s", i.second.c_str());
}
unordered_map<DWORD, char> tryHookedProc;
vector<string> goodHookedProc;
vector<string> filteredProc; // <20><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>Ľ<EFBFBD><C4BD><EFBFBD>
HWND windowHandle = NULL;
do {
windowHandle = FindWindowEx(NULL, windowHandle, NULL, NULL);
DWORD dwPid;
if (GetWindowThreadProcessId(windowHandle, &dwPid)) {
if (tryHookedProc.find(dwPid) == tryHookedProc.end()) {
tryHookedProc[dwPid] = 1;
if (suspendProc.find(dwPid) != suspendProc.end())
{
Log(LogLevel::LOG_WARN, __LINE__, "This is a suspend process: %s", suspendProc[dwPid].c_str());
continue;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess) {
string exeName = getProcNameByHandle(hProcess);
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;
if (IsWow64Process(hProcess, &procIs32bit)) {
#ifdef _WIN64
if (!procIs32bit && is64BitOS) {
if (ZwCreateThreadExInjectDll(hProcess, DllPath.c_str())) {
Log(LogLevel::LOG_INFO, __LINE__, "Hook Window For: %s", exeName.c_str());
goodHookedProc.push_back(exeName);
}
else
Log(LogLevel::LOG_WARN, __LINE__, "Hook Window Failed: %s", exeName.c_str());
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "It's a 32 app: %s", exeName.c_str());
}
#else
if (procIs32bit || (!procIs32bit && !is64BitOS)) {
Log(LogLevel::LOG_INFO, __LINE__, "ready inject: %s", exeName.c_str());
if (ZwCreateThreadExInjectDll(hProcess, DllPath.c_str())) {
Log(LogLevel::LOG_INFO, __LINE__, "Hook Window For: %s", exeName.c_str());
goodHookedProc.push_back(exeName);
}
else
Log(LogLevel::LOG_WARN, __LINE__, "Hook Window Failed: %s", exeName.c_str());
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "It's a 64 app: %s", exeName.c_str());
}
#endif
}
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());
continue;
}
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d, ʧ<><CAA7>: %d", dwPid, GetLastError());
continue;
}
}
}
else {
Log(LogLevel::LOG_WARN, __LINE__, "GetWindowThreadProcessId Error<6F><72>%d, HWND: %x", GetLastError(), windowHandle);
}
} while (windowHandle);
//Summary
Log(LogLevel::LOG_INFO, __LINE__, ">>>>>>>>>>>>>>>>HOOK CURRENT WINDOW END<<<<<<<<<<<<<<<<<<");
Log(LogLevel::LOG_INFO, __LINE__, "Summary:");
Log(LogLevel::LOG_INFO, __LINE__, "<EFBFBD>ɹ<EFBFBD>Hook<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD> (%zu<7A><75>):", goodHookedProc.size());
for (auto& i : goodHookedProc)
{
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;
}