initial push

This commit is contained in:
2022-09-29 12:31:39 +02:00
commit 88a0261880
17 changed files with 1350 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
#include <Windows.h>
#include <util/hooklib.hpp>
#include <vendor/hde.hpp>
namespace util {
constexpr uint8_t target_shellcode[] = {
0x8D, 0x64, 0x24, 0xFC, // lea esp, [esp-0x4]
0xC7, 0x04, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, // mov DWORD PTR [esp], ADDRESS
0xC3 // ret
};
constexpr uint8_t tramp_shellcode[] = {
0x68, 0xFF, 0xFF, 0xFF, 0xFF, // push imm32
0xC3, // ret
};
bool Hook::enable(uintptr_t target, uintptr_t detour) {
hde32s hde_state;
while (_bytes < sizeof(target_shellcode)) {
_bytes += hde32_disasm((const void *) (target + _bytes), &hde_state);
if (hde_state.opcode == 0xC3) {
_bytes = 0;
return false;
}
}
auto tramp = VirtualAlloc(nullptr, _bytes + sizeof(tramp_shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!tramp) {
_bytes = 0;
return false;
}
unsigned long old_prot;
VirtualProtect((void *) target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot);
_target = target;
_detour = detour;
_tramp = (uintptr_t) tramp;
memcpy((uint8_t *) _tramp, (const uint8_t *) _target, _bytes);
memcpy((uint8_t *) _tramp + _bytes, tramp_shellcode, sizeof(tramp_shellcode));
memcpy((uint8_t *) _target, target_shellcode, sizeof(target_shellcode));
*(uintptr_t *) (_target + 7) = _detour;
*(uintptr_t *) (_tramp + _bytes + 1) = _target + _bytes;
VirtualProtect((void *) target, _bytes, old_prot, &old_prot);
return true;
}
void Hook::disable() {
if (!_bytes)
return;
unsigned long old_prot;
VirtualProtect((void *) _target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot);
memcpy((uint8_t *) _target, (const uint8_t *) _tramp + _bytes, _bytes);
VirtualFree((void *) _tramp, 0, MEM_RELEASE);
VirtualProtect((void *) _target, _bytes, old_prot, &old_prot);
_bytes = 0;
_target = 0;
_detour = 0;
_tramp = 0;
}
} // namespace util

View File

@@ -0,0 +1,64 @@
#include <util/memory.hpp>
#include <util/pe.hpp>
#include <vendor/small_vector.hpp>
namespace util {
constexpr uint8_t hex_to_byte(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
} else if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
} else if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
// >.<
std::unreachable();
}
constexpr uint8_t stich_byte(char x, char y) {
return hex_to_byte(x) << 4 | hex_to_byte(y);
}
uint8_t *find_pattern(std::string_view pattern, uint8_t *begin, size_t size, ptrdiff_t offset) {
vendor::small_vector<uint8_t, 0x20> vec;
for (auto i = 0u; i < pattern.size(); i++) {
auto &ch = pattern[i];
if (ch == '?') {
vec.push_back(0xCC);
} else if (std::isxdigit(ch)) {
vec.push_back(stich_byte(ch, pattern[++i]));
}
}
for (auto mem = begin; mem < begin + size; mem++) {
bool is_found = true;
for (auto i = 0u; i < vec.size(); i++) {
if (vec[i] != 0xCC && vec[i] != mem[i]) {
is_found = false;
break;
}
}
if (is_found) {
return mem + offset;
}
}
return nullptr;
}
uint8_t *scan_module(std::string_view module_name, std::string_view pattern, ptrdiff_t offset) {
auto module_info = util::get_module(module_name);
if (!module_info.base)
return nullptr;
return util::find_pattern(pattern, (uint8_t *) module_info.base, module_info.size, offset);
}
} // namespace util

View File

@@ -0,0 +1,70 @@
#include <Windows.h>
#include <Winternl.h>
#include <cstdint>
#include <cstdlib>
#include <util/pe.hpp>
struct LdrEntry {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
uintptr_t DllBase;
uintptr_t EntryPoint;
uint32_t SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
};
namespace util {
ModuleInfo get_module(std::string_view module_name) {
auto peb = ((_TEB *) __readfsdword(0x18))->ProcessEnvironmentBlock;
auto list = &peb->Ldr->InMemoryOrderModuleList;
size_t wide_name_length = 0;
wchar_t wide_name[256] = {0};
mbstowcs_s(&wide_name_length, wide_name, 256, module_name.data(), module_name.size());
for (auto iter = list->Flink; iter != list; iter = iter->Flink) {
auto entry = CONTAINING_RECORD(iter, LdrEntry, InMemoryOrderLinks);
if (entry->BaseDllName.Buffer && _wcsnicmp(entry->BaseDllName.Buffer, wide_name, wide_name_length) == 0) {
return {
.base = entry->DllBase,
.size = entry->SizeOfImage,
};
}
}
return {};
}
uintptr_t get_export(std::string_view module_name, std::string_view export_name) {
auto module_info = get_module(module_name);
auto module_base = module_info.base;
if (!module_base)
return 0u;
auto dos_hdr = (IMAGE_DOS_HEADER *) module_base;
auto nt_hdrs = (IMAGE_NT_HEADERS *) (module_base + dos_hdr->e_lfanew);
auto exports_va = nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
auto exports_size = nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
auto exports = (IMAGE_EXPORT_DIRECTORY *) (module_base + exports_va);
auto names = (uintptr_t *) (module_base + exports->AddressOfNames);
auto functions = (uintptr_t *) (module_base + exports->AddressOfFunctions);
auto name_ordinals = (uint16_t *) (module_base + exports->AddressOfNameOrdinals);
for (auto i = 0u; i < exports->NumberOfNames; i++) {
if (export_name.compare((const char *) (module_base + names[i])) == 0)
return module_base + functions[name_ordinals[i]];
}
return 0u;
}
} // namespace util