admin 发表于 2024-12-29 22:37:15

一个简单的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]
查看完整版本: 一个简单的inlineHook的实现