First Commit
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
#include "memory.hpp"
|
||||
#include <tlhelp32.h>
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
bool pProcess::AttachProcess(const char* ProcessName)
|
||||
{
|
||||
this->pid_ = this->FindProcessIdByProcessName(ProcessName);
|
||||
|
||||
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_module_.base = (uintptr_t)modules[0];
|
||||
|
||||
GetModuleInformation(this->handle_, modules[0], &module_info, sizeof(module_info));
|
||||
base_module_.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_module_.base = (uintptr_t)modules[0];
|
||||
|
||||
GetModuleInformation(this->handle_, modules[0], &module_info, sizeof(module_info));
|
||||
base_module_.size = module_info.SizeOfImage;
|
||||
|
||||
hwnd_ = this->GetWindowHandleFromProcessId(pid_);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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_module_.size);
|
||||
|
||||
if (!ReadProcessMemory(this->handle_, (void*)(this->base_module_.base), data.get(), this->base_module_.size, NULL)) {
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < this->base_module_.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_module_.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_module_.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_);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
#ifndef _PPROCESS_HPP_
|
||||
#define _PPROCESS_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <math.h>
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <Psapi.h>
|
||||
|
||||
struct ProcessModule
|
||||
{
|
||||
uintptr_t base, size;
|
||||
};
|
||||
|
||||
class pProcess
|
||||
{
|
||||
public:
|
||||
DWORD pid_; // process id
|
||||
HANDLE handle_; // handle to process
|
||||
HWND hwnd_; // window handle
|
||||
ProcessModule base_module_;
|
||||
|
||||
public:
|
||||
bool AttachProcess(const char* process_name);
|
||||
bool AttachWindow(const char* window_name);
|
||||
void Close();
|
||||
|
||||
public:
|
||||
ProcessModule GetModule(const char* module_name);
|
||||
LPVOID Allocate(size_t size_in_bytes);
|
||||
uintptr_t FindCodeCave(uint32_t length_in_bytes);
|
||||
uintptr_t FindSignature(std::vector<uint8_t> signature);
|
||||
uintptr_t FindSignature(ProcessModule target_module, std::vector<uint8_t> signature);
|
||||
|
||||
template<class T>
|
||||
uintptr_t ReadOffsetFromSignature(std::vector<uint8_t> signature, uint8_t offset) // offset example: "FF 05 ->22628B01<-" offset is 2
|
||||
{
|
||||
uintptr_t pattern_address = this->FindSignature(signature);
|
||||
if (!pattern_address)
|
||||
return 0x0;
|
||||
|
||||
T offset_value = this->read<T>(pattern_address + offset);
|
||||
return pattern_address + offset_value + offset + sizeof(T);
|
||||
}
|
||||
|
||||
bool read_raw(uintptr_t address, void* buffer, size_t size)
|
||||
{
|
||||
SIZE_T bytesRead;
|
||||
if (ReadProcessMemory(this->handle_, reinterpret_cast<LPCVOID>(address), buffer, size, &bytesRead))
|
||||
{
|
||||
return bytesRead == size;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void write(uintptr_t address, T value)
|
||||
{
|
||||
WriteProcessMemory(handle_, (void*)address, &value, sizeof(T), 0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T read(uintptr_t address)
|
||||
{
|
||||
T buffer{};
|
||||
ReadProcessMemory(handle_, (void*)address, &buffer, sizeof(T), 0);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void write_bytes(uintptr_t addr, std::vector<uint8_t> patch)
|
||||
{
|
||||
WriteProcessMemory(handle_, (void*)addr, &patch[0], patch.size(), 0);
|
||||
}
|
||||
|
||||
uintptr_t read_multi_address(uintptr_t ptr, std::vector<uintptr_t> offsets)
|
||||
{
|
||||
uintptr_t buffer = ptr;
|
||||
for (int i = 0; i < offsets.size(); i++)
|
||||
buffer = this->read<uintptr_t>(buffer + offsets[i]);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T read_multi(uintptr_t base, std::vector<uintptr_t> offsets) {
|
||||
uintptr_t buffer = base;
|
||||
for (int i = 0; i < offsets.size() - 1; i++)
|
||||
{
|
||||
buffer = this->read<uintptr_t>(buffer + offsets[i]);
|
||||
}
|
||||
return this->read<T>(buffer + offsets.back());
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t FindProcessIdByProcessName(const char* process_name);
|
||||
uint32_t FindProcessIdByWindowName(const char* window_name);
|
||||
HWND GetWindowHandleFromProcessId(DWORD ProcessId);
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user