逆向NP处理报文例程

来源:互联网 发布:想在淘宝买情趣用品 编辑:程序博客网 时间:2024/06/05 18:36

NTSTATUS DispatchIoControl(PFILE_OBJECT FileObject,  //+8FileObject
                           BOOLEAN IsMyRequest,//+c这里都是1
                           PVOID inputBuffer,//10这里是Irp->AssociatedIrp->SystemBuffer
                           ULONG inputBufferLength,//14
                           PVOID outputBuffer,//18这里也是Irp->AssociatedIrp->SystemBuffer
                           ULONG outputBufferLength,//1c pIrpStack->Parameters.DeviceIoControl.OutputBufferLength
                           ULONG IoControlCode,//20
                           PIO_STATUS_BLOCK pIrpStatus,//24
                           PDEVICE_OBJECT DeviceObject //28
                           )
{
    VOID *dword_1000d560;
    DWORD dword_1000d564;
    DWORD dword_1000c7f8;
    DWORD dwTem1;
    PVOID pBuffer;
    pIrpStatus->Status      = STATUS_SUCCESS;
    pIrpStatus->Information = 0;
    switch(IoControlCode)
    {
    case 0x84020044:
        {
           

            if(inputBufferLength < 0x14 || inputBuffer  == NULL /
                ||outputBufferLength < 4 || outputBuffer  == NULL)
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER ;
                break;
            }
            memcpy(dword_1000d560,inputBuffer,0x14); //d560是个全局变量
            dword_1000c7f8 = dword_1000d564+dword_1000d560;

            if(dword_1000d564 == 0)
            {
                pIrpStatus->Information = 4;
                outputBuffer  = NULL;
                break;
            }
            UnKownHOOK(hand,dword_1000d560,dword_1000d568,Length,&dwTem1); //这个函数成功返回的,失败0
            if(dwTem1 == 0)
                pIrpStatus->Status = STATUS_UNSUCCESSFUL;
            pIrpStatus->Information = 4;
            *outputBuffer = 1; //这个用的是UnKownHook返回的值
            break;


        }
    case 0x84020028: //这个和上面的差不多
        {
            if(inputBufferLength < 0x14 || inputBuffer  == NULL /
                ||outputBufferLength < 4 || outputBuffer  == NULL)
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER ;
                break;
            }
        }
    case 0x84020040:
        {
            //这里的区别是看inputBufferLength 是不是0XC,而上面是0X14
            if(inputBufferLength < 0xc || inputBuffer  == NULL /
                ||outputBufferLength < 0x4c || outputBuffer  == NULL)
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER ;
                break;
            }
            memcpy(pBuffer,inputBuffer,0xc);
            memset(outputBuffer,0,0x4c);
            //这里有个函数通过未导出的函数,取得对象
            //然后通过ObOpenObjectByPointer(object,0,0,0x1f0fff,0,0,&tem);
            //获得对象,然后
            ZwDuplicateObject(tem,sourcehandle,-1,&Targethandle,-1,0,0,2);
            ZwClose(tem);
            PFILE_OBJECT tem2;
            PDEVICE_OBJECT pDev;
            PDRIVER_OBJECT pDri;
            if(sourcehandle != NULL)
            {
                dword_ebp3c  =ObReferenceObjectByHandle(tem,0x80000000,0,0,&tem2,0);//这里取得的是FileOBject
               
                ZwClose(tem);
                if(!NT_SUCCESS(dword_ebp3c))
                {
                    pIrpStatus->Information = 0x4c;
                    break;
                }
                pDev = IoGetRelatedDeviceObject(tem2);
                if(pDev!=0 && pDev->DriverObject != 0)
                {
                    pDri = pDev->DriverObject;
                    if(pDri->DriverSection!=0)
                        DWORD * ebp38 = pDri->DriverSection;
                    if(pDri->DriverName->Length !=0 && pDri->DriverName->Buffer != NULL)
                        if((WORD)pDri->DriverName->Buffer[1] ==0X44 ) //这里比较第2个字是不是大写D?不知道有什么用
                        {
                                *((DWORD *)outputBuffer)= *(DWORD *)((DWORD)ebp38+0x18);//这里是DLLBASE?
                                * ( (DWORD *)((DWORD)outputBuffer+4) ) =  *(DWORD *)((DWORD)ebp38+0x20); //这里是Sizeofimage?
                                if(pDri->DriverName->Length < 0x40)
                                    DWORD ebp108 = pDri->DriverName->Length;
                                else
                                    ebp108 = 0x40;
                                memmove((void *)(outputBuffer+8),pDri->DriverName->Buffer,ebp108);
                                *(WORD *)(outputBuffer+0x46) =  0;
                        }

                }
             ObfDereferenceObject(tem);
           
            }
            pIrpStatus->Information = 0x4c;
            break;

        }
    case 0x84020034:
        {
            if(inputBufferLength < 0x4 || inputBuffer  == NULL /
                ||outputBufferLength < 0x4 || outputBuffer  == NULL)
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER ;
                break;
            }
            //这里有个函数通过未导出的函数,取得对象
            //然后通过ObOpenObjectByPointer(object,0,0,0x1f0fff,0,0,&tem);
            //获得对象,然后
            if() //获取对象失败
            {
                //检查名单,如果没有把对象加入名单中
                pIrpStatus->Status =STATUS_UNSUCCESSFUL;
            }
            //如果获取成功
            *(DWORD *)outputBuffer = 获取的对象;
                pIrpStatus->Information = 4;

        }
    case 0x8420010:
        {

            DWORD* pdeviceEx = DeviceObject->DeviceExtension;
            if(outputBufferLength < 0x2c || outputBuffer == NULL )
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER;
                break;
            }
            ((DWORD *)outputBuffer)[0] = pdeviceEx[3];
            ((DWORD *)outputBuffer)[1] = pdeviceEx[4];
            ((DWORD *)outputBuffer)[2] = (DWORD)((byte) pdeviceEx[5]);
            strncpy((void *)(outputBuffer + 9),(void *)((void *)pdeviceEx + 0x15),0x20);
            *((char *)(outputBuffer+0x28) )  = 0;
            KeClearEvent(pdeviceEx[2]);
            pIrpStatus->Information = outputBufferLength;
            break;
        }
    case 0x8402003c:
        {
            DWORD* pdeviceEx = DeviceObject->DeviceExtension;
            if(outputBufferLength < 0x104 || outputBuffer == NULL )
            {
                pIrpStatus->Status = STATUS_INVALID_PARAMETER;
                break;
            }
            ((DWORD *)outputBuffer)[0] = pdeviceEx[10];
            //长度达到400,不知道NP做什么
            strncpy((void *)(outputBuffer + 4),    (void *)((char *)pdeviceEx +0x44), 0x400);
            *(char *)(outputBuffer + 0x403) = 0;
            KeClearEvent(pdeviceEx[0X0F]);
            pIrpStatus->Information = outputBufferLength;
            break;
        }
    }
    ExAcquireFastMutex(&ControlMutex);
    //未知代码
    return STATUS_SUCCESS;
}
BOOLEAN UnKownHOOK(HANDLE handle,void * pMem,DWORD iunknow ,DWORD Length,DWORD* iOut) //iOut 是传入的返回指针
{
    DWORD dwTem1,dwTem2,dwTem3,dwTem4;
    DWORD pAddress=0;
    PMDL pmdl = NULL;
    PVOID BaseAddr=0;
    PVOID pObject=NULL;
    dwTem1 = dwTem2  = dwTem3 = 0;
    pAddress  = pMem;
    dwTem1  = (DWORD)pAddress +Length;
    if(pAddress>0x8000000 && handle != NULL)
    {
        if( NT_SUCCESS(ObReferenceObjectByHandle(handle,0x10,0,1,&pObject,0)) )
        {
           
            if(pObject != NULL)
            {
                dwTem3 = GetObjectValue(pObject); //取得指定位置的偏移值
                //这里取Object偏移中的值,这里不知道TYPE所以不能确定是取什么
                /*这里比较一个全局变量1000c784是不是为0,不为0才执行下面*/
                    for(dwTem2 = 0;dword_1000c784 !=0; dwTem2++)
                    {
                    StartTimer(0x1f018); //这里启动一个定时器,好像是延时作用吧
                    if(dwTem2 > 0x64)
                    {
                        dword_1000c784 -=1;
                    }
                    }
                    dword_1000c788 = dwTem3;//保存取得的对象值】
                    dword_1000c784 +=1;
                    KeAttachProcess(pObject); //看来获取的是EPROC对象了。
                    pmdl = MmCreateMdl(NULL,pMem,Length);
                    if(pmdl != NULL)
                    {
                        CheckAddrVilible(pmdl,1,0,pMem,Length);
                        if(pmdl->Process == (PEPROCESS)pObject)
                            if(pmdl->StartVa + pmdl->ByteOffset == pAddress)
                                if(Length = pmdl->ByteCount)
                                {
                                    BaseAddr = MmMapLockedPagesSpecifyCache(pmdl,0,1,0,0,0x20);
                                    if(pmdl->Process == (PEPROCESS)pObject)
                                    {
                                        pMem = BaseAddr;
                                        dwTem4 = BaseAddr + Length;
                                        *iOut = 1;
                                    }
                                }
                           
                    }
                    KeDetachProcess();

                    dword_1000c784 -=1;
                    dword_1000c788  = 0;
                    if (BaseAddr !=0)
                    {
                        //memcpy(); 这里应该是挂钩函数了
                    }
                    MmUnmapLockedPages(BaseAddr,pmdl);
                    MmUnlockPages(pmdl);
                    IoFreeMdl(pmdl);
                   
                }
            }
        ObfDereferenceObject(pObject);
        }
    }

        return 1;//这里自己加,上面的忽略了好多。
}


逆得不全,很粗糙没有详细的还原,也没有必要还原吧,知道大体的作用就好了,欢迎大家补全,这里处理例程应该还没有完,不过IDA已经分析不出来了。下面就是数据不是代码了。

原创粉丝点击