-
Автор темы
- #1
main.cpp
setup_hooks
findpattern
C++:
std::uintptr_t newFunctionClientDLL;
std::uintptr_t newFunctionEngineDLL;
std::uintptr_t newFunctionStudioRenderDLL;
std::uintptr_t newFunctionMaterialSystemDLL;
void balamirfix() {
newFunctionClientDLL = findPattern("client", "\x55\x8B\xEC\x56\x8B\xF1\x33\xC0\x57\x8B\x7D\x08");
newFunctionEngineDLL = findPattern("engine", "\x55\x8B\xEC\x56\x8B\xF1\x33\xC0\x57\x8B\x7D\x08");
newFunctionStudioRenderDLL = findPattern("studiorender", "\x55\x8B\xEC\x56\x8B\xF1\x33\xC0\x57\x8B\x7D\x08");
newFunctionMaterialSystemDLL = findPattern("materialsystem", "\x55\x8B\xEC\x56\x8B\xF1\x33\xC0\x57\x8B\x7D\x08");
}
DWORD newFunctionClientDLL_hook;
DWORD newFunctionEngineDLL_hook;
DWORD newFunctionStudioRenderDLL_hook;
DWORD newFunctionMaterialSystemDLL_hook;
static char __fastcall newFunctionClientBypass(void* thisPointer, void* edx, const char* moduleName) noexcept
{
return 1;
}
static char __fastcall newFunctionEngineBypass(void* thisPointer, void* edx, const char* moduleName) noexcept
{
return 1;
}
static char __fastcall newFunctionStudioRenderBypass(void* thisPointer, void* edx, const char* moduleName) noexcept
{
return 1;
}
static char __fastcall newFunctionMaterialSystemBypass(void* thisPointer, void* edx, const char* moduleName) noexcept
{
return 1;
}
C++:
balamirfix();
newFunctionClientDLL_hook = (DWORD)DetourFunction((PBYTE)newFunctionClientDLL, (PBYTE)newFunctionClientBypass);
newFunctionEngineDLL_hook = (DWORD)DetourFunction((PBYTE)newFunctionEngineDLL, (PBYTE)newFunctionEngineBypass);
newFunctionStudioRenderDLL_hook = (DWORD)DetourFunction((PBYTE)newFunctionStudioRenderDLL, (PBYTE)newFunctionStudioRenderBypass);
newFunctionMaterialSystemDLL_hook = (DWORD)DetourFunction((PBYTE)newFunctionMaterialSystemDLL, (PBYTE)newFunctionMaterialSystemBypass);
C++:
struct ModuleInfo {
void* base;
std::size_t size;
};
[[nodiscard]] static auto generateBadCharTable(std::string_view pattern) noexcept
{
assert(!pattern.empty());
std::array<std::size_t, (std::numeric_limits<std::uint8_t>::max)() + 1> table;
auto lastWildcard = pattern.rfind('?');
if (lastWildcard == std::string_view::npos)
lastWildcard = 0;
const auto defaultShift = (std::max)(std::size_t(1), pattern.length() - 1 - lastWildcard);
table.fill(defaultShift);
for (auto i = lastWildcard; i < pattern.length() - 1; ++i)
table[static_cast<std::uint8_t>(pattern[i])] = pattern.length() - 1 - i;
return table;
}
static ModuleInfo getModuleInformation(const char* name) noexcept
{
#ifdef _WIN32
if (HMODULE handle = GetModuleHandleA(name)) {
if (MODULEINFO moduleInfo; GetModuleInformation(GetCurrentProcess(), handle, &moduleInfo, sizeof(moduleInfo)))
return ModuleInfo{ moduleInfo.lpBaseOfDll, moduleInfo.SizeOfImage };
}
return {};
#elif __linux__
struct ModuleInfo_ {
const char* name;
void* base = nullptr;
std::size_t size = 0;
} moduleInfo;
moduleInfo.name = name;
dl_iterate_phdr([](struct dl_phdr_info* info, std::size_t, void* data) {
const auto moduleInfo = reinterpret_cast<ModuleInfo_*>(data);
if (!std::string_view{ info->dlpi_name }.ends_with(moduleInfo->name))
return 0;
if (const auto fd = open(info->dlpi_name, O_RDONLY); fd >= 0) {
if (struct stat st; fstat(fd, &st) == 0) {
if (const auto map = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); map != MAP_FAILED) {
const auto ehdr = (ElfW(Ehdr)*)map;
const auto shdrs = (ElfW(Shdr)*)(std::uintptr_t(ehdr) + ehdr->e_shoff);
const auto strTab = (const char*)(std::uintptr_t(ehdr) + shdrs[ehdr->e_shstrndx].sh_offset);
for (auto i = 0; i < ehdr->e_shnum; ++i) {
const auto shdr = (ElfW(Shdr)*)(std::uintptr_t(shdrs) + i * ehdr->e_shentsize);
if (std::strcmp(strTab + shdr->sh_name, ".text") != 0)
continue;
moduleInfo->base = (void*)(info->dlpi_addr + shdr->sh_offset);
moduleInfo->size = shdr->sh_size;
munmap(map, st.st_size);
close(fd);
return 1;
}
munmap(map, st.st_size);
}
}
close(fd);
}
moduleInfo->base = (void*)(info->dlpi_addr + info->dlpi_phdr[0].p_vaddr);
moduleInfo->size = info->dlpi_phdr[0].p_memsz;
return 1;
}, &moduleInfo);
return ModuleInfo{ moduleInfo.base, moduleInfo.size };
#endif
}
template <bool ReportNotFound = true>
static std::uintptr_t findPattern31(ModuleInfo moduleInfo, std::string_view pattern) noexcept
{
static auto id = 0;
++id;
if (moduleInfo.base && moduleInfo.size) {
const auto lastIdx = pattern.length() - 1;
const auto badCharTable = generateBadCharTable(pattern);
auto start = static_cast<const char*>(moduleInfo.base);
const auto end = start + moduleInfo.size - pattern.length();
while (start <= end) {
int i = lastIdx;
while (i >= 0 && (pattern[i] == '?' || start[i] == pattern[i]))
--i;
if (i < 0)
return reinterpret_cast<std::uintptr_t>(start);
start += badCharTable[static_cast<std::uint8_t>(start[lastIdx])];
}
}
assert(false);
#ifdef _WIN32
if constexpr (ReportNotFound)
MessageBoxA(nullptr, ("Failed to find pattern #" + std::to_string(id) + '!').c_str(), "Osiris", MB_OK | MB_ICONWARNING);
#endif
return 0;
}
template <bool ReportNotFound = true>
static std::uintptr_t findPattern(const char* moduleName, std::string_view pattern) noexcept
{
return findPattern31<ReportNotFound>(getModuleInformation(moduleName), pattern);
}