Files
2025-05-14 01:38:43 +08:00

269 lines
6.9 KiB
C++

#include "memory.hpp"
#include <tlhelp32.h>
#include "handle_hijack.hpp"
uint32_t pProcess::FindProcessIdByProcessName(const char* ProcessName)
{
std::wstring wideProcessName;
int wideCharLength = MultiByteToWideChar(CP_UTF8, 0, ProcessName, -1, nullptr, 0);
if (wideCharLength > 0)
{
wideProcessName.resize(wideCharLength);
MultiByteToWideChar(CP_UTF8, 0, ProcessName, -1, &wideProcessName[0], wideCharLength);
}
HANDLE hPID = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32W process_entry_{ };
process_entry_.dwSize = sizeof(PROCESSENTRY32W);
DWORD pid = 0;
if (Process32FirstW(hPID, &process_entry_))
{
do
{
if (!wcscmp(process_entry_.szExeFile, wideProcessName.c_str()))
{
pid = process_entry_.th32ProcessID;
break;
}
} while (Process32NextW(hPID, &process_entry_));
}
CloseHandle(hPID);
return pid;
}
uint32_t pProcess::FindProcessIdByWindowName(const char* WindowName)
{
DWORD process_id = 0;
HWND windowHandle = FindWindowA(nullptr, WindowName);
if (windowHandle)
GetWindowThreadProcessId(windowHandle, &process_id);
return process_id;
}
HWND pProcess::GetWindowHandleFromProcessId(DWORD ProcessId) {
HWND hwnd = NULL;
do {
hwnd = FindWindowEx(NULL, hwnd, NULL, NULL);
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
if (pid == ProcessId) {
TCHAR windowTitle[MAX_PATH];
GetWindowText(hwnd, windowTitle, MAX_PATH);
if (IsWindowVisible(hwnd) && windowTitle[0] != '\0') {
return hwnd;
}
}
} while (hwnd != NULL);
return NULL; // No main window found for the given process ID
}
HANDLE OpenProcessNt(DWORD dwDesiredAccess, BOOL bInheritHandle,
DWORD dwProcessId) {
// At last is same with "OpenProcess", but we call NativeAPI instead of WindowsAPI directly.
HANDLE hProcess = 0;
_NtOpenProcess NtOpenProcess = (_NtOpenProcess)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtOpenProcess");
CLIENT_ID clientId = {(HANDLE)dwProcessId, NULL};
OBJECT_ATTRIBUTES objAttr = hj::InitObjectAttributes(NULL, 0, NULL, NULL);
NtOpenProcess(&hProcess, dwDesiredAccess,
&objAttr, &clientId);
return hProcess;
}
bool pProcess::AttachProcess(const char* ProcessName)
{
this->pid_ = this->FindProcessIdByProcessName(ProcessName);
if (pid_)
{
HMODULE modules[0xFF];
MODULEINFO module_info;
DWORD _;
handle_ = OpenProcessNt(PROCESS_QUERY_INFORMATION |PROCESS_VM_OPERATION |
PROCESS_VM_READ,FALSE, pid_);
EnumProcessModulesEx(this->handle_, modules, sizeof(modules), &_, LIST_MODULES_64BIT);
base_client_.base = (uintptr_t)modules[0];
GetModuleInformation(this->handle_, modules[0], &module_info, sizeof(module_info));
base_client_.size = module_info.SizeOfImage;
hwnd_ = this->GetWindowHandleFromProcessId(pid_);
return true;
}
return false;
}
bool pProcess::AttachProcessHj(const char* ProcessName)
{
this->pid_ = this->FindProcessIdByProcessName(ProcessName);
if (pid_)
{
HMODULE modules[0xFF];
MODULEINFO module_info;
DWORD _;
// Using Apxaey's handle hijack function to safely open a handle
handle_ = hj::HijackExistingHandle(pid_);
if (!hj::IsHandleValid(handle_))
{
std::cout << "[cheat] Handle Hijack failed, falling back to OpenProcess method." << std::endl;
return pProcess::AttachProcess(ProcessName); // Handle hijacking failed, so we fall back to the normal OpenProcess method
}
EnumProcessModulesEx(this->handle_, modules, sizeof(modules), &_, LIST_MODULES_64BIT);
base_client_.base = (uintptr_t)modules[0];
GetModuleInformation(this->handle_, modules[0], &module_info, sizeof(module_info));
base_client_.size = module_info.SizeOfImage;
hwnd_ = this->GetWindowHandleFromProcessId(pid_);
return true;
}
return false;
}
bool pProcess::AttachWindow(const char* WindowName)
{
this->pid_ = this->FindProcessIdByWindowName(WindowName);
if (pid_)
{
HMODULE modules[0xFF];
MODULEINFO module_info;
DWORD _;
handle_ = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid_);
EnumProcessModulesEx(this->handle_, modules, sizeof(modules), &_, LIST_MODULES_64BIT);
base_client_.base = (uintptr_t)modules[0];
GetModuleInformation(this->handle_, modules[0], &module_info, sizeof(module_info));
base_client_.size = module_info.SizeOfImage;
hwnd_ = this->GetWindowHandleFromProcessId(pid_);
return true;
}
return false;
}
bool pProcess::UpdateHWND()
{
hwnd_ = this->GetWindowHandleFromProcessId(pid_);
return hwnd_ == nullptr;
}
ProcessModule pProcess::GetModule(const char* lModule)
{
std::wstring wideModule;
int wideCharLength = MultiByteToWideChar(CP_UTF8, 0, lModule, -1, nullptr, 0);
if (wideCharLength > 0)
{
wideModule.resize(wideCharLength);
MultiByteToWideChar(CP_UTF8, 0, lModule, -1, &wideModule[0], wideCharLength);
}
HANDLE handle_module = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid_);
MODULEENTRY32W module_entry_{};
module_entry_.dwSize = sizeof(MODULEENTRY32W);
do
{
if (!wcscmp(module_entry_.szModule, wideModule.c_str()))
{
CloseHandle(handle_module);
return { (DWORD_PTR)module_entry_.modBaseAddr, module_entry_.dwSize };
}
} while (Module32NextW(handle_module, &module_entry_));
CloseHandle(handle_module);
return { 0, 0 };
}
LPVOID pProcess::Allocate(size_t size_in_bytes)
{
return VirtualAllocEx(this->handle_, NULL, size_in_bytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
uintptr_t pProcess::FindSignature(std::vector<uint8_t> signature)
{
std::unique_ptr<uint8_t[]> data;
data = std::make_unique<uint8_t[]>(this->base_client_.size);
if (!ReadProcessMemory(this->handle_, (void*)(this->base_client_.base), data.get(), this->base_client_.size, NULL)) {
return 0x0;
}
for (uintptr_t i = 0; i < this->base_client_.size; i++)
{
for (uintptr_t j = 0; j < signature.size(); j++)
{
if (signature.at(j) == 0x00)
continue;
if (*reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(&data[i + j])) == signature.at(j))
{
if (j == signature.size() - 1)
return this->base_client_.base + i;
continue;
}
break;
}
}
return 0x0;
}
uintptr_t pProcess::FindSignature(ProcessModule target_module, std::vector<uint8_t> signature)
{
std::unique_ptr<uint8_t[]> data;
data = std::make_unique<uint8_t[]>(0xFFFFFFF);
if (!ReadProcessMemory(this->handle_, (void*)(target_module.base), data.get(), 0xFFFFFFF, NULL)) {
return NULL;
}
for (uintptr_t i = 0; i < 0xFFFFFFF; i++)
{
for (uintptr_t j = 0; j < signature.size(); j++)
{
if (signature.at(j) == 0x00)
continue;
if (*reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(&data[i + j])) == signature.at(j))
{
if (j == signature.size() - 1)
return this->base_client_.base + i;
continue;
}
break;
}
}
return 0x0;
}
uintptr_t pProcess::FindCodeCave(uint32_t length_in_bytes)
{
std::vector<uint8_t> cave_pattern = {};
for (uint32_t i = 0; i < length_in_bytes; i++) {
cave_pattern.push_back(0x00);
}
return FindSignature(cave_pattern);
}
void pProcess::Close()
{
CloseHandle(handle_);
}