IopLoadDriver
NTSTATUS __stdcall IopLoadDriver(PVOID KeyHandle, UINT8 CheckForSafeBoot, BOOL IsFilter, INT64 *DriverEntryStatus){
ULONG_PTR v4;
unsigned int v5;
wchar_t *Buffer;
NTSTATUS v8;
unsigned __int16 *v9;
NTSTATUS DriverNameFromKeyNode;
unsigned int v11;
__int64 v12;
CHAR *Pool_1;
WCHAR v14;
int v15;
IMAGE_NT_HEADERS *v16;
_QWORD *v17;
IMAGE_NT_HEADERS *v18;
char *v19;
HANDLE v20;
KPROCESSOR_MODE v21;
NTSTATUS v22;
PVOID v23;
CHAR *v24;
_UNICODE_STRING *v25;
unsigned int MaximumLength;
__int64 v27;
UNICODE_STRING *v28;
unsigned int i;
__int64 v30;
_ETHREAD *Lock;
__int64 v32;
EVENT_DESCRIPTOR *v33;
int v35;
NTSTATUS v36;
ULONG_PTR v37;
PULONG ResultLength;
struct _UNICODE_STRING Destination;
UINT64 Length;
UNICODE_STRING KeyName;
UINT64 Version;
UNICODE_STRING DriverName;
PVOID BaseAddress;
unsigned int PnpFlags;
HANDLE Handle;
ULONG_PTR BugCheckParameter2;
UINT64 v49;
PVOID v50;
PVOID v51;
struct _UNICODE_STRING DestinationString;
PVOID Object;
PVOID v54;
PVOID P;
INT64 *v56;
int v57[2];
__int64 v58;
UNICODE_STRING *p_DriverName;
int v60;
int v61;
__int128 v62;
char KeyValueInformation[8];
__int16 v64;
char v65;
v4 = 0i64;
v56 = DriverEntryStatus;
*(_DWORD *)DriverEntryStatus = 0;
v5 = IsFilter;
P = 0i64;
LODWORD(Length) = 0;
*(_QWORD *)&Destination.Length = 0i64;
Buffer = 0i64;
*(_QWORD *)&KeyName.Length = 0i64;
KeyName.Buffer = 0i64;
v57[1] = 0;
v61 = 0;
BugCheckParameter2 = 0i64;
*(_QWORD *)&DriverName.Length = 0i64;
Object = 0i64;
BaseAddress = 0i64;
LODWORD(Version) = 0;
Handle = 0i64;
DriverName.Buffer = 0i64;
Destination.Buffer = 0i64;
PnpFlags = 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(NonPagedPoolNx, (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(PagedPool, 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((UINT8 *)Pool_1, (UINT8 *)Destination.Buffer, Destination.Length);
Buffer[(unsigned __int64)Destination.Length >> 1] = 0;
RtlAppendUnicodeToString(&Destination, (PWCHAR)L".SYS");
HeadlessKernelAddLogEntry(1ui64, &Destination);
PnpDiagnosticTraceObject(&KMPnPEvt_DriverLoad_Start, &KeyName);
if( InitSafeBootMode )
{
if( CheckForSafeBoot )
{
LODWORD(v49) = 0;
DestinationString = 0i64;
RtlInitUnicodeString(&DestinationString, L"Group", v14);
memset((INT64)KeyValueInformation, 0i64);
LODWORD(ResultLength) = 76;
v35 = NtQueryValueKey(
KeyHandle,
&DestinationString,
KeyValuePartialInformation,
KeyValueInformation,
(UINT64)ResultLength,
&v49);
if( v35 < 0
|| (DestinationString.Length = v64 - 2,
DestinationString.MaximumLength = v64 - 2,
DestinationString.Buffer = (wchar_t *)&v65,
!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;
v57[0] = 48;
v58 = 0i64;
p_DriverName = &DriverName;
v60 = IopCaseInsensitive != 0 ? 592 : 528;
v62 = 0i64;
ExAcquireResourceExclusiveLite(&IopDriverLoadResource, 1u);
v15 = MmLoadSystemImage(&Destination, 0i64, 0i64, 0i64, (PVOID *)&BugCheckParameter2, &BaseAddress);
DriverNameFromKeyNode = v15;
if( v15 >= 0 )
{
v16 = RtlImageNtHeader(BaseAddress);
LODWORD(Version) = v16->OptionalHeader.MinorImageVersion | (v16->OptionalHeader.MajorImageVersion << 16);
DriverNameFromKeyNode = PnpPrepareDriverLoading(&KeyName, KeyHandle, BaseAddress, v5, &PnpFlags);
if( DriverNameFromKeyNode < 0
|| (DriverNameFromKeyNode = ObCreateObject(
*((_BYTE *)KeGetCurrentThread() + 562),
IoDriverObjectType,
(__int64)v57,
0,
0,
416,
0,
0,
&Object),
DriverNameFromKeyNode < 0) )
{
MmUnloadSystemImage((VOID *)BugCheckParameter2);
ExReleaseResourceLite(&IopDriverLoadResource);
}
else
{
v17 = Object;
memset((INT64)Object, 0i64);
v17[6] = v17 + 42;
v17[42] = v17;
HIDWORD(v49) = 28;
memset64(v17 + 14, (unsigned __int64)IopInvalidDeviceRequest, 0x1Cui64);
*(_DWORD *)v17 = 22020100;
v18 = RtlImageNtHeader(BaseAddress);
LODWORD(Version) = v18->OptionalHeader.MinorImageVersion | (v18->OptionalHeader.MajorImageVersion << 16);
v19 = (char *)BaseAddress + v18->OptionalHeader.AddressOfEntryPoint;
if( (v18->OptionalHeader.DllCharacteristics & 0x2000) == 0 )
*((_DWORD *)v17 + 4) |= 2u;
v17[11] = v19;
v17[5] = BugCheckParameter2;
v17[3] = BaseAddress;
*((_DWORD *)v17 + 8) = v18->OptionalHeader.SizeOfImage;
DriverNameFromKeyNode = ObInsertObject(v17, 0i64, 1ui64, 0i64, 0i64, &Handle);
ExReleaseResourceLite(&IopDriverLoadResource);
if( DriverNameFromKeyNode >= 0 )
{
v20 = Handle;
v21 = *((_BYTE *)KeGetCurrentThread() + 562);
v51 = 0i64;
v22 = ObReferenceObjectByHandle(Handle, 0, IoDriverObjectType, v21, &v51, 0i64);
if( v22 )
KeBugCheckEx(0x11Fu, (ULONG_PTR)v20, v22, (ULONG_PTR)v51, 0i64);
ZwClose(v20);
v23 = v51;
*((_QWORD *)v51 + 9) = &CmRegistryMachineHardwareDescriptionSystemName;
v24 = IopVerifierExAllocatePool_1(NonPagedPoolNx, DriverName.MaximumLength);
*((_QWORD *)v23 + 8) = v24;
if( v24 )
{
*((_WORD *)v23 + 29) = DriverName.MaximumLength;
*((_WORD *)v23 + 28) = DriverName.Length;
memmove(*((UINT8 **)v23 + 8), (UINT8 *)DriverName.Buffer, DriverName.MaximumLength);
}
v25 = (_UNICODE_STRING *)IopVerifierExAllocatePool_1(NonPagedPoolNx, 0x1000ui64);
if( !v25 )
{
ObMakeTemporaryObject(v23);
HalPutDmaAdapter((PADAPTER_OBJECT)v23);
Buffer = KeyName.Buffer;
DriverNameFromKeyNode = -1073741670;
goto LABEL_54;
}
DriverNameFromKeyNode = NtQueryObject(
KeyHandle,
ObjectNameInformation,
v25,
0x1000ui64,
(UINT64 *)((char *)&v49 + 4));
if( DriverNameFromKeyNode < 0 )
{
ObMakeTemporaryObject(v23);
HalPutDmaAdapter((PADAPTER_OBJECT)v23);
ExFreePoolWithTag(v25, 0);
Buffer = KeyName.Buffer;
}
else
{
Buffer = KeyName.Buffer;
if( KeyName.Buffer )
{
MaximumLength = KeyName.MaximumLength;
*(_QWORD *)(*((_QWORD *)v23 + 6) + 32i64) = IopVerifierExAllocatePool_1(
NonPagedPoolNx,
KeyName.MaximumLength);
v27 = *((_QWORD *)v23 + 6);
if( *(_QWORD *)(v27 + 32) )
{
*(_WORD *)(v27 + 26) = MaximumLength;
*(_WORD *)(*((_QWORD *)v23 + 6) + 24i64) = KeyName.Length;
memmove(*(UINT8 **)(*((_QWORD *)v23 + 6) + 32i64), (UINT8 *)Buffer, MaximumLength);
}
}
if( (PnpFlags & 1) != 0 )
*((_DWORD *)v23 + 4) |= 0x100u;
PnpDiagnosticTraceObject(&KMPnPEvt_DriverInit_Start, v25);
VfDifCaptureDriverEntry((DRIVER_OBJECT *)v23);
DriverNameFromKeyNode = PnpCallDriverEntry((INT64)v23, (INT64)v25);
if( DriverNameFromKeyNode >= 0 )
{
VfDifCaptureIoCallbacks((DRIVER_OBJECT *)v23);
KseShimDriverIoCallbacks((DRIVER_OBJECT *)v23, v28);
}
PnpDiagnosticTraceObjectWithStatus(&KMPnPEvt_DriverInit_Stop, v25, (unsigned int)DriverNameFromKeyNode);
*(_DWORD *)v56 = DriverNameFromKeyNode;
if( DriverNameFromKeyNode < 0 )
DriverNameFromKeyNode = -1073740955;
for( i = 0; i <= 0x1B; ++i )
{
if( !*((_QWORD *)v23 + i + 14) )
*((_QWORD *)v23 + i + 14) = IopInvalidDeviceRequest;
}
ExFreePoolWithTag(v25, 0);
if( DriverNameFromKeyNode < 0 )
{
ObMakeTemporaryObject(v23);
HalPutDmaAdapter((PADAPTER_OBJECT)v23);
}
else
{
IopBootLog(&Destination, 1u);
v30 = *((_QWORD *)v23 + 5);
Lock = MmAcquireLoadLock();
MiFreeDriverInitialization(v30);
MmReleaseLoadLock(Lock);
IopReadyDeviceObjects((DRIVER_OBJECT *)v23);
EtwTiLogDriverObjectLoad((unsigned __int16 *)v23 + 28, v32, v33);
}
}
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 = ((_BYTE)v5 != 0) - 1073740949;
IopLogBlockedDriverEvent(&Destination, v36, DriverNameFromKeyNode);
}
if( DriverNameFromKeyNode == -1073741554 )
{
LABEL_56:
DriverNameFromKeyNode = ObOpenObjectByName(
(__int64)v57,
(__int64)IoDriverObjectType,
0,
0i64,
0,
0i64,
&Handle);
if( DriverNameFromKeyNode < 0 )
{
ExReleaseResourceLite(&IopDriverLoadResource);
IopBootLog(&Destination, 0);
if( DriverNameFromKeyNode == -1073741772 )
DriverNameFromKeyNode = -1073740914;
goto LABEL_36;
}
v50 = 0i64;
DriverNameFromKeyNode = ObReferenceObjectByHandle(Handle, 0, IoDriverObjectType, 0, &v50, 0i64);
ZwClose(Handle);
if( DriverNameFromKeyNode >= 0 )
{
DriverNameFromKeyNode = IopResurrectDriver((DRIVER_OBJECT *)v50);
HalPutDmaAdapter((PADAPTER_OBJECT)v50);
}
}
ExReleaseResourceLite(&IopDriverLoadResource);
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 )
{
v54 = 0i64;
if( DriverNameFromKeyNode != -1073741554 )
{
PnpDriverLoadingFailed(KeyHandle, 0i64);
if( DriverNameFromKeyNode != -1073740955
&& IopGetRegistryValue(KeyHandle, (PWCHAR)L"ErrorControl", 0i64, (KEY_VALUE_FULL_INFORMATION **)&v54) >= 0 )
{
if( *((_DWORD *)v54 + 3)
&& (_BYTE)CmFirstTime == 1
&& (unsigned int)(*(_DWORD *)((char *)v54 + *((unsigned int *)v54 + 2)) - 2) <= 1 )
{
if( ((unsigned __int64)&Destination & -(__int64)(Destination.Buffer != 0i64)) != 0 )
v37 = *(_QWORD *)(((unsigned __int64)&Destination & -(__int64)(Destination.Buffer != 0i64)) + 8);
else
v37 = 0i64;
if( ((unsigned __int64)&DriverName & -(__int64)(DriverName.Buffer != 0i64)) != 0 )
v4 = *(_QWORD *)(((unsigned __int64)&DriverName & -(__int64)(DriverName.Buffer != 0i64)) + 8);
KeBugCheckEx(0x5Au, 1ui64, v4, v37, DriverNameFromKeyNode);
}
ExFreePoolWithTag(v54, 0);
}
}
}
if( P )
ExFreePoolWithTag(P, 0);
if( Buffer )
{
LODWORD(ResultLength) = Version;
PnpDiagnosticTraceDriverFullInfo(
&KMPnPEvt_DriverLoad_Stop,
&KeyName,
(unsigned int)DriverNameFromKeyNode,
&DriverName,
(UINT64)ResultLength);
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