通过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;
}
}