Skip to content

Commit

Permalink
FIX: Protections without execute on x86 code causes crash in some
Browse files Browse the repository at this point in the history
functions
  • Loading branch information
buzzer-re committed Mar 10, 2023
1 parent 1e93a65 commit f239ff6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
32 changes: 26 additions & 6 deletions Gancho/HookManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
HookManager::HookManager()
{
#if defined(_WIN64)
ZydisDecoderInit(&zDecoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
ZydisDecoderInit(&ZDecoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
#else
ZydisDecoderInit(&zDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
ZydisDecoderInit(&ZDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
#endif
}

Expand All @@ -26,7 +26,6 @@ HookManager::AddHook(
#else
pGatewayAddr = Hook32(Src, Dst);
#endif

//
// Insert new hook on the manager map
//
Expand All @@ -40,6 +39,27 @@ HookManager::AddHook(
return pGatewayAddr;
}

VOID HookManager::DisassambleAt(_In_ ULONG_PTR* Address, _In_ SIZE_T NumberOfInstructions)
{
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
CHAR Buffer[256];


for (SIZE_T i = 0; i < NumberOfInstructions; i++)
{
// Decode the instruction at the specified address
ZydisDecodedInstruction instruction;
ZydisDecoderDecodeBuffer(&ZDecoder, reinterpret_cast<const void*>(Address), 16, &instruction);

// Format the instruction and print it to the console

ZydisFormatterFormatInstruction(&formatter, &instruction, Buffer, sizeof(Buffer), (ZyanU64)Address);
std::printf("0x%x - %s\n", Address, Buffer);
Address = (ULONG_PTR*)((BYTE*)Address + instruction.length);
}
}

LPVOID
HookManager::Hook64(_In_ BYTE* Src, _In_ BYTE* Dst)
{
Expand Down Expand Up @@ -81,7 +101,7 @@ HookManager::Hook64(_In_ BYTE* Src, _In_ BYTE* Dst)
//
// Disassemble to pick the instructions length
//
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&zDecoder, pSrc, X64_TRAMPOLINE_SIZE, &inst)) && overlap < X64_TRAMPOLINE_SIZE)
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&ZDecoder, pSrc, X64_TRAMPOLINE_SIZE, &inst)) && overlap < X64_TRAMPOLINE_SIZE)
{
overlap += inst.length;
pSrc += inst.length;
Expand Down Expand Up @@ -147,7 +167,7 @@ HookManager::Hook32(
//
// Disassemble to pick the instructions length
//
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&zDecoder, pSrc, X64_TRAMPOLINE_SIZE, &inst)) && overlap < X86_TRAMPOLINE_SIZE)
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&ZDecoder, pSrc, X64_TRAMPOLINE_SIZE, &inst)) && overlap < X86_TRAMPOLINE_SIZE)
{
overlap += inst.length;
pSrc += inst.length;
Expand All @@ -156,7 +176,7 @@ HookManager::Hook32(
//
// Change protections to for writing
//
if (!VirtualProtect(Src, X86_TRAMPOLINE_SIZE, PAGE_READWRITE, &dwOldProtection))
if (!VirtualProtect(Src, X86_TRAMPOLINE_SIZE, PAGE_EXECUTE_READWRITE, &dwOldProtection))
{
std::printf("Error on replacing protection!\n");
return nullptr;
Expand Down
4 changes: 3 additions & 1 deletion Gancho/HookManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ class __declspec(dllexport) HookManager
public:
HookManager();
LPVOID AddHook(_In_ BYTE* Src, _In_ BYTE* Dst);
VOID DisassambleAt(_In_ ULONG_PTR* Address, _In_ SIZE_T NumberOfInstructions);

private:
LPVOID Hook64(_In_ BYTE* Src, _In_ BYTE* Dst);
LPVOID Hook32(_In_ BYTE* Src, _In_ BYTE* Dst);

private:
ZydisDecoder zDecoder;
ZydisDecoder ZDecoder;

std::unordered_map<LPVOID, Hook> hooks;
};
Expand Down

0 comments on commit f239ff6

Please sign in to comment.