天天看點

undocumented function--還原的IoCreateDriver()

通過WinDbg得到的反彙編代碼來重寫的IoCreateDriver(),完成之後對它的大概流程有了基本的了解。這個函數的目的是 依據提供的兩個參數,一個是名稱,一個是驅動初始化例程,來建立一個輕量級的驅動程式—功能不完善;初始化例程是完成相關任務。寫完之後感覺有些不對,有些地方将函數往字元串的位址拷,有的地方調用字元串。有的地方沒看明白,僅供參考:(。

NTSTATTUS IoCreateDriver(PUNICODE_STRING Name,
                        PVOID    DriverInit)
{
    NTSTATUS status=STATUS_SUCCESS;
    USHORT Length;//esp+10
    USHORT MaximumLength;   //esp+12
    char* DriverName; //esp+14
    PVIUD LocalRoutine;//esp+18h
    PVOID Pool,PoolForName;  //esp+20h
    USHORT fakeHandle; //esp+24
    PVOID *pDriverObject;//esp+28h
    PDRIVER_OBJECT DriverObject;  //esp+2c
    PDRIVER_OBJECT ReturnedObject;//0x30
    PDRIVER_OBJECT DriverToInsert;//esp+34h
    LPWSTR pszDest;  //esp+54h  0x3c
    ULONG Cookie=(security_cookie)^(esp); //esp+0C0h
    //
    LocalRoutine=DriverInit;
    if(!Name)  //jne 0x84名稱為空,下面就是去弄個名字
    {
        RtlStringCchPrintfW(pszDest,
                            0x3c,
                            "??::NNGAKEGL::'string'",
                            KeTickCount);
        RtlStringCchLengthW(pszDest,
                            0x3c,
                            esp+20h);
        if((0xFFFF)=<*(esp+1ch))  //jbe 0x6b
        {
            _security_check_cookie(Cookie^(esp)); //0x314
            return STATUS_BUFFER_OVERFLOW; //#define STATUS_BUFFER_OVERFLOW ((NTSATTUS)0x80000005L)
        }
        *(esp+1ch)=*(esp+1ch)*2; //0x6b  2bytes
        Length=*(esp+1ch)&(0x0000fff);
        MaximumLength=Length+2;
        DriverName=(esp+50h);
    }
    else //0x84
    {
        DriverName=Name->Buffer;
        Length=Name->Length;
    }
    //esp+40h
    status=IoCreateObject(0,*IoDriverObjectType,(esp+50),0,0
                   0xc4,0,0,pDriverObject);//建立驅動對象
    DriverObject=*pDriverObject;
    if(!status) //jl 0x314
    {
        _security_check_cookie(Cookie^(esp));
        return status;
    }
    memset(DriverObject,0,0xc4);  /*be careful,the size of DriverObject struct here is not same as the value shown under WinDbg.There maybe 
something undocumented! */
    (DriverObject+0xa8)=DriverObject;
    DriverObejct->DriverExtension->DriverObject=DriverObject;
    DriverToInsert=DriverObject->DriverExtension->DriverObject;

    DriverObject->Type=4;
    DriverObject->Flags=4;
    DriverObject->Size=0xa8;
    //初始化28個MajorFunction
    for(int i=0;i<0x1c;i++)
    {
        DriverObject->MajorFunction[i]=IopInvalidDeviceRequest;
    }
    DriverObject->DriverInit=DriverInit;
    IoGetCurrentThread()->WaitBlock.WaitKey--;
    ExAcquireResourceSharedLite(PsLoadedModuleResource,1);
    //确定DriverStart
    PLIST_ENTRY temListEntry=PsLoadedModuleList;
    if(temListEntry->Flink!=PsLoadedModuleList) //list 
    {
       while(temListEntry->Flink!=PsLoadedModuleList)
       {
           if((LocalRoutine>*(tempListEntry->Flink+0x18))
               &&(LocalRoutine<(*(temListEntry->Flink+0x18)+
               *(temListEntry->Flink+0x20))
           {
               DriverObject->DriverStart=temListEntry+*(temListEntry+0x18);
               break;
           }
           temListEntry=temListEntry->Flink;
       }
    }
    //0x172
    ExReleaseResourceLite(PsLoadedModuleResource);
    if(!(++IoGerCurrentThread()->WaitBlock.WaitKey)) //je 0x1a6
    {
        if((IoGetCurrentThread()->ApcState.ApcListHead[0]!=
            IoGetCurrentThread()->ApcState.ApcListHead[0].Flink))||
            (IoGetCurrentThread()->SpecialApcDisable==0))
        {
            KiCheckForKernelApcDelivery();
        }
    }
    ULONG tem=0;  //0x1a6
    tem=Length;
    tem=tem+2;
    if(!ViVerifierDriverAddedThunkListHead) //jne 0x1c5
    {
        Pool=ExAllocatePoolWithTag(PagedPool,tem,0x20206f49); //Io
    }
    else //0x1c5
    {
        tem=*MmVerifierData;
        Pool=ExAllocatePoolWithTagPriority(PagedPool,tem,0x20206f49,
                                      ((tem&0x10)|0x40)/2);
    }
    if(Pool) //je 0x2fb
    {
        *(esp+1eh)=tem;
        tem=Length;
        fakeHandle=tem;
        mempy(esp+28,esp+18,tem);//problem
        //将對象插入到連結清單中管理 
        status=IoInsertObjectEx(0,1,0,0,
                         DriverToInsert,(esp+38),0);//esp+38h==HANDLE???
        if(!status) //jl 312
        {
            _security_check_cookie(Cookie^(esp));
            return status;
        }
        status=ObReferenceObjectByHandle(Handle,0,*IoDriverObjectType,
                                         0,&ReturnedObject,0);
        if(!status) //jge 0x289
        { //can not reference the inserted object ,insert fails
            ZwMakeTemporaryObject(fakeHandle,);//插入失敗,做個臨時的
            ZwClose(fakeHandle);
            _security_check_cookie(Cookie^(esp));
            return status;
        }
        ZwClose(fakeHandle);
        if(!*ViVerifierDriverAddedThunkListHead) //jne 0x25a
        {
            PoolForName=ExAllocatePoolWithTag(0,MaximumLength,0x20206f49);
        }
        else //0x2a5
        {
            tem=*MmVerifierData;
            PoolForName=ExAllocatePoolWithTagPriority(PagedPool,Length,0x20206f49,
                                      ((tem&0x10)|0x40)/2);
        }
        //0x2bd
        ReturnedObject->DriverName.Buffer=PoolForName;
        if(PoolForName)//je 0x2ed
        { 
            ReturnedObject->DriverName.MaximumLength=MaximumLength;
            ReturnedObject->DriverName.Length=Length;
            memcpy(PoolForName,DriverName,MaximumLength); //??????
        }
        status=call(esp+20h)(esi,0);//(esp+20h)好像是字元串,怎麼用成了函數
        if(NT_SUCCESS(status))
        {
            _security_check_cookie(Cookie^(esp));
            return status;
        }
        ObMakeTemporaryObject(DriverObjcet);
        ObfDereferenceObject(DriverObject);
         _security_check_cookie(Cookie^(esp));
        return status;
    }
    else//0x2fb
    {
        status=STATUS_INSUFFICIENT_RESOURCES;  //0X9A
        ObMakeTemporaryObject(DriverObjcet);
        ObfDereferenceObject(DriverObject);
         _security_check_cookie(Cookie^(esp));
        return status;
    }
}

           

繼續閱讀