BanMe
May 19th, 2009, 14:45
im still in process of refining this so questions and comments are most welcome..
kind regards BanMe
Code:
namespace hkHook
{
struct CLLHook
{
SLIST_ENTRY HookEntry;
bool Installed;//0 is not installed 1 if installed
BYTE Opcode;//e9 jmp e8 call
int Index;
LPVOID pHeap;
DWORD TProcessId;//Targets ProcessId
DWORD hkTAddress;//Target Function to Hook
DWORD hkAddress;//Hook address
PVOID hkAllocAddr;
DWORD hkSz;//our hook size generally 5 bytes byte+dword
};
typedef CLLHook* PCLLHook;
extern "C"
{
__checkReturn bool hkInitialize(__inout CLLHook*);//Initialization
__checkReturn bool hkUninitialize(void);//Destructor
void *RtlAllocateAlignedHeap(__in size_t, __in size_t);
void *hkAllocateEntry(void);//Allocate the proper structure and connects it to our list..
__checkReturn bool hkSetTargetExeName(__in wchar_t *);//Sets Global Exe Name used for process opening by exe name...
__checkReturn bool hkSetHookParams(__in_opt wchar_t *,__in LPVOID,__in LPVOID,__in DWORD,__in BYTE,__inout CLLHook *HkStruct);
__checkReturn bool hkInstallHook(PCLLHook,HK_ROUTINE);//installs the hook specified
__checkReturn bool hkDeleteNode(__in int);//Delete hook link off our list
wchar_t *cProcessName;//current target process name..
HANDLE hHeap,hWaitParams,pHeap;
PSLIST_ENTRY pFirstEntry = {0},pListEntry = {0};
PSLIST_HEADER pListHead = {0};
int InitPhase = 0;
void *RtlAllocateAlignedHeap(size_t size, size_t alignment )
{
void *pa, *ptr;
pa=RtlAllocateHeap(hHeap,HEAP_ZERO_MEMORY,(size+alignment-1)+sizeof(void *));
if(!pa)
{
return NULL;
}
ptr=(void*)( ((ULONG_PTR)pa+sizeof(void *)+alignment-1)&~(alignment-1) );
*((void **)ptr-1)=pa;
return ptr;
}
__checkReturn bool hkInitialize(__inout CLLHook* pCLL )
{
if(InitPhase > 0)
{
return false;
}
hHeap = RtlCreateHeap(HEAP_GROWABLE|HEAP_ZERO_MEMORY,0,0,0,0,0);//64 pages reserved, 1 page allocated
if(hHeap != INVALID_HANDLE_VALUE && hHeap != 0)
{
pListHead = (PSLIST_HEADER)RtlAllocateAlignedHeap(sizeof(SLIST_HEADER),MEMORY_ALLOCATION_ALIGNMENT);
if(!pListHead)
{
return false;
}
RtlInitializeSListHead(pListHead);
if(pListHead)
{
*pCLL = *(CLLHook*)hkAllocateEntry();
if(pCLL != 0)
{
return true;
}
}
}
return pCLL;
}
//the destructor
__checkReturn bool hkUninitialize(void)
{
if(InitPhase)
{
RtlInterlockedFlushSList(pListHead);
RtlDestroyHeap(hHeap);
InitPhase = 0;
return true;
}
return false;
}
//Allocates Memory for new cLL Structure..
void *hkAllocateEntry(void)
{
if(InitPhase)
{
return false;
}
else
{
pHeap = RtlAllocateAlignedHeap(sizeof(CLLHook),MEMORY_ALLOCATION_ALIGNMENT);
PCLLHook pCLL = (PCLLHook)pHeap;
pCLL->pHeap = pHeap;
if(pCLL)
{
if(!InitPhase)
{
pFirstEntry = RtlInterlockedPushEntrySList(pListHead,&(pCLL->HookEntry));
InitPhase++;
}
pListEntry = RtlInterlockedPushEntrySList(pListHead,&(pCLL->HookEntry));
return (void*)pCLL;
}
return false;
}
}
__checkReturn bool hkSetTargetExeName(wchar_t *TargetProcName)
{
if(TargetProcName)
{
cProcessName = TargetProcName;
return true;
}
return false;
}
__checkReturn bool hkSetHookParams(__in_opt wchar_t* TargetName,__in LPVOID TargetAddr,__in LPVOID HookAddr,__in DWORD HkSz,__in BYTE Opcode,__inout CLLHook *HkStruct)
{
if(Opcode && HkSz && HookAddr && TargetAddr && InitPhase)
{
if(InitPhase == 1)
{
HkStruct->Opcode = Opcode;
HkStruct->hkTAddress = (DWORD)TargetAddr;
HkStruct->hkAddress = (DWORD)HookAddr;
HkStruct->hkSz = HkSz;
HkStruct->Index = InitPhase;
InitPhase++;
if(TargetName != 0)
{
hkSetTargetExeName(TargetName);
HkStruct->TProcessId = GetProcessId(UsrDrOpenProcess(cProcessName));
}
return true;
}
else
{
HkStruct->Opcode = Opcode;
HkStruct->hkTAddress = (DWORD)TargetAddr;
HkStruct->hkAddress = (DWORD)HookAddr;
HkStruct->hkSz = HkSz;
HkStruct->Index = InitPhase;
InitPhase++;
if(TargetName != 0)
{
hkSetTargetExeName(TargetName);
HkStruct->TProcessId = GetProcessId(UsrDrOpenProcess(cProcessName));
}
return true;
}
}
return false;
}
bool hkInstallHook(PCLLHook HkTempPar,HK_ROUTINE HkType)
{
BYTE ByteArray[8] = {0};
BYTE HookArray[8] = {0};
if(InitPhase >= 2)
{
PVOID pHolder = 0;
ULONG ProtectSize = 0;
DWORD oProt = 0;
MEMORY_BASIC_INFORMATION mbi = {0};
struct CLLHook HkParams = *(CLLHook*)HkTempPar;
if(NT_SUCCESS(NtQueryVirtualMemory(NtCurrentProcess(),(PVOID)HkParams.hkTAddress,0,&mbi,sizeof(mbi),0)))
{
if(mbi.AllocationProtect & PAGE_EXECUTE_READWRITE)
{
__asm jmp sswitch;
}
else
{
pHolder = (PVOID)HkParams.hkTAddress;
ProtectSize = HkParams.hkSz;
if(NT_SUCCESS(NtProtectVirtualMemory(NtCurrentProcess(),&pHolder,&ProtectSize,PAGE_EXECUTE_READWRITE,&oProt)))
{
__asm jmp sswitch;
}
else
{
return false;
}
}
}
return false;
sswitch:
switch (HkType)
{
case HKMOV:
__asm
{
pushad
lea eax,HkParams
lea edi,ByteArray
mov esi,[eax]HkParams.hkTAddress
mov ecx,0x5
push esi
rep movsb
pop esi
push eax
mov al,byte ptr [eax]HkParams.Opcode
mov byte ptr [esi],al
pop eax
mov ebx,[eax]HkParams.hkAddress
add esi,5
sub ebx,esi
sub esi,4
mov dword ptr [esi],ebx
popad
}
return true;
case HKCMPXCHG:
__asm
{
pushad
lea eax,HkParams
lea edi,ByteArray//destination
mov esi,[eax]HkParams.hkTAddress//Source
mov ecx,0x5
push edi
push esi
rep movsb
pop esi
pop edi
lea ecx,HookArray
push eax
mov al,byte ptr [eax]HkParams.Opcode
mov byte ptr [esi],al
pop eax
mov ebx,[eax]HkParams.hkAddress
add esi,5
sub ebx,esi
sub esi,4
mov dword ptr [ecx],ebx
mov ebx,dword ptr [ecx]
mov eax,[edi]
mxchg:
lock cmpxchg dword ptr [esi],ebx
jne mxchg
popad
}
return true;
default:
break;
}
}
return false;
}
__checkReturn bool hkDeleteNode(int Index)
{
PCLLHook pCLL = (PCLLHook)pFirstEntry;
if(pCLL->Index == Index) //case 1 corpse = Head
{
RtlFreeHeap(hHeap,0,pCLL->pHeap);
return true;
}
else
{
while(pCLL->HookEntry.Next)
{
pCLL = (PCLLHook)pFirstEntry->Next;
if(pCLL->Index == Index)
{
RtlFreeHeap(hHeap,0,pCLL->pHeap);
return true;
}
}
return false;
}
}
}
}
kind regards BanMe