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已经分析不出来了。下面就是数据不是代码了。
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已经分析不出来了。下面就是数据不是代码了。