摘除XP系統LoadImageNotifyRoutine回調常式

來源:互聯網
上載者:User

在XP系統下調用PsSetLoadImageNotifyRoutine註冊LoadImage回調常式,就能夠在每個進程或者DLL載入的時候註冊的常式得到回調。

看看PsSetLoadImageNotifyRoutine的代碼

kd> u PsSetLoadImageNotifyRoutine L22

nt!PsSetLoadImageNotifyRoutine:

805c718c 8bff            mov     edi,edi

805c718e 55              push    ebp

805c718f 8bec            mov     ebp,esp

805c7191 53              push    ebx

805c7192 57              push    edi

805c7193 33ff            xor     edi,edi

805c7195 57              push    edi

805c7196 ff7508          push    dword ptr [ebp+8]

805c7199 e87cd10300      call    nt!ExAllocateCallBack (8060431a)

805c719e 8bd8            mov     ebx,eax

805c71a0 3bdf            cmp     ebx,edi

805c71a2 7507            jne     nt!PsSetLoadImageNotifyRoutine+0x1f (805c71ab)

805c71a4 b89a0000c0      mov     eax,0C000009Ah

805c71a9 eb2a            jmp     nt!PsSetLoadImageNotifyRoutine+0x49 (805c71d5)

805c71ab56             push    esi

805c71acbe80b25580      mov     esi,offset nt!PspLoadImageNotifyRoutine(8055b280)

805c71b1 6a00            push    0

805c71b3 53              push    ebx

805c71b4 56              push    esi

805c71b5 e890d10300      call    nt!ExCompareExchangeCallBack (8060434a)

805c71ba 84c0            test    al,al

805c71bc 751d            jne     nt!PsSetLoadImageNotifyRoutine+0x4f (805c71db)

805c71be 83c704          add     edi,4

805c71c1 83c604          add     esi,4

805c71c4 83ff20          cmp     edi,20h

805c71c7 72e8            jb      nt!PsSetLoadImageNotifyRoutine+0x25 (805c71b1)

805c71c9 53              push    ebx

805c71ca e819d00300      call    nt!RtlpFreeAtom (806041e8)

805c71cf b89a0000c0      mov     eax,0C000009Ah

805c71d4 5e              pop     esi

805c71d5 5f              pop     edi

805c71d6 5b              pop     ebx

805c71d7 5d              pop     ebp

805c71d8 c20400          ret     4

以上0x56和0xbe是特徵碼

對應的C代碼(摘自WRK 1.2)

NTSTATUS

PsSetLoadImageNotifyRoutine(

    __in PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine

    )

{

    ULONG i;

    PEX_CALLBACK_ROUTINE_BLOCK CallBack;

 

    PAGED_CODE();

    //Allocate a new callback block.

    CallBack = ExAllocateCallBack ((PEX_CALLBACK_FUNCTION) NotifyRoutine, NULL);

    if (CallBack == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;

    }

 

    for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) {

        // Try and swap a null entry for the new block.

        if (ExCompareExchangeCallBack (&PspLoadImageNotifyRoutine[i],

                                       CallBack,

                                       NULL)) {

            InterlockedIncrement ((PLONG) &PspLoadImageNotifyRoutineCount);

            PsImageNotifyEnabled = TRUE;

            return STATUS_SUCCESS;

        }

    }

    // No slots left. Free the block and return.

    ExFreeCallBack (CallBack);

    return STATUS_INSUFFICIENT_RESOURCES;

}

看到PspLoadImageNotifyRoutine是一個數組,定義如下:

EX_CALLBACK PspLoadImageNotifyRoutine[PSP_MAX_LOAD_IMAGE_NOTIFY];

要摘除回調常式就必須得到PspLoadImageNotifyRoutine變數的地址,這就使用了特徵碼搜尋法來定位變數位置(相關文章可在看雪上面找到)

這裡附上摘除回呼函數的代碼

 

// LoadImage回調結構體(摘自WRK)

#pragma pack(1)           

typedef struct _EX_FAST_REF

{

    union

    {

        PVOID Object;

        ULONG_PTR RefCnt:3;

        ULONG_PTR Value;

    };

} EX_FAST_REF, *PEX_FAST_REF;

 

typedef struct _EX_CALLBACK_ROUTINE_BLOCK

{

    EX_RUNDOWN_REF RundownProtect;

    PEX_CALLBACK_FUNCTION Function;

    PVOID Context;

} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;

#pragma pack()

 

// PspLoadImageNotifyRoutine數組大小

#define PSP_MAX_LOAD_IMAGE_NOTIFY           8

 

// 系統PspLoadImageNotifyRoutine變數位置

PULONG g_PspLoadImageNotifyRoutine = NULL;

// 根據特徵碼尋找PspLoadImageNotifyRoutine變數的地址

PULONG FindPspLoadImageNotifyRoutine( PUCHAR FuncBase )

{

    ULONG nIndex;

    PULONG result = NULL;

 

    // 尋找ing

    for ( nIndex = 0; nIndex < 512; ++nIndex )

    {

        // 比較頭部(這裡的0x56和0xbe是特徵碼)

        if ( (*(UCHAR*)FuncBase == 0x56) && (*(UCHAR*)(FuncBase + 1) == 0xbe) )

        {

            // 儲存地址並返回

            result = *(PULONG)(FuncBase + 2);

            break;

        }

 

        // 繼續遍曆

        ++FuncBase;

    }

 

    return result;

}

// 檢測並掛鈎NP的回呼函數

VOID RemoveLoadImageCallBack()

{

    PEX_FAST_REF ExRef;

    ULONG nIndex;

    NTSTATUS status;

 

    ExRef = (PEX_FAST_REF)(g_PspLoadImageNotifyRoutine);

    for ( nIndex = 0; nIndex < PSP_MAX_LOAD_IMAGE_NOTIFY; ++nIndex )

    {

        PEX_CALLBACK_ROUTINE_BLOCK Point;

        // 去掉末尾3位元

        Point = (PEX_CALLBACK_ROUTINE_BLOCK)(ExRef->Value & ~7);      // 詳見WRK

        if ( MmIsAddressValid((PVOID)Point) )

        {

            // 移除註冊的回呼函數

            status = PsRemoveLoadImageNotifyRoutine( Point->Function );

            if ( NT_SUCCESS(status) )

            {

                KdPrint(("remove LoadImage notify success: %d.\n", nIndex));

            }

        }

        ++ExRef;

    }

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.