摘掉关机回调链上的应和结构

UNICODE_STRING  g_FuncName_KeAcquireQueuedSpinLock = RTL_CONSTANT_STRING(L"KeAcquireQueuedSpinLock");
UNICODE_STRING  g_FuncName_KeRaiseIrqlToDpcLevel = RTL_CONSTANT_STRING(L"KeRaiseIrqlToDpcLevel");
UNICODE_STRING  g_FuncName_IoRegisterShutdownNotification = RTL_CONSTANT_STRING(L"IoRegisterShutdownNotification");

typedef struct _SHUTDOWN_PACKET 
{
    LIST_ENTRY ListEntry;
    PDEVICE_OBJECT DeviceObject;
} SHUTDOWN_PACKET, *PSHUTDOWN_PACKET;

void sub_13E96( PVOID ImageBase, PVOID ImageSize )
{
    PUCHAR      _KeAcquireQueuedSpinLock = NULL;
    PUCHAR      _KeRaiseIrqlToDpcLevel = NULL;
    PUCHAR      _IoRegisterShutdownNotification = NULL;
    PUCHAR      IopInterlockedInsertHeadList = NULL;
    PLIST_ENTRY IopNotifyShutdownQueueHead = NULL;
    ULONG       Offset = 0;
    ULONG       SubOffset = 0;
    ULONG       CallAddr = 0;
    PVOID       MoveAddr = NULL;

    _KeAcquireQueuedSpinLock = (PUCHAR)MmGetSystemRoutineAddress(&g_FuncName_KeAcquireQueuedSpinLock);
    _KeRaiseIrqlToDpcLevel = (PUCHAR)MmGetSystemRoutineAddress(&g_FuncName_KeRaiseIrqlToDpcLevel);
    _IoRegisterShutdownNotification =(PUCHAR)MmGetSystemRoutineAddress(&g_FuncName_IoRegisterShutdownNotification);

    do
    {
        //
        //在IoRegisterShutdownNotification中定位nt!IopNotifyShutdownQueueHead和nt!IopInterlockedInsertHeadList
        //

        if( _IoRegisterShutdownNotification[Offset] != 0xB9 && _IoRegisterShutdownNotification[Offset] != 0xBF 
                || _IoRegisterShutdownNotification[Offset+5] != 0xE8 )
        {
            continue;
        }

        CallAddr = *(PULONG)( _IoRegisterShutdownNotification+Offset+6 );
        if(! MmIsAddressValid( _IoRegisterShutdownNotification+Offset+10+CallAddr ) )
        {
            continue;
        }

        MoveAddr = *(PVOID*)(_IoRegisterShutdownNotification+Offset+1);
        if(!MmIsAddressValid( MoveAddr ) )
        {
            continue;
        }

        IopInterlockedInsertHeadList = _IoRegisterShutdownNotification+Offset+10+CallAddr;
        SubOffset = 0;
        do
        {
            //
            //从可疑的IopInterlockedInsertHeadList函数中找到对KeAcquireQueuedSpinLock或者KeRaiseIrqlToDpcLevel的调用
            //

            if( ! MmIsAddressValid( IopInterlockedInsertHeadList+SubOffset )
            || ! MmIsAddressValid(IopInterlockedInsertHeadList+6)
            || *(PUSHORT)(IopInterlockedInsertHeadList+SubOffset) != 0x15FF )
            {
                continue;
            }

            CallAddr = *(PULONG)(IopInterlockedInsertHeadList+SubOffset+2);
            if( !MmIsAddressValid((PVOID)CallAddr) || !MmIsAddressValid((PUCHAR)CallAddr+3) )
            {
                continue;
            }

            CallAddr = *(PULONG)CallAddr;
            if( (PUCHAR)CallAddr == _KeAcquireQueuedSpinLock 
                || (PUCHAR)CallAddr==_KeRaiseIrqlToDpcLevel )
            {
                IopNotifyShutdownQueueHead = *(PLIST_ENTRY*)(_IoRegisterShutdownNotification+Offset+1);
                break;
            }

        }while( ++SubOffset < 0x20);

        if( IopNotifyShutdownQueueHead )
        {
            break;
        }

    }while( ++Offset < 0x60);    

    if(IopNotifyShutdownQueueHead)
    {               
        KIRQL               OldIrql = 0;
        PSHUTDOWN_PACKET    ShutdownPacket = NULL;
        PDEVICE_OBJECT      DeviceObject = NULL;
        PDRIVER_OBJECT      DriverObject = NULL;
        PVOID               ShutdownDisp = NULL;                
        PLIST_ENTRY         pNotifyShutdownNode = IopNotifyShutdownQueueHead->Flink;             

        OldIrql = KeAcquireQueuedSpinLock( LockQueueIoDatabaseLock );               
        while( pNotifyShutdownNode !=IopNotifyShutdownQueueHead )
        {
            ShutdownPacket = (PSHUTDOWN_PACKET)pNotifyShutdownNode;
            DeviceObject = ShutdownPacket->DeviceObject,
            DriverObject = DeviceObject->DriverObject;
            ShutdownDisp = DriverObject->MajorFunction[IRP_MJ_SHUTDOWN];

            if( ImageBase<ShutdownDisp && ((ULONG)ImageBase+ImageSize)>(ULONG)ShutdownDisp )
            {
                pNotifyShutdownNode->Blink->Flink = pNotifyShutdownNode->Flink;
                pNotifyShutdownNode->Flink->Blink = pNotifyShutdownNode->Blink;
                pNotifyShutdownNode = pNotifyShutdownNode->Blink;
                ObfDereferenceObject(DeviceObject);     
                ExFreePool(ShutdownPacket);
            }       

            pNotifyShutdownNode = pNotifyShutdownNode->Flink;
        }
        KeReleaseQueuedSpinLock( LockQueueIoDatabaseLock,OldIrql );
    }
}
//该片段来自于http://outofmemory.cn

本文由华夏彩票发布于关于计算机,转载请注明出处:摘掉关机回调链上的应和结构

您可能还会对下面的文章感兴趣: