Skip to content

Commit

Permalink
ADD: Hook NT functions instead kernelbase
Browse files Browse the repository at this point in the history
ADD: Better code structure for hooking functions and Win32 pointers
ADD: Memory handling improvements
  • Loading branch information
buzzer-re committed Mar 10, 2023
1 parent 72f4b64 commit 27210fc
Show file tree
Hide file tree
Showing 12 changed files with 446 additions and 285 deletions.
55 changes: 38 additions & 17 deletions Shinigami/Ichigo/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,7 +39,28 @@ HookManager::AddHook(
return pGatewayAddr;
}

LPVOID
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 @@ -71,17 +91,17 @@ HookManager::Hook64(_In_ BYTE* Src, _In_ BYTE* Dst)
//
// Holds how many bytes should be copied before place the trampoline
//
BYTE overlap = 0;
BYTE overlap = 0;

//
// Dissasemble and analyze the instructions make sure that everything is aligned and working properly
//
ZydisDecodedInstruction inst;

//
// 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 @@ -114,7 +134,7 @@ HookManager::Hook64(_In_ BYTE* Src, _In_ BYTE* Dst)
//
// Add the jump back to the next instruction
//
*(ULONG_PTR*)(JumpBackCode + 3) = (ULONG_PTR)(Src + X64_TRAMPOLINE_SIZE-1);
*(ULONG_PTR*)(JumpBackCode + 3) = (ULONG_PTR)(Src + X64_TRAMPOLINE_SIZE - 1);

memcpy_s(pOldCode + overlap + NOP_SLIDE, X64_TRAMPOLINE_SIZE, JumpBackCode, X64_TRAMPOLINE_SIZE);

Expand All @@ -125,19 +145,20 @@ HookManager::Hook64(_In_ BYTE* Src, _In_ BYTE* Dst)

memcpy_s(Src, X64_TRAMPOLINE_SIZE, JumpToHookCode, X64_TRAMPOLINE_SIZE);
VirtualProtect(Src, X64_TRAMPOLINE_SIZE, dwOldProtect, &dwOldProtect);

return pOldCode;
}

LPVOID
LPVOID
HookManager::Hook32(
_In_ BYTE* Src,
_In_ BYTE* Src,
_In_ BYTE* Dst
)
{
DWORD dwOldCodeDelta;
ULONG_PTR dwOldCodeDelta;
ULONG_PTR dwRelativeAddrDstDelta;

DWORD dwOldProtection;
DWORD dwRelativeAddrDstDelta;
DWORD overlap = 0;
BYTE* pSrc = Src;

Expand All @@ -146,16 +167,16 @@ 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;
}

//
// 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 Expand Up @@ -217,5 +238,5 @@ HookManager::Hook32(
return nullptr;
}

return (LPVOID) pOldCode;
return (LPVOID)pOldCode;
}
30 changes: 15 additions & 15 deletions Shinigami/Ichigo/HookManager.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include <windows.h>
#include <unordered_map>
#include <Zydis/Zydis.h>
Expand All @@ -7,8 +8,6 @@
#define X64_TRAMPOLINE_SIZE 13
#define X64_JUMP_BACK_SIZE X64_TRAMPOLINE_SIZE



#define HOOK_MAX_SIZE 2*5
#define NOP_SLIDE 16
#define TRAMPOLINE_SIZE 5
Expand All @@ -17,30 +16,31 @@
#define JUMP 0xE9

enum HOOK_STATUS {
HOOK_STATUS_SUCCESS,
HOOK_STATUS_ALREADY_HOOKED,
HOOK_STATUS_NOT_ENOUGH_MEMORY
HOOK_STATUS_SUCCESS,
HOOK_STATUS_ALREADY_HOOKED,
HOOK_STATUS_NOT_ENOUGH_MEMORY
};


struct Hook {
LPVOID OriginalAddr;
LPVOID HookAddr;
LPVOID GatewayAddr;
LPVOID OriginalAddr;
LPVOID HookAddr;
LPVOID GatewayAddr;
};

class HookManager
{
public:
HookManager();
LPVOID AddHook(_In_ BYTE* Src, _In_ BYTE* Dst);
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);
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;
std::unordered_map<LPVOID, Hook> hooks;
};

1 change: 1 addition & 0 deletions Shinigami/Ichigo/Mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ struct Memory
DWORD Size;
DWORD prot;
bool safe;
DWORD ProcessID;
bool cAlloc;
};
2 changes: 1 addition & 1 deletion Shinigami/Ichigo/PEDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ Memory* PEDumper::FindRemotePE(HANDLE hProcess, const Memory* mem)

if (!ReadProcessMemory(hProcess, mem->Addr, &dosHdr, sizeof(dosHdr), &dwBytesRead)) return nullptr;


if (dosHdr.e_magic != IMAGE_DOS_SIGNATURE)
{
// TODO: Deep search, implement
return nullptr;
}


LPVOID pPE = VirtualAlloc(NULL, mem->Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pPE == nullptr) return nullptr;

Expand Down
Loading

0 comments on commit 27210fc

Please sign in to comment.