IopLoadDriver
NTSTATUS __stdcall IopLoadDriver(PVOID KeyHandle, UINT8 CheckForSafeBoot, BOOL IsFilter, INT64 *DriverEntryStatus){
void *v4;
_BOOL4 v5;
wchar_t *Buffer;
NTSTATUS v8;
unsigned __int16 *v9;
int DriverNameFromKeyNode;
unsigned int v11;
__int64 v12;
VOID **Pool_1;
INT64 v14;
int v15;
__int64 v16;
_QWORD *v17;
__int64 v18;
__int64 v19;
char *v20;
PVOID v21;
char PreviousMode;
NTSTATUS v23;
PVOID v24;
VOID **v25;
VOID **v26;
size_t MaximumLength;
__int64 v28;
UINT64 v29;
_UNICODE_STRING *v30;
unsigned int i;
_KLDR_DATA_TABLE_ENTRY *v32;
INT8 v33;
INT64 v34;
_ETHREAD *Lock;
__int64 v36;
INT64 v37;
NTSTATUS v39;
void *v40;
UINT64 *ResultLength;
UINT64 *ResultLengtha;
PVOID *ImageBaseAddress;
UINT64 PagedPoolCharge;
UINT64 NonPagedPoolCharge;
_UNICODE_STRING Destination;
UINT64 Length;
_UNICODE_STRING KeyName;
char v50[4];
_UNICODE_STRING DriverName;
PVOID ImageBase;
__int64 v53;
PVOID Handle;
PVOID ImageHandle;
UINT64 ReturnLength;
_DRIVER_OBJECT *DriverObject;
PVOID BugCheckParameter3;
_UNICODE_STRING DestinationString;
PVOID Object;
_KEY_VALUE_FULL_INFORMATION *Information;
PVOID P;
INT64 *v63;
_OBJECT_ATTRIBUTES ObjectAttributes;
__int16 KeyValueInformation[40];
v4 = 0i64;
v63 = DriverEntryStatus;
*(_DWORD *)DriverEntryStatus = 0;
v5 = IsFilter;
P = 0i64;
LODWORD(Length) = 0;
*(_QWORD *)&Destination.Length = 0i64;
Buffer = 0i64;
*(_QWORD *)&KeyName.Length = 0i64;
KeyName.Buffer = 0i64;
*(&ObjectAttributes.Length + 1) = 0;
*(&ObjectAttributes.Attributes + 1) = 0;
ImageHandle = 0i64;
*(_QWORD *)&DriverName.Length = 0i64;
Object = 0i64;
ImageBase = 0i64;
*(_DWORD *)v50 = 0;
Handle = 0i64;
DriverName.Buffer = 0i64;
Destination.Buffer = 0i64;
LODWORD(v53) = 0;
v8 = NtQueryKey(KeyHandle, KeyBasicInformation, 0i64, 0i64, &Length);
if( v8 == -1073741789 || v8 == -2147483643 )
{
if( (int)Length + 8 < (unsigned int)Length )
{
DriverNameFromKeyNode = -1073741675;
goto LABEL_54;
}
P = IopVerifierExAllocatePool_1(0x200ui64, (unsigned int)(Length + 8));
v9 = (unsigned __int16 *)P;
if( !P )
{
DriverNameFromKeyNode = -1073741670;
goto LABEL_54;
}
DriverNameFromKeyNode = NtQueryKey(KeyHandle, KeyBasicInformation, P, (unsigned int)Length, &Length);
v11 = 2;
if( DriverNameFromKeyNode < 0 )
{
LABEL_53:
if( DriverNameFromKeyNode == -1073741554 )
goto LABEL_37;
goto LABEL_54;
}
v12 = v9[6];
Destination.Length = v12;
Destination.MaximumLength = v12 + 8;
Destination.Buffer = v9 + 8;
Pool_1 = IopVerifierExAllocatePool_1(1ui64, v12 + 2);
KeyName.Buffer = (wchar_t *)Pool_1;
Buffer = (wchar_t *)Pool_1;
if( Pool_1 )
{
KeyName.Length = Destination.Length;
KeyName.MaximumLength = Destination.Length + 2;
memmove(Pool_1, Destination.Buffer, Destination.Length);
Buffer[(unsigned __int64)Destination.Length >> 1] = 0;
RtlAppendUnicodeToString(&Destination, (WCHAR *)L".SYS");
HeadlessKernelAddLogEntry(1ui64, &Destination);
PnpDiagnosticTraceObject(&KMPnPEvt_DriverLoad_Start, &KeyName.Length);
if( InitSafeBootMode )
{
if( CheckForSafeBoot )
{
LODWORD(ReturnLength) = 0;
DestinationString = 0i64;
RtlInitUnicodeString(&DestinationString, L"Group");
memset(KeyValueInformation, 0i64, 0x4Cu);
LODWORD(ResultLength) = 76;
if( NtQueryValueKey(
KeyHandle,
&DestinationString,
KeyValuePartialInformation,
KeyValueInformation,
(UINT64)ResultLength,
&ReturnLength) < 0
|| (DestinationString.Length = KeyValueInformation[4] - 2,
DestinationString.MaximumLength = KeyValueInformation[4] - 2,
DestinationString.Buffer = (wchar_t *)&KeyValueInformation[6],
!IopSafebootDriverLoad(&DestinationString)) )
{
if( !IopSafebootDriverLoad(&Destination) )
{
IopBootLog(&Destination, 0);
DbgPrint("SAFEBOOT: skipping device = %wZ(%wZ)\n", &Destination, &DestinationString);
HeadlessKernelAddLogEntry(2ui64, 0i64);
ObCloseHandle(KeyHandle, 0);
return -1073740961;
}
}
}
}
DriverNameFromKeyNode = IopBuildFullDriverPath(&KeyName, KeyHandle, &Destination);
if( DriverNameFromKeyNode >= 0 )
{
DriverNameFromKeyNode = IopGetDriverNameFromKeyNode(KeyHandle, &DriverName);
if( DriverNameFromKeyNode < 0 )
goto LABEL_53;
ObjectAttributes.Length = 48;
ObjectAttributes.RootDirectory = 0i64;
ObjectAttributes.ObjectName = &DriverName;
ObjectAttributes.Attributes = IopCaseInsensitive != 0 ? 592 : 528;
*(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
ExAcquireResourceExclusiveLite((UINT64)&stru_140C452E0 + 1152, 1, v14);
v15 = MmLoadSystemImage(&Destination, 0i64, 0i64, 0i64, &ImageHandle, &ImageBase);
DriverNameFromKeyNode = v15;
if( v15 >= 0 )
{
LODWORD(v16) = RtlImageNtHeader((UINT64)ImageBase);
*(_DWORD *)v50 = *(unsigned __int16 *)(v16 + 70) | (*(unsigned __int16 *)(v16 + 68) << 16);
DriverNameFromKeyNode = PnpPrepareDriverLoading(&KeyName, KeyHandle, ImageBase, v5, (__int64)&v53);
if( DriverNameFromKeyNode < 0
|| (LODWORD(NonPagedPoolCharge) = 0,
LODWORD(PagedPoolCharge) = 0,
LODWORD(ImageBaseAddress) = 416,
DriverNameFromKeyNode = ObCreateObject(
KeGetCurrentThread()->PreviousMode,
IoDriverObjectType,
&ObjectAttributes,
0,
0i64,
(UINT64)ImageBaseAddress,
PagedPoolCharge,
NonPagedPoolCharge,
&Object),
DriverNameFromKeyNode < 0) )
{
MmUnloadSystemImage(ImageHandle);
ExReleaseResourceLite((PERESOURCE)((char *)&stru_140C452E0 + 1152));
}
else
{
v17 = Object;
memset(Object, 0i64, 0x1A0u);
v17[6] = v17 + 42;
v17[42] = v17;
HIDWORD(ReturnLength) = 28;
memset64(v17 + 14, (unsigned __int64)IopInvalidDeviceRequest, 0x1Cui64);
*(_DWORD *)v17 = 22020100;
LODWORD(v18) = RtlImageNtHeader((UINT64)ImageBase);
v19 = v18;
*(_DWORD *)v50 = *(unsigned __int16 *)(v18 + 70) | (*(unsigned __int16 *)(v18 + 68) << 16);
v20 = (char *)ImageBase + *(unsigned int *)(v18 + 40);
if( (*(_WORD *)(v19 + 94) & 0x2000) == 0 )
*((_DWORD *)v17 + 4) |= 2u;
v17[11] = v20;
v17[5] = ImageHandle;
v17[3] = ImageBase;
*((_DWORD *)v17 + 8) = *(_DWORD *)(v19 + 80);
DriverNameFromKeyNode = ObInsertObject(v17, 0i64, 1, 0i64, 0i64, &Handle);
ExReleaseResourceLite((PERESOURCE)((char *)&stru_140C452E0 + 1152));
if( DriverNameFromKeyNode >= 0 )
{
v21 = Handle;
PreviousMode = KeGetCurrentThread()->PreviousMode;
BugCheckParameter3 = 0i64;
v23 = ObReferenceObjectByHandle(Handle, 0i64, IoDriverObjectType, PreviousMode, &BugCheckParameter3, 0i64);
if( v23 )
KeBugCheckEx(0x11Fu, v21, (PVOID)v23, BugCheckParameter3, 0i64);
ZwClose((_HANDLE)v21);
v24 = BugCheckParameter3;
*((_QWORD *)BugCheckParameter3 + 9) = &CmRegistryMachineHardwareDescriptionSystemName;
v25 = IopVerifierExAllocatePool_1(0x200ui64, DriverName.MaximumLength);
*((_QWORD *)v24 + 8) = v25;
if( v25 )
{
*((_WORD *)v24 + 29) = DriverName.MaximumLength;
*((_WORD *)v24 + 28) = DriverName.Length;
memmove(*((VOID **)v24 + 8), DriverName.Buffer, DriverName.MaximumLength);
}
v26 = IopVerifierExAllocatePool_1(0x200ui64, 0x1000ui64);
if( !v26 )
{
ObMakeTemporaryObject(v24);
HalPutDmaAdapter((PADAPTER_OBJECT)v24);
Buffer = KeyName.Buffer;
DriverNameFromKeyNode = -1073741670;
goto LABEL_54;
}
DriverNameFromKeyNode = NtQueryObject(
KeyHandle,
ObjectNameInformation,
v26,
0x1000ui64,
(UINT64 *)((char *)&ReturnLength + 4));
if( DriverNameFromKeyNode < 0 )
{
ObMakeTemporaryObject(v24);
HalPutDmaAdapter((PADAPTER_OBJECT)v24);
ExFreePoolWithTag(v26, 0);
Buffer = KeyName.Buffer;
}
else
{
Buffer = KeyName.Buffer;
if( KeyName.Buffer )
{
MaximumLength = KeyName.MaximumLength;
*(_QWORD *)(*((_QWORD *)v24 + 6) + 32i64) = IopVerifierExAllocatePool_1(
0x200ui64,
KeyName.MaximumLength);
v28 = *((_QWORD *)v24 + 6);
if( *(_QWORD *)(v28 + 32) )
{
*(_WORD *)(v28 + 26) = MaximumLength;
*(_WORD *)(*((_QWORD *)v24 + 6) + 24i64) = KeyName.Length;
memmove(*(VOID **)(*((_QWORD *)v24 + 6) + 32i64), Buffer, MaximumLength);
}
}
if( (v53 & 1) != 0 )
*((_DWORD *)v24 + 4) |= 0x100u;
PnpDiagnosticTraceObject(&KMPnPEvt_DriverInit_Start, (unsigned __int16 *)v26);
VfDifCaptureDriverEntry((_DRIVER_OBJECT *)v24);
DriverNameFromKeyNode = PnpCallDriverEntry((__int64)v24, (__int64)v26);
if( DriverNameFromKeyNode >= 0 )
{
VfDifCaptureIoCallbacks((INT64 *)v24, v29);
KseShimDriverIoCallbacks((_DRIVER_OBJECT *)v24, v30);
}
PnpDiagnosticTraceObjectWithStatus(
&KMPnPEvt_DriverInit_Stop,
(unsigned __int16 *)v26,
DriverNameFromKeyNode);
*(_DWORD *)v63 = DriverNameFromKeyNode;
if( DriverNameFromKeyNode < 0 )
DriverNameFromKeyNode = -1073740955;
for( i = 0; i <= 0x1B; ++i )
{
if( !*((_QWORD *)v24 + i + 14) )
*((_QWORD *)v24 + i + 14) = IopInvalidDeviceRequest;
}
ExFreePoolWithTag(v26, 0);
if( DriverNameFromKeyNode < 0 )
{
ObMakeTemporaryObject(v24);
HalPutDmaAdapter((PADAPTER_OBJECT)v24);
}
else
{
IopBootLog(&Destination, 1u);
v32 = (_KLDR_DATA_TABLE_ENTRY *)*((_QWORD *)v24 + 5);
Lock = MmAcquireLoadLock(v34, v33);
MiFreeDriverInitialization(v32);
MmReleaseLoadLock(Lock);
IopReadyDeviceObjects((_DRIVER_OBJECT *)v24);
EtwTiLogDriverObjectLoad((unsigned __int16 *)v24 + 28);
}
}
v11 = 2;
goto LABEL_36;
}
}
IopBootLog(&Destination, 0);
Buffer = KeyName.Buffer;
LABEL_36:
if( DriverNameFromKeyNode >= 0 )
goto LABEL_37;
goto LABEL_53;
}
if( v15 == -1073741554 )
goto LABEL_56;
if( IopCheckIfNotNativeDriver(v15, &Destination) )
{
DriverNameFromKeyNode = v5 - 1073740949;
IopLogBlockedDriverEvent(&Destination, v39, DriverNameFromKeyNode);
}
if( DriverNameFromKeyNode == -1073741554 )
{
LABEL_56:
LODWORD(ResultLengtha) = 0;
DriverNameFromKeyNode = ObOpenObjectByName(
&ObjectAttributes,
IoDriverObjectType,
0,
0i64,
(UINT64)ResultLengtha,
0i64,
&Handle);
if( DriverNameFromKeyNode < 0 )
{
ExReleaseResourceLite((PERESOURCE)((char *)&stru_140C452E0 + 1152));
IopBootLog(&Destination, 0);
if( DriverNameFromKeyNode == -1073741772 )
DriverNameFromKeyNode = -1073740914;
goto LABEL_36;
}
DriverObject = 0i64;
DriverNameFromKeyNode = ObReferenceObjectByHandle(
Handle,
0i64,
IoDriverObjectType,
0,
(VOID **)&DriverObject,
0i64);
ZwClose((_HANDLE)Handle);
if( DriverNameFromKeyNode >= 0 )
{
DriverNameFromKeyNode = IopResurrectDriver(DriverObject);
HalPutDmaAdapter((PADAPTER_OBJECT)DriverObject);
}
}
ExReleaseResourceLite((PERESOURCE)((char *)&stru_140C452E0 + 1152));
IopBootLog(&Destination, 0);
goto LABEL_36;
}
}
else
{
DriverNameFromKeyNode = -1073741670;
}
Destination.Buffer = 0i64;
goto LABEL_36;
}
DriverNameFromKeyNode = -1073741472;
LABEL_54:
v11 = 3;
LABEL_37:
HeadlessKernelAddLogEntry(v11, 0i64);
if( (int)(DriverNameFromKeyNode + 0x80000000) >= 0 && DriverNameFromKeyNode != -1073741218 )
{
Information = 0i64;
if( DriverNameFromKeyNode != -1073741554 )
{
PnpDriverLoadingFailed(KeyHandle, 0i64, v36, v37);
if( DriverNameFromKeyNode != -1073740955
&& IopGetRegistryValue(KeyHandle, (PWCHAR)L"ErrorControl", 0i64, &Information) >= 0 )
{
if( Information->DataLength
&& (_BYTE)CmFirstTime == 1
&& *(ULONG *)((char *)&Information->TitleIndex + Information->DataOffset) - 2 <= 1 )
{
if( ((unsigned __int64)&Destination & -(__int64)(Destination.Buffer != 0i64)) != 0 )
v40 = *(void **)(((unsigned __int64)&Destination & -(__int64)(Destination.Buffer != 0i64)) + 8);
else
v40 = 0i64;
if( ((unsigned __int64)&DriverName & -(__int64)(DriverName.Buffer != 0i64)) != 0 )
v4 = *(void **)(((unsigned __int64)&DriverName & -(__int64)(DriverName.Buffer != 0i64)) + 8);
KeBugCheckEx(0x5Au, (PVOID)1, v4, v40, (PVOID)DriverNameFromKeyNode);
}
ExFreePoolWithTag(Information, 0);
}
}
}
if( P )
ExFreePoolWithTag(P, 0);
if( Buffer )
{
PnpDiagnosticTraceDriverFullInfo(
&KMPnPEvt_DriverLoad_Stop,
&KeyName.Length,
DriverNameFromKeyNode,
(__int64)&DriverName,
v50[0]);
ExFreePoolWithTag(Buffer, 0);
}
if( DriverName.Buffer )
ExFreePoolWithTag(DriverName.Buffer, 0);
if( Destination.Buffer )
ExFreePoolWithTag(Destination.Buffer, 0);
ObCloseHandle(KeyHandle, 0);
return DriverNameFromKeyNode;
}Referenced by:
IopInitializeSystemDrivers
IopLoadUnloadDriver
PipCallDriverAddDeviceQueryRoutine