3#include <CS2Kit/Utils/Log.hpp>
26static std::vector<PatternByte>
ParsePattern(
const std::string& pattern)
28 std::vector<PatternByte> bytes;
29 std::istringstream stream(pattern);
32 while (stream >> token)
34 if (token ==
"?" || token ==
"??")
36 bytes.push_back({0,
true});
40 bytes.push_back({
static_cast<uint8_t
>(std::stoul(token,
nullptr, 16)),
false});
46static void*
ScanMemory(
const uint8_t* base,
size_t size,
const std::vector<PatternByte>& pattern)
48 if (pattern.empty() || size < pattern.size())
51 size_t scanEnd = size - pattern.size();
52 for (
size_t i = 0; i <= scanEnd; ++i)
55 for (
size_t j = 0; j < pattern.size(); ++j)
57 if (!pattern[j].wildcard && base[i + j] != pattern[j].value)
64 return const_cast<uint8_t*
>(base + i);
71static bool GetModuleInfo(
const char* moduleName, uint8_t*& base,
size_t& size)
73 HANDLE hProcess = GetCurrentProcess();
74 HMODULE hModules[1024];
77 if (!EnumProcessModules(hProcess, hModules,
sizeof(hModules), &cbNeeded))
80 DWORD moduleCount = cbNeeded /
sizeof(HMODULE);
81 HMODULE bestModule =
nullptr;
84 for (DWORD i = 0; i < moduleCount; ++i)
86 char modPath[MAX_PATH];
87 if (!GetModuleFileNameA(hModules[i], modPath,
sizeof(modPath)))
90 const char* fileName = strrchr(modPath,
'\\');
92 fileName = strrchr(modPath,
'/');
93 fileName = fileName ? fileName + 1 : modPath;
95 if (_stricmp(fileName, moduleName) != 0)
99 if (GetModuleInformation(hProcess, hModules[i], &modInfo,
sizeof(modInfo)))
101 if (modInfo.SizeOfImage > bestSize)
103 bestModule = hModules[i];
104 bestSize = modInfo.SizeOfImage;
112 MODULEINFO modInfo{};
113 if (!GetModuleInformation(hProcess, bestModule, &modInfo,
sizeof(modInfo)))
116 base =
static_cast<uint8_t*
>(modInfo.lpBaseOfDll);
117 size = modInfo.SizeOfImage;
134 if (info->dlpi_name && strstr(info->dlpi_name, mod->name))
136 mod->
base =
reinterpret_cast<uint8_t*
>(info->dlpi_addr);
138 for (
int i = 0; i < info->dlpi_phnum; ++i)
140 if (info->dlpi_phdr[i].p_type == PT_LOAD)
142 size_t segEnd = info->dlpi_phdr[i].p_vaddr + info->dlpi_phdr[i].p_memsz;
143 if (segEnd > maxAddr)
154static bool GetModuleInfo(
const char* moduleName, uint8_t*& base,
size_t& size)
156 ModuleInfo mod{moduleName,
nullptr, 0,
false};
168void*
FindPattern(
const char* moduleName,
const std::string& pattern)
170 std::string fullName;
172 fullName = std::string(moduleName) +
".dll";
174 fullName = std::string(
"lib") + moduleName +
".so";
177 uint8_t* base =
nullptr;
181 Log::Error(
"SigScanner: Module '{}' not found.", fullName);
185 Log::Info(
"SigScanner: Scanning '{}' (base={:#x}, size=0x{:X})...", fullName,
reinterpret_cast<uintptr_t
>(base),
189 void* result =
ScanMemory(base, size, patternBytes);
192 Log::Warn(
"SigScanner: Pattern not found in '{}'.", fullName);
196 Log::Info(
"SigScanner: Found match at {:#x}.",
reinterpret_cast<uintptr_t
>(result));
206 int32_t relative = *
reinterpret_cast<int32_t*
>(addr + ripOffset);
207 return addr + ripSize + relative;
static bool GetModuleInfo(const char *moduleName, uint8_t *&base, size_t &size)
void * FindPattern(const char *moduleName, const std::string &pattern)
static int DlIterateCallback(struct dl_phdr_info *info, size_t, void *data)
static std::vector< PatternByte > ParsePattern(const std::string &pattern)
static void * ScanMemory(const uint8_t *base, size_t size, const std::vector< PatternByte > &pattern)
uintptr_t ResolveRelativeAddress(uintptr_t addr, int ripOffset, int ripSize)