用instDrv加載驅(qū)動(dòng),用CreateService()函數(shù)等等過程如下,
1,先是它向Service進(jìn)程注冊(cè)服務(wù)。
2,然后Service進(jìn)程調(diào)用ZwLoadDriver()加載驅(qū)動(dòng)。進(jìn)入NtLoadDriver()系統(tǒng)調(diào)用,它先會(huì)檢測(cè)SerVice進(jìn)程(當(dāng)前進(jìn)程)是不是有加載驅(qū)動(dòng)的權(quán)限,然后檢測(cè)當(dāng)前進(jìn)程是不是System進(jìn)程,是的話直接調(diào)用IopLoadUnloadDriver()加載驅(qū)動(dòng),-》IopLoadDriver()最后會(huì)調(diào)用驅(qū)動(dòng)的DriverEntry(),所以這種方法加載驅(qū)動(dòng)的DriverEntry()函數(shù)是在System進(jìn)程的地址空間執(zhí)行的。
如果當(dāng)前進(jìn)程不是System進(jìn)程的話,則調(diào)用如下的函數(shù),向system進(jìn)程的系統(tǒng)線程的工作隊(duì)列中插入這項(xiàng),函數(shù)為IopLoadUnloadDriver(),也就是說系統(tǒng)線程會(huì)替它調(diào)用IopLoadUnloadDriver()函數(shù)
ExInitializeWorkItem( &loadPacket.WorkQueueItem,
????????????????????????????? IopLoadUnloadDriver,
????????????????????????????? &loadPacket ); ExQueueWorkItem( &loadPacket.WorkQueueItem, DelayedWorkQueue );
IopLoadUnloadDriver會(huì)調(diào)用IopLoadDriver()做真正的加載驅(qū)動(dòng)的工作
1,先根據(jù)鍵句柄調(diào)用NtQueryKey()函數(shù)得到驅(qū)動(dòng)的全路徑名。
2,循環(huán)檢查PsLoadedModuleList內(nèi)核模塊鏈表看是不是這個(gè)驅(qū)動(dòng)已經(jīng)加載
3.調(diào)用 status = MmLoadSystemImage( &baseName,
??????????????????????????????? NULL,
??????????????????????????????? NULL,
??????????????????????????????? 0,
??????????????????????????????? §ionPointer,
??????????????????????????????? (PVOID *) &imageBaseAddress );
?? 這函數(shù)里面會(huì)調(diào)用 InitializeObjectAttributes (&ObjectAttributes,
??????????????????????????????????? ImageFileName,
??????????????????????????????????? (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE),
??????????????????????????????????? NULL,
??????????????????????????????????? NULL);
??????? Status = ZwOpenFile (&FileHandle,
???????????????????????????? FILE_EXECUTE,
???????????????????????????? &ObjectAttributes,
???????????????????????????? &IoStatus,
???????????????????????????? FILE_SHARE_READ | FILE_SHARE_DELETE,
???????????????????????????? 0);?? //返回句柄為0x80000140
函數(shù)根據(jù)驅(qū)動(dòng)文件名打開文件,向system進(jìn)程的句柄表中插入一項(xiàng),返回句柄表的下標(biāo),就是文件句柄(這里是內(nèi)核句柄))
Status = MmCheckSystemImage (FileHandle, FALSE);//這個(gè)函數(shù)是檢查這個(gè)PE文件各個(gè)節(jié)看是不是好的。
最后調(diào)用
InitializeObjectAttributes (&ObjectAttributes,
??????????????????????????????????? NULL,
??????????????????????????????????? (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE),
??????????????????????????????????? NULL,
??????????????????????????????????? NULL);
??????? Status = ZwCreateSection (&SectionHandle,
????????????????????????????????? SectionAccess,
????????????????????????????????? &ObjectAttributes,
????????????????????????????????? (PLARGE_INTEGER) NULL,
????????????????????????????????? PAGE_EXECUTE,
????????????????????????????????? SEC_IMAGE,
????????????????????????????????? FileHandle);
建立節(jié)對(duì)象向system進(jìn)程句柄表中插入一項(xiàng),返回句柄為0x80000170
Status = ObReferenceObjectByHandle (SectionHandle,
??????????????????????????????????????????? SECTION_MAP_EXECUTE,
??????????????????????????????????????????? MmSectionObjectType,
??????????????????????????????????????????? KernelMode,
??????????????????????????????????????????? (PVOID *) &SectionPointer,
??????????????????????????????????????????? (POBJECT_HANDLE_INFORMATION) NULL);//根據(jù)句柄從system進(jìn)程句柄中找到節(jié)對(duì)象的地址。
??????? ZwClose (SectionHandle);//把此句柄關(guān)了,會(huì)從system 進(jìn)程句柄中刪除一項(xiàng)。下次訪問節(jié)對(duì)象時(shí)就通過地址來訪問。不用句柄。
調(diào)用 Status = MiLoadImageSection (&SectionPointer,
???????????????????????????????? ImageBaseAddress,
???????????????????????????????? ImageFileName,
???????????????????????????????? LoadFlags & MM_LOAD_IMAGE_IN_SESSION,
???????????????????????????????? FoundDataTableEntry);
進(jìn)行真正的文件映射它里面會(huì)調(diào)用 MmMapViewOfSection (SectionPointer,TargetProcess(system),
???????????????????????????????? &Base,
???????????????????????????????? 0,
???????????????????????????????? 0,
???????????????????????????????? &SectionOffset,
???????????????????????????????? &ViewSize,
???????????????????????????????? ViewUnmap,
???????????????????????????????? 0,
???????????????????????????????? PAGE_EXECUTE);
進(jìn)行文件映射,返回基址為0xba377000
最后分配 PKLDR_DATA_TABLE_ENTRY DataTableEntry;
初始化它,最后調(diào)用 MiProcessLoaderEntry (DataTableEntry, TRUE);
把它個(gè)內(nèi)核模塊結(jié)構(gòu)加入PsLoadModuleList鏈表中等等,還會(huì)處理這個(gè)驅(qū)動(dòng)的Reference等等
4,調(diào)用??? status = ObCreateObject( KeGetPreviousMode(),
???????????????????????????? IoDriverObjectType,
???????????????????????????? &objectAttributes,
???????????????????????????? KernelMode,
???????????????????????????? (PVOID) NULL,
???????????????????????????? (ULONG) (sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )),
???????????????????????????? 0,
???????????????????????????? 0,
???????????????????????????? (PVOID *) &driverObject );建立驅(qū)動(dòng)對(duì)象
初始化驅(qū)動(dòng)對(duì)象后,調(diào)用 status = ObInsertObject( driverObject,
???????????????????????????? (PACCESS_STATE) NULL,
???????????????????????????? FILE_READ_DATA,
???????????????????????????? 0,
???????????????????????????? (PVOID *) NULL,
???????????????????????????? &driverHandle );把驅(qū)動(dòng)對(duì)象插入到system進(jìn)程的句柄表的一項(xiàng),返回句柄,注意這個(gè)函數(shù)還會(huì)把這對(duì)象插入對(duì)象目錄中。
5,最后會(huì)調(diào)用 status = driverObject->DriverInit( driverObject, ®istryPath->Name );也就是DriverEntry()函數(shù)。