一个简单的inlineHook的实现
main.c```c
#include <ntddk.h>
#include "LDasm.h"
extern KAFFINITY KeSetAffinityThread ( PKTHREAD Thread, KAFFINITY Affinity );
#define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'neek')
#define kfree(_p) ExFreePool(_p)
#define CLEAR_WP() \
__asm cli \
__asm mov eax,cr0 \
__asm and eax,not 000010000h\
__asm mov cr0,eax
#define SET_WP() \
__asm mov eax,cr0 \
__asm or eax,000010000h \
__asm mov cr0,eax \
__asm sti
typedef struct _HOOK_POINT
{
ULONG HookType;
ULONG FuncLen;
ULONG HookAddr;
}HOOK_POINT, *PHOOK_POINT;
typedef enum _INLINE_ENGINE_TYPES
{
Automatic,
CallHookE8,
CallHookFF15,
InlineHookPre2,// 短跳+长跳转
InlineHookPre1,// 开头5字节JMP
InlineHookDep2,// push+ret
InlineHookDep1,// 深度JMP
InlineCrazyPatch
} INLINE_ENGINE_TYPES;
#pragma pack(1)
typedef struct _JMP_CODE
{
UCHAR Jmp;
ULONG JmpOffset;
}JMP_CODE, *PJMP_CODE;
typedef struct _HOOK_INFO
{
UCHAR Type; /*1*/
UCHAR CodeLen; /*2*/
ULONG OrgAddr; /*6*/
ULONG NewCallVal; /*10*/
ULONG OrgCallval; /*14*/
JMP_CODE JmpNewCode; /*19*/
UCHAR OrgCode; /*24*/
JMP_CODE JmpOrgCode; /*29*/
UCHAR unknown; /*36*/
}HOOK_INFO, *PHOOK_INFO;
#pragma pack()
HOOK_POINT g_strucHookPoint;
ULONG NumberOfRaisedCPU;
ULONG AllCPURaised;
PKDPC g_basePKDPC;
KIRQL g_NewIRQL;
BOOLEAN GetHookPoint( PUCHAR pCode,
ULONG nCodeLen,
ULONG nTotalLen,
ULONG nFuncLen,
ULONG HookType )
{
UCHAR bRet = 0;
if ( nTotalLen >= nFuncLen ){
return 0;
}
if ( nTotalLen != 2 && nCodeLen != 2 ){
if ( nCodeLen == 5 ){
//
//for call opt
//
if ( *pCode == 0xe8 ){
g_strucHookPoint.HookType = CallHookE8;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)(pCode + 1);
return TRUE;
}
//
//not call and is valid
//
if ( nTotalLen > 7 && nTotalLen < (2 * nFuncLen / 3) ){
if ( HookType == InlineHookDep1 ){
g_strucHookPoint.HookType = InlineHookDep1;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)pCode;
return TRUE;
}
if ( g_strucHookPoint.HookType == Automatic ){
g_strucHookPoint.HookType = InlineHookDep1;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)pCode;
return FALSE;
}
}
return FALSE;
//
//for nlen == 6
//
}else if ( nCodeLen == 6 ){
if ( nTotalLen > 7 && nTotalLen < (2 * nFuncLen / 3) ){
if ( HookType == InlineHookDep2 )
{
g_strucHookPoint.HookType = InlineHookDep2;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)pCode;
return TRUE;
}
if ( g_strucHookPoint.HookType == Automatic )
{
g_strucHookPoint.HookType = InlineHookDep2;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)pCode;
//return FALSE;
}
}
if ( *(USHORT*)pCode == 0x15FF )
{
g_strucHookPoint.HookType = CallHookFF15;
g_strucHookPoint.FuncLen = nTotalLen;
g_strucHookPoint.HookAddr = (ULONG)(pCode + 2);
return TRUE;
}
return FALSE;
}
}
if ( *(ULONG*)pCode == 0x8B55FF8B &&
pCode == 0xEC ){
if ( HookType == InlineHookPre1 ){
g_strucHookPoint.HookType = InlineHookPre1;
g_strucHookPoint.FuncLen = 2;
g_strucHookPoint.HookAddr = (ULONG)pCode;
return TRUE;
}
}
if ( *(USHORT*)pCode == 0xFF8B){
if ( (*((ULONG*)pCode - 1) == 0xCCCCCCCC && *(pCode - 5) == 0xCC) ||
(*((ULONG*)pCode - 1) ==0x90909090 && *(pCode - 5) == 0x90u) ){
if ( HookType == InlineHookPre2 ){
g_strucHookPoint.HookType = InlineHookPre2;
g_strucHookPoint.FuncLen = 2;
g_strucHookPoint.HookAddr = (ULONG)pCode;
return TRUE;
}
}
}
return FALSE;
}
ULONG GetFuncHookPoint( ULONG uFuncAddr, int nHookType )
{
ULONG uFuncAddrTmp = uFuncAddr;
ULONG uFuncLen = 0, uCodeLen = 0;
ULONG uTotalLen = 0;
UCHAR uRet = 0;
UCHAR *pOpcode;
g_strucHookPoint.FuncLen = 0;
g_strucHookPoint.HookAddr = 0;
g_strucHookPoint.HookType = 0;
if ( uFuncAddr ){
uFuncLen = SizeOfProc( (PVOID)uFuncAddr );
if ( uFuncLen > 0 ){
do
{
uCodeLen = SizeOfCode( (PVOID)uFuncAddrTmp, &pOpcode );
uTotalLen += uCodeLen;
uFuncAddrTmp += uCodeLen;
uRet = GetHookPoint( pOpcode, uCodeLen, uTotalLen, uFuncLen, nHookType );
}while ( !uRet && uTotalLen < uFuncLen );
}
}
return uRet;
}
ULONG FindPushRet( ULONG NewFunctionAddr )
{
ULONG uRet = NewFunctionAddr;
//
//这里应该检查一下,或者设置个最大长度
//
while ( *(UCHAR*)uRet != 0x68 || *(UCHAR*)(uRet + 5) != 0xC3 )
{
uRet++;
}
return ++uRet;
}
VOID RaiseCPUIrqlAndWait(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
)
{
InterlockedIncrement(&NumberOfRaisedCPU);
while (!InterlockedCompareExchange( &AllCPURaised, 1, 1 )){
__asm nop;
}
InterlockedDecrement(&NumberOfRaisedCPU);
}
BOOLEAN GainExlusivity(VOID)
{
NTSTATUS ntStatus;
ULONG u_currentCPU;
CCHAR i;
PKDPC pKdpc, temp_pkdpc;
KIRQL NewIrql;
/*if (DISPATCH_LEVEL != KeGetCurrentIrql())
{
return FALSE;
}*/
NewIrql = KeRaiseIrqlToDpcLevel();
InterlockedAnd(&NumberOfRaisedCPU, 0);
InterlockedAnd(&AllCPURaised, 0);
temp_pkdpc = (PKDPC)kmalloc(KeNumberProcessors * sizeof(KDPC));
if (NULL == temp_pkdpc){
KfLowerIrql(NewIrql);
return FALSE;
}
g_basePKDPC = temp_pkdpc;
u_currentCPU = KeGetCurrentProcessorNumber();
for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++){
if ( i != u_currentCPU ){
KeInitializeDpc( temp_pkdpc, RaiseCPUIrqlAndWait, NULL );
KeSetTargetProcessorDpc( temp_pkdpc, i );
KeInsertQueueDpc( temp_pkdpc, NULL, NULL );
}
}
while( (KeNumberProcessors - 1) != InterlockedCompareExchange( &NumberOfRaisedCPU, KeNumberProcessors - 1, KeNumberProcessors - 1) )
{
__asm nop;
}
g_NewIRQL = NewIrql;
return TRUE;
}
void ReleaseExclusivity()
{
InterlockedIncrement(&AllCPURaised);
while (InterlockedCompareExchange(&NumberOfRaisedCPU, 0, 0))
{
__asm nop;
}
if (NULL != g_basePKDPC){
kfree((PVOID)g_basePKDPC);
g_basePKDPC = NULL;
}
KfLowerIrql(g_NewIRQL);
}
VOID __stdcall SetWp()
{
SET_WP();
ReleaseExclusivity();
}
BOOLEAN __stdcall ClearWp()
{
BOOLEAN bRet = GainExlusivity();
CLEAR_WP();
return bRet;
}
BOOLEAN fnInlineHookPre1( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != InlineHookPre1 || \
!g_strucHookPoint.HookAddr || \
*(ULONG*)g_strucHookPoint.HookAddr != 0x8B55FF8B || \
*(UCHAR*)(g_strucHookPoint.HookAddr + 4) != 0xEC ){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = InlineHookPre1;
pInfo->CodeLen = 5;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr - \
((ULONG)pInfo + 5 /*sizeof 'JMP XXXX' opt*/ + FIELD_OFFSET(HOOK_INFO, JmpNewCode));
RtlCopyMemory( pInfo->OrgCode, g_strucHookPoint.HookAddr, 5 );
pInfo->JmpOrgCode.Jmp = 0xE9;
pInfo->JmpOrgCode.JmpOffset = g_strucHookPoint.HookAddr + 5/*size of shell code*/ - \
((ULONG)pInfo + 5 /*sizeof 'JMP XXXX' opt*/ + FIELD_OFFSET(HOOK_INFO, JmpOrgCode));
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
((PJMP_CODE)g_strucHookPoint.HookAddr)->Jmp = 0xE9;
((PJMP_CODE)g_strucHookPoint.HookAddr)->JmpOffset = \
(ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpNewCode) - (g_strucHookPoint.HookAddr + 5);
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN fnCallHookE8( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != CallHookE8 || \
!g_strucHookPoint.HookAddr){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
//
//fill the struct
//
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = CallHookE8;
pInfo->CodeLen = 4;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->NewCallVal = (ULONG)pInfo - g_strucHookPoint.HookAddr + 10;
pInfo->OrgCallval = *(ULONG*)g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr - \
(ULONG)pInfo - 5 - FIELD_OFFSET(HOOK_INFO, JmpNewCode);
((PJMP_CODE)(pInfo->OrgCode))->Jmp = 0xE9;
//
//NOTE ( For example )
//
//ORG_CALL: CALL CALLADDR1
//CALLADDR1 = Target - ORG_CALL - sizeof(opt)/*5*/;
//==> Target = CALLADDR1 + ORG_CALL + sizeof(opt);
//SHELL_JMP: JMP CALLADDR2--> JMP to target
// CALLADDR2 = Target - SHELL_JMP - sizeof(opt)/*5*/;
//==> CALLADDR2 = CALLADDR1 + ORG_CALL + sizeof(opt) - SHELL_JMP - sizeof(opt)
//==> CALLADDR2 = CALLADDR1 + ORG_CALL - SHELL_JMP;
//CALLADDR2 ==(is)== ((PJMP_CODE)(pInfo->OrgCode))->JmpOffset
//CALLADDR1==(is)== *(ULONG*)g_strucHookPoint.HookAddr
//ORG_CALL ==(is)== g_strucHookPoint.HookAddr - 1 (因为在取地址的时候没有加上0xE8)
//SHELL_JMP ==(is)== (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode)
//
((PJMP_CODE)(pInfo->OrgCode))->JmpOffset = (*(ULONG*)g_strucHookPoint.HookAddr) + \
(g_strucHookPoint.HookAddr - 1) - \
((ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode) /*19*/);
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
*(ULONG*)g_strucHookPoint.HookAddr = pInfo->NewCallVal;
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN fnCallHookFF15( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != CallHookFF15 || \
!g_strucHookPoint.HookAddr){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = CallHookFF15;
pInfo->CodeLen = 4;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->NewCallVal = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpNewCode);
pInfo->OrgCallval = *(ULONG*)g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr -
(ULONG)pInfo - FIELD_OFFSET(HOOK_INFO, JmpNewCode) - 5;
((PJMP_CODE)(pInfo->OrgCode))->Jmp = 0xE9;
((PJMP_CODE)(pInfo->OrgCode))->JmpOffset = (**((ULONG**)(g_strucHookPoint.HookAddr))) - \
(ULONG)pInfo - FIELD_OFFSET(HOOK_INFO, OrgCode) - 5;
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
*(ULONG*)g_strucHookPoint.HookAddr = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpNewCode);
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN fnInlineHookPre2( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != InlineHookPre2 || \
!g_strucHookPoint.HookAddr){
return FALSE;
}
if ( *(USHORT*)g_strucHookPoint.HookAddr != 0xFF8 ){
return FALSE;
}
if ( (*(ULONG*)(g_strucHookPoint.HookAddr - 4) != 0xCCCCCCCC || \
*(ULONG*)(g_strucHookPoint.HookAddr - 5) != 0xCC) && \
(*(ULONG*)(g_strucHookPoint.HookAddr - 4) != 0x90909090 || \
*(UCHAR*)(g_strucHookPoint.HookAddr - 5) != 0x90)){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = InlineHookPre2;
pInfo->CodeLen = 2;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr -
(ULONG)pInfo - FIELD_OFFSET(HOOK_INFO, JmpNewCode) - 5;
*(USHORT*)(pInfo->OrgCode) = *(USHORT *)g_strucHookPoint.HookAddr;
*(UCHAR*)((ULONG)(pInfo->OrgCode) + 2) = 0xE9;
*(UCHAR*)((ULONG)(pInfo->OrgCode) + 3) = g_strucHookPoint.HookAddr - (ULONG)pInfo - \
FIELD_OFFSET(HOOK_INFO, OrgCode) - 5;
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
*(UCHAR*)g_strucHookPoint.HookAddr = 0xEB;
*(UCHAR*)(g_strucHookPoint.HookAddr + 1) = 0xF9;
*(UCHAR*)(g_strucHookPoint.HookAddr - 5) = 0xE9;
*(ULONG*)(g_strucHookPoint.HookAddr - 4) = (ULONG)pInfo + \
FIELD_OFFSET(HOOK_INFO, OrgCode) - g_strucHookPoint.HookAddr - 5;
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN fnInlineHookDep2( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != InlineHookDep2 || \
!g_strucHookPoint.HookAddr){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = InlineHookDep2;
pInfo->CodeLen = 6;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr -
(ULONG)pInfo - FIELD_OFFSET(HOOK_INFO, JmpNewCode) - 5;
//RtlCopyMemory( pInfo->OrgCode, g_strucHookPoint.HookAddr, 6 );
*(ULONG *)((ULONG)pInfo + 19) = *(ULONG*)(g_strucHookPoint.HookAddr);
*(USHORT*)((ULONG)pInfo + 23) = *(USHORT*)(g_strucHookPoint.HookAddr + 4);
*(UCHAR*)((ULONG)pInfo + 25) = 0xE9;
*(ULONG *)((ULONG)pInfo + 26) = g_strucHookPoint.HookAddr - (ULONG)pInfo - \
FIELD_OFFSET(HOOK_INFO, OrgCode) - 5;
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
*(UCHAR*)g_strucHookPoint.HookAddr = 0x68;
*(ULONG*)(g_strucHookPoint.HookAddr + 1) = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpNewCode);
*(UCHAR*)(g_strucHookPoint.HookAddr + 5) = 0xC3;
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, OrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN fnInlineHookDep1( ULONG NewFunctionAddr )
{
ULONG uPushRet = 0;
PHOOK_INFO pInfo;
//
//Check paramter and Hook struct
//
if ( g_strucHookPoint.HookType != InlineHookDep1 || \
!g_strucHookPoint.HookAddr){
return FALSE;
}
//
//Find the Push and ret
//Note: The new function must be end of with (push XXXX; ret)
//
uPushRet = FindPushRet( NewFunctionAddr );
if ( *(ULONG*)uPushRet ){
return FALSE;
}
//
//Allocate memory for HOOK_INFO
//
pInfo = (PHOOK_INFO)kmalloc( sizeof(HOOK_INFO) );
if ( !pInfo ){
return FALSE;
}
RtlZeroMemory( pInfo, sizeof(HOOK_INFO) );
pInfo->JmpNewCode.JmpOffset = 0;
pInfo->Type = InlineHookDep1;
pInfo->CodeLen = 5;
pInfo->OrgAddr = g_strucHookPoint.HookAddr;
pInfo->JmpNewCode.Jmp = 0xE9;
pInfo->JmpNewCode.JmpOffset = NewFunctionAddr -
(ULONG)pInfo - FIELD_OFFSET(HOOK_INFO, JmpNewCode) - 5;
*(ULONG*)((ULONG)pInfo + 19) = *(ULONG *)g_strucHookPoint.HookAddr;
*(UCHAR*)((ULONG)pInfo + 23) = *(UCHAR*)(g_strucHookPoint.HookAddr + 4);
pInfo->JmpOrgCode.Jmp = 0xE9;
pInfo->JmpOrgCode.JmpOffset = g_strucHookPoint.HookAddr - (ULONG)pInfo - \
FIELD_OFFSET(HOOK_INFO, OrgCode) - 5;
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
//
//do hook
//
if ( ClearWp() ){
((PJMP_CODE)(g_strucHookPoint.HookAddr))->Jmp = 0xE9;
((PJMP_CODE)(g_strucHookPoint.HookAddr))->JmpOffset = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpNewCode) - 5;
*(ULONG*)uPushRet = (ULONG)pInfo + FIELD_OFFSET(HOOK_INFO, JmpOrgCode);
SetWp();
return TRUE;
}
return FALSE;
}
BOOLEAN
HookCode95 ( PVOIDpTarFunction, PVOIDpNewFunction, ULONGHookNumber )
{
BOOLEAN bRet = FALSE;
if ( !pTarFunction || !pNewFunction ){
return FALSE;
}
GetFuncHookPoint( pTarFunction, HookNumber );
if ( !g_strucHookPoint.HookType ){
return FALSE;
}
switch( g_strucHookPoint.HookType )
{
case CallHookE8:
bRet = fnCallHookE8( (ULONG)pNewFunction );
break;
case CallHookFF15:
bRet = fnCallHookFF15( (ULONG)pNewFunction );
break;
case InlineHookPre2:
bRet = fnInlineHookPre2( (ULONG)pNewFunction );
break;
case InlineHookPre1:
bRet = fnInlineHookPre1( (ULONG)pNewFunction );
break;
case InlineHookDep2:
bRet = fnInlineHookDep2( (ULONG)pNewFunction );
break;
case InlineHookDep1:
bRet = fnInlineHookDep1( (ULONG)pNewFunction );
break;
case InlineCrazyPatch:
break;
default:
bRet = TRUE;
break;
}
return bRet;
}
VOID UnhookCode95 ( PVOID pNewFunction )
{
ULONG uPushRet = 0;
if ( !pNewFunction ){
return;
}
if ( KeNumberProcessors > 1 )
{
PVOID pThread;
pThread = KeGetCurrentThread();
KeSetAffinityThread( pThread, KeNumberProcessors );
}
uPushRet = FindPushRet( pNewFunction );
if ( *(ULONG*)uPushRet ){
//PHOOK_INFO pInfo = CONTAINING_RECORD( *(ULONG*)uPushRet, PHOOK_INFO, JmpOrgCode );
PHOOK_INFO pInfo = *(ULONG*)uPushRet - 19;
if ( !pInfo ){
return;
}
if ( pInfo->Type != Automatic ){
if ( pInfo->Type == CallHookE8 || pInfo->Type == CallHookFF15 ){
if ( ClearWp() ){
*(ULONG*)(pInfo->OrgAddr) = pInfo->OrgCallval;
*(ULONG*)uPushRet = 0;
}
}else{
if ( pInfo->Type == InlineHookPre2 )
{
if ( ClearWp() ){
RtlCopyMemory( (PVOID)(pInfo->OrgAddr), (PVOID)(*(ULONG*)uPushRet), pInfo->CodeLen );
*(ULONG*)(pInfo->OrgAddr - 4) = 0xCCCCCCCCu;
*(UCHAR*)(pInfo->OrgAddr - 5) = 0xCCu;
}
}else{
if ( pInfo->Type == 4 || pInfo->Type == 5 || pInfo->Type == 6 ){
if ( ClearWp() )
RtlCopyMemory( (PVOID)(pInfo->OrgAddr), (PVOID)(*(ULONG*)uPushRet), pInfo->CodeLen);
}
}
*(ULONG*)uPushRet = 0;
}
SetWp();
}
kfree( pInfo );
}
}
```
LDasm.h
```c
#ifndef _LDASM_
#define _LDASM_
#ifdef __cplusplus
extern "C" {
#endif
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode);
unsigned long __fastcall RetOffofProc(void *Proc, unsigned long uParam, unsigned long uFuncLen);
unsigned long __fastcall SizeOfProc(void *Proc);
char __fastcall IsRelativeCmd(unsigned char *pOpcode);
char __stdcall RelocateJumps(void* FuncPtr, unsigned long Reloc, unsigned long Length);
#ifdef __cplusplus
}
#endif
#endif
```
LDasm.c
```c
#include "LDasm.h"
#define OP_NONE 0x00
#define OP_MODRM 0x01
#define OP_DATA_I8 0x02
#define OP_DATA_I16 0x04
#define OP_DATA_I32 0x08
#define OP_DATA_PRE66_670x10
#define OP_WORD 0x20
#define OP_REL32 0x40
#define UCHAR unsigned char
#define ULONG unsigned long
#define PVOID void*
#define PUCHAR unsigned char*
#define BOOLEAN char
#define FALSE 0
#define TRUE1
UCHAR OpcodeFlags =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_DATA_I8, // 04
OP_DATA_PRE66_67, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_MODRM, // 08
OP_MODRM, // 09
OP_MODRM, // 0A
OP_MODRM, // 0B
OP_DATA_I8, // 0C
OP_DATA_PRE66_67, // 0D
OP_NONE, // 0E
OP_NONE, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_DATA_I8, // 14
OP_DATA_PRE66_67, // 15
OP_NONE, // 16
OP_NONE, // 17
OP_MODRM, // 18
OP_MODRM, // 19
OP_MODRM, // 1A
OP_MODRM, // 1B
OP_DATA_I8, // 1C
OP_DATA_PRE66_67, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_DATA_I8, // 24
OP_DATA_PRE66_67, // 25
OP_NONE, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_DATA_I8, // 2C
OP_DATA_PRE66_67, // 2D
OP_NONE, // 2E
OP_NONE, // 2F
OP_MODRM, // 30
OP_MODRM, // 31
OP_MODRM, // 32
OP_MODRM, // 33
OP_DATA_I8, // 34
OP_DATA_PRE66_67, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_MODRM, // 38
OP_MODRM, // 39
OP_MODRM, // 3A
OP_MODRM, // 3B
OP_DATA_I8, // 3C
OP_DATA_PRE66_67, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_NONE, // 40
OP_NONE, // 41
OP_NONE, // 42
OP_NONE, // 43
OP_NONE, // 44
OP_NONE, // 45
OP_NONE, // 46
OP_NONE, // 47
OP_NONE, // 48
OP_NONE, // 49
OP_NONE, // 4A
OP_NONE, // 4B
OP_NONE, // 4C
OP_NONE, // 4D
OP_NONE, // 4E
OP_NONE, // 4F
OP_NONE, // 50
OP_NONE, // 51
OP_NONE, // 52
OP_NONE, // 53
OP_NONE, // 54
OP_NONE, // 55
OP_NONE, // 56
OP_NONE, // 57
OP_NONE, // 58
OP_NONE, // 59
OP_NONE, // 5A
OP_NONE, // 5B
OP_NONE, // 5C
OP_NONE, // 5D
OP_NONE, // 5E
OP_NONE, // 5F
OP_NONE, // 60
OP_NONE, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_NONE, // 64
OP_NONE, // 65
OP_NONE, // 66
OP_NONE, // 67
OP_DATA_PRE66_67, // 68
OP_MODRM | OP_DATA_PRE66_67, // 69
OP_DATA_I8, // 6A
OP_MODRM | OP_DATA_I8, // 6B
OP_NONE, // 6C
OP_NONE, // 6D
OP_NONE, // 6E
OP_NONE, // 6F
OP_DATA_I8, // 70
OP_DATA_I8, // 71
OP_DATA_I8, // 72
OP_DATA_I8, // 73
OP_DATA_I8, // 74
OP_DATA_I8, // 75
OP_DATA_I8, // 76
OP_DATA_I8, // 77
OP_DATA_I8, // 78
OP_DATA_I8, // 79
OP_DATA_I8, // 7A
OP_DATA_I8, // 7B
OP_DATA_I8, // 7C
OP_DATA_I8, // 7D
OP_DATA_I8, // 7E
OP_DATA_I8, // 7F
OP_MODRM | OP_DATA_I8, // 80
OP_MODRM | OP_DATA_PRE66_67, // 81
OP_MODRM | OP_DATA_I8, // 82
OP_MODRM | OP_DATA_I8, // 83
OP_MODRM, // 84
OP_MODRM, // 85
OP_MODRM, // 86
OP_MODRM, // 87
OP_MODRM, // 88
OP_MODRM, // 89
OP_MODRM, // 8A
OP_MODRM, // 8B
OP_MODRM, // 8C
OP_MODRM, // 8D
OP_MODRM, // 8E
OP_MODRM, // 8F
OP_NONE, // 90
OP_NONE, // 91
OP_NONE, // 92
OP_NONE, // 93
OP_NONE, // 94
OP_NONE, // 95
OP_NONE, // 96
OP_NONE, // 97
OP_NONE, // 98
OP_NONE, // 99
OP_DATA_I16 | OP_DATA_PRE66_67,// 9A
OP_NONE, // 9B
OP_NONE, // 9C
OP_NONE, // 9D
OP_NONE, // 9E
OP_NONE, // 9F
OP_DATA_PRE66_67, // A0
OP_DATA_PRE66_67, // A1
OP_DATA_PRE66_67, // A2
OP_DATA_PRE66_67, // A3
OP_NONE, // A4
OP_NONE, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_DATA_I8, // A8
OP_DATA_PRE66_67, // A9
OP_NONE, // AA
OP_NONE, // AB
OP_NONE, // AC
OP_NONE, // AD
OP_NONE, // AE
OP_NONE, // AF
OP_DATA_I8, // B0
OP_DATA_I8, // B1
OP_DATA_I8, // B2
OP_DATA_I8, // B3
OP_DATA_I8, // B4
OP_DATA_I8, // B5
OP_DATA_I8, // B6
OP_DATA_I8, // B7
OP_DATA_PRE66_67, // B8
OP_DATA_PRE66_67, // B9
OP_DATA_PRE66_67, // BA
OP_DATA_PRE66_67, // BB
OP_DATA_PRE66_67, // BC
OP_DATA_PRE66_67, // BD
OP_DATA_PRE66_67, // BE
OP_DATA_PRE66_67, // BF
OP_MODRM | OP_DATA_I8, // C0
OP_MODRM | OP_DATA_I8, // C1
OP_DATA_I16, // C2
OP_NONE, // C3
OP_MODRM, // C4
OP_MODRM, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM | OP_DATA_PRE66_67, // C7
OP_DATA_I8 | OP_DATA_I16, // C8
OP_NONE, // C9
OP_DATA_I16, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_DATA_I8, // CD
OP_NONE, // CE
OP_NONE, // CF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_DATA_I8, // D4
OP_DATA_I8, // D5
OP_NONE, // D6
OP_NONE, // D7
OP_WORD, // D8
OP_WORD, // D9
OP_WORD, // DA
OP_WORD, // DB
OP_WORD, // DC
OP_WORD, // DD
OP_WORD, // DE
OP_WORD, // DF
OP_DATA_I8, // E0
OP_DATA_I8, // E1
OP_DATA_I8, // E2
OP_DATA_I8, // E3
OP_DATA_I8, // E4
OP_DATA_I8, // E5
OP_DATA_I8, // E6
OP_DATA_I8, // E7
OP_DATA_PRE66_67 | OP_REL32, // E8
OP_DATA_PRE66_67 | OP_REL32, // E9
OP_DATA_I16 | OP_DATA_PRE66_67,// EA
OP_DATA_I8, // EB
OP_NONE, // EC
OP_NONE, // ED
OP_NONE, // EE
OP_NONE, // EF
OP_NONE, // F0
OP_NONE, // F1
OP_NONE, // F2
OP_NONE, // F3
OP_NONE, // F4
OP_NONE, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_NONE, // F8
OP_NONE, // F9
OP_NONE, // FA
OP_NONE, // FB
OP_NONE, // FC
OP_NONE, // FD
OP_MODRM, // FE
OP_MODRM | OP_REL32 // FF
};
UCHAR OpcodeFlagsExt =
{
OP_MODRM, // 00
OP_MODRM, // 01
OP_MODRM, // 02
OP_MODRM, // 03
OP_NONE, // 04
OP_NONE, // 05
OP_NONE, // 06
OP_NONE, // 07
OP_NONE, // 08
OP_NONE, // 09
OP_NONE, // 0A
OP_NONE, // 0B
OP_NONE, // 0C
OP_MODRM, // 0D
OP_NONE, // 0E
OP_MODRM | OP_DATA_I8, // 0F
OP_MODRM, // 10
OP_MODRM, // 11
OP_MODRM, // 12
OP_MODRM, // 13
OP_MODRM, // 14
OP_MODRM, // 15
OP_MODRM, // 16
OP_MODRM, // 17
OP_MODRM, // 18
OP_NONE, // 19
OP_NONE, // 1A
OP_NONE, // 1B
OP_NONE, // 1C
OP_NONE, // 1D
OP_NONE, // 1E
OP_NONE, // 1F
OP_MODRM, // 20
OP_MODRM, // 21
OP_MODRM, // 22
OP_MODRM, // 23
OP_MODRM, // 24
OP_NONE, // 25
OP_MODRM, // 26
OP_NONE, // 27
OP_MODRM, // 28
OP_MODRM, // 29
OP_MODRM, // 2A
OP_MODRM, // 2B
OP_MODRM, // 2C
OP_MODRM, // 2D
OP_MODRM, // 2E
OP_MODRM, // 2F
OP_NONE, // 30
OP_NONE, // 31
OP_NONE, // 32
OP_NONE, // 33
OP_NONE, // 34
OP_NONE, // 35
OP_NONE, // 36
OP_NONE, // 37
OP_NONE, // 38
OP_NONE, // 39
OP_NONE, // 3A
OP_NONE, // 3B
OP_NONE, // 3C
OP_NONE, // 3D
OP_NONE, // 3E
OP_NONE, // 3F
OP_MODRM, // 40
OP_MODRM, // 41
OP_MODRM, // 42
OP_MODRM, // 43
OP_MODRM, // 44
OP_MODRM, // 45
OP_MODRM, // 46
OP_MODRM, // 47
OP_MODRM, // 48
OP_MODRM, // 49
OP_MODRM, // 4A
OP_MODRM, // 4B
OP_MODRM, // 4C
OP_MODRM, // 4D
OP_MODRM, // 4E
OP_MODRM, // 4F
OP_MODRM, // 50
OP_MODRM, // 51
OP_MODRM, // 52
OP_MODRM, // 53
OP_MODRM, // 54
OP_MODRM, // 55
OP_MODRM, // 56
OP_MODRM, // 57
OP_MODRM, // 58
OP_MODRM, // 59
OP_MODRM, // 5A
OP_MODRM, // 5B
OP_MODRM, // 5C
OP_MODRM, // 5D
OP_MODRM, // 5E
OP_MODRM, // 5F
OP_MODRM, // 60
OP_MODRM, // 61
OP_MODRM, // 62
OP_MODRM, // 63
OP_MODRM, // 64
OP_MODRM, // 65
OP_MODRM, // 66
OP_MODRM, // 67
OP_MODRM, // 68
OP_MODRM, // 69
OP_MODRM, // 6A
OP_MODRM, // 6B
OP_MODRM, // 6C
OP_MODRM, // 6D
OP_MODRM, // 6E
OP_MODRM, // 6F
OP_MODRM | OP_DATA_I8, // 70
OP_MODRM | OP_DATA_I8, // 71
OP_MODRM | OP_DATA_I8, // 72
OP_MODRM | OP_DATA_I8, // 73
OP_MODRM, // 74
OP_MODRM, // 75
OP_MODRM, // 76
OP_NONE, // 77
OP_NONE, // 78
OP_NONE, // 79
OP_NONE, // 7A
OP_NONE, // 7B
OP_MODRM, // 7C
OP_MODRM, // 7D
OP_MODRM, // 7E
OP_MODRM, // 7F
OP_DATA_PRE66_67 | OP_REL32, // 80
OP_DATA_PRE66_67 | OP_REL32, // 81
OP_DATA_PRE66_67 | OP_REL32, // 82
OP_DATA_PRE66_67 | OP_REL32, // 83
OP_DATA_PRE66_67 | OP_REL32, // 84
OP_DATA_PRE66_67 | OP_REL32, // 85
OP_DATA_PRE66_67 | OP_REL32, // 86
OP_DATA_PRE66_67 | OP_REL32, // 87
OP_DATA_PRE66_67 | OP_REL32, // 88
OP_DATA_PRE66_67 | OP_REL32, // 89
OP_DATA_PRE66_67 | OP_REL32, // 8A
OP_DATA_PRE66_67 | OP_REL32, // 8B
OP_DATA_PRE66_67 | OP_REL32, // 8C
OP_DATA_PRE66_67 | OP_REL32, // 8D
OP_DATA_PRE66_67 | OP_REL32, // 8E
OP_DATA_PRE66_67 | OP_REL32, // 8F
OP_MODRM, // 90
OP_MODRM, // 91
OP_MODRM, // 92
OP_MODRM, // 93
OP_MODRM, // 94
OP_MODRM, // 95
OP_MODRM, // 96
OP_MODRM, // 97
OP_MODRM, // 98
OP_MODRM, // 99
OP_MODRM, // 9A
OP_MODRM, // 9B
OP_MODRM, // 9C
OP_MODRM, // 9D
OP_MODRM, // 9E
OP_MODRM, // 9F
OP_NONE, // A0
OP_NONE, // A1
OP_NONE, // A2
OP_MODRM, // A3
OP_MODRM | OP_DATA_I8, // A4
OP_MODRM, // A5
OP_NONE, // A6
OP_NONE, // A7
OP_NONE, // A8
OP_NONE, // A9
OP_NONE, // AA
OP_MODRM, // AB
OP_MODRM | OP_DATA_I8, // AC
OP_MODRM, // AD
OP_MODRM, // AE
OP_MODRM, // AF
OP_MODRM, // B0
OP_MODRM, // B1
OP_MODRM, // B2
OP_MODRM, // B3
OP_MODRM, // B4
OP_MODRM, // B5
OP_MODRM, // B6
OP_MODRM, // B7
OP_NONE, // B8
OP_NONE, // B9
OP_MODRM | OP_DATA_I8, // BA
OP_MODRM, // BB
OP_MODRM, // BC
OP_MODRM, // BD
OP_MODRM, // BE
OP_MODRM, // BF
OP_MODRM, // C0
OP_MODRM, // C1
OP_MODRM | OP_DATA_I8, // C2
OP_MODRM, // C3
OP_MODRM | OP_DATA_I8, // C4
OP_MODRM | OP_DATA_I8, // C5
OP_MODRM | OP_DATA_I8, // C6
OP_MODRM, // C7
OP_NONE, // C8
OP_NONE, // C9
OP_NONE, // CA
OP_NONE, // CB
OP_NONE, // CC
OP_NONE, // CD
OP_NONE, // CE
OP_NONE, // CF
OP_MODRM, // D0
OP_MODRM, // D1
OP_MODRM, // D2
OP_MODRM, // D3
OP_MODRM, // D4
OP_MODRM, // D5
OP_MODRM, // D6
OP_MODRM, // D7
OP_MODRM, // D8
OP_MODRM, // D9
OP_MODRM, // DA
OP_MODRM, // DB
OP_MODRM, // DC
OP_MODRM, // DD
OP_MODRM, // DE
OP_MODRM, // DF
OP_MODRM, // E0
OP_MODRM, // E1
OP_MODRM, // E2
OP_MODRM, // E3
OP_MODRM, // E4
OP_MODRM, // E5
OP_MODRM, // E6
OP_MODRM, // E7
OP_MODRM, // E8
OP_MODRM, // E9
OP_MODRM, // EA
OP_MODRM, // EB
OP_MODRM, // EC
OP_MODRM, // ED
OP_MODRM, // EE
OP_MODRM, // EF
OP_MODRM, // F0
OP_MODRM, // F1
OP_MODRM, // F2
OP_MODRM, // F3
OP_MODRM, // F4
OP_MODRM, // F5
OP_MODRM, // F6
OP_MODRM, // F7
OP_MODRM, // F8
OP_MODRM, // F9
OP_MODRM, // FA
OP_MODRM, // FB
OP_MODRM, // FC
OP_MODRM, // FD
OP_MODRM, // FE
OP_NONE // FF
};
unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode)
{
PUCHAR cPtr;
UCHAR Flags;
BOOLEAN PFX66, PFX67;
BOOLEAN SibPresent;
UCHAR iMod, iRM, iReg;
UCHAR OffsetSize, Add;
UCHAR Opcode;
OffsetSize = 0;
PFX66 = FALSE;
PFX67 = FALSE;
cPtr = (PUCHAR)Code;
while ( (*cPtr == 0x2E) || (*cPtr == 0x3E) || (*cPtr == 0x36) ||
(*cPtr == 0x26) || (*cPtr == 0x64) || (*cPtr == 0x65) ||
(*cPtr == 0xF0) || (*cPtr == 0xF2) || (*cPtr == 0xF3) ||
(*cPtr == 0x66) || (*cPtr == 0x67) )
{
if (*cPtr == 0x66) PFX66 = TRUE;
if (*cPtr == 0x67) PFX67 = TRUE;
cPtr++;
if (cPtr > (PUCHAR)Code + 16) return 0;
}
Opcode = *cPtr;
if (pOpcode) *pOpcode = cPtr;
if (*cPtr == 0x0F)
{
cPtr++;
Flags = OpcodeFlagsExt[*cPtr];
} else
{
Flags = OpcodeFlags;
if (Opcode >= 0xA0 && Opcode <= 0xA3) PFX66 = PFX67;
}
cPtr++;
if (Flags & OP_WORD) cPtr++;
if (Flags & OP_MODRM)
{
iMod = *cPtr >> 6;
iReg = (*cPtr & 0x38) >> 3;
iRM= *cPtr &7;
cPtr++;
if ((Opcode == 0xF6) && !iReg) Flags |= OP_DATA_I8;
if ((Opcode == 0xF7) && !iReg) Flags |= OP_DATA_PRE66_67;
SibPresent = !PFX67 & (iRM == 4);
switch (iMod)
{
case 0:
if ( PFX67 && (iRM == 6)) OffsetSize = 2;
if (!PFX67 && (iRM == 5)) OffsetSize = 4;
break;
case 1: OffsetSize = 1;
break;
case 2: if (PFX67) OffsetSize = 2; else OffsetSize = 4;
break;
case 3: SibPresent = FALSE;
}
if (SibPresent)
{
if (((*cPtr & 7) == 5) && ( (!iMod) || (iMod == 2) )) OffsetSize = 4;
cPtr++;
}
cPtr = (PUCHAR)(ULONG)cPtr + OffsetSize;
}
if (Flags & OP_DATA_I8)cPtr++;
if (Flags & OP_DATA_I16) cPtr += 2;
if (Flags & OP_DATA_I32) cPtr += 4;
if (PFX66) Add = 2; else Add = 4;
if (Flags & OP_DATA_PRE66_67) cPtr += Add;
return (ULONG)cPtr - (ULONG)Code;
}
unsigned long __fastcall SizeOfProc(void *Proc)
{
ULONGLength;
PUCHAR pOpcode;
ULONGResult = 0;
do
{
Length = SizeOfCode(Proc, &pOpcode);
Result += Length;
if ((Length == 1) && (*pOpcode == 0xC3)) break;
if ((Length == 3) && (*pOpcode == 0xC2)) break;
Proc = (PVOID)((ULONG)Proc + Length);
} while (Length);
return Result;
}
unsigned long __fastcall RetOffofProc(void *Proc, unsigned long uParam, unsigned long uFuncLen)
{
ULONGLength;
PUCHAR pOpcode;
ULONGResult = 0;
do
{
Length = SizeOfCode(Proc, &pOpcode);
if ((Length == 1) && (*pOpcode == 0xC3) && uParam == 0) break;
if ((Length == 3) && (*pOpcode == 0xC2))
{
//*((unsigned long*)((PUCHAR)pOpcode + 1)) == uParam;
unsigned short test = *((unsigned short*)((PUCHAR)pOpcode + 1));
if ( test == uParam )
{
break;
}
}
Result += Length;
Proc = (PVOID)((ULONG)Proc + Length);
} while (Length && Result < uFuncLen);
return Result;
}
char __fastcall IsRelativeCmd(unsigned char *pOpcode)
{
UCHAR Flags;
if (*pOpcode == 0x0F) Flags = OpcodeFlagsExt[*(PUCHAR)((ULONG)pOpcode + 1)];
else Flags = OpcodeFlags[*pOpcode];
return (Flags & OP_REL32);
}
//By iceboy
char __stdcall RelocateJumps(PVOID FuncPtr, ULONG Reloc, ULONG Length)
{
ULONG Offset = 0, CodeLen;
PUCHAR pOpcode = 0;
do
{
CodeLen = SizeOfCode((PVOID)((ULONG)FuncPtr + Offset), &pOpcode);
if (CodeLen == 0) return FALSE;
switch (*(PUCHAR)((ULONG)FuncPtr + Offset))
{
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77:
case 0x78:
case 0x79:
case 0x7a:
case 0x7b:
case 0x7c:
case 0x7d:
case 0x7e:
case 0x7f:
case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
case 0xea:
case 0xeb:
return FALSE;
case 0xe8:
case 0xe9:
*(ULONG *)((ULONG)FuncPtr + Offset + 1) -= Reloc;
break;
}
Offset += CodeLen;
}while (Offset < Length);
return TRUE;
}
```
页:
[1]