登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 151|回复: 0

一个简单的inlineHook的实现

[复制链接]

91

主题

9

回帖

477

积分

管理员

积分
477
发表于 2024-12-29 22:37:15 | 显示全部楼层 |阅读模式

main.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[5];       /*24*/
    JMP_CODE JmpOrgCode;    /*29*/
    UCHAR unknown[7];       /*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[4] == 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 ( PVOID  pTarFunction, PVOID  pNewFunction, ULONG  HookNumber )
{
    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

#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

#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_67  0x10
#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 TRUE  1

UCHAR OpcodeFlags[256] = 
{
    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[256] =
{
    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[Opcode];
        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)
{
    ULONG  Length;
    PUCHAR pOpcode;
    ULONG  Result = 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)
{
    ULONG  Length;
    PUCHAR pOpcode;
    ULONG  Result = 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;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-1-30 23:01 , Processed in 0.074615 second(s), 27 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表