IopLoadDriverImage
NTSTATUS __stdcall IopLoadDriverImage(_OWORD *a1){
_ETHREAD *CurrentThread;
INT8 PreviousMode;
__int64 v4;
int v5;
unsigned __int64 v6;
unsigned __int64 v7;
VOID *PoolWithQuota_2;
VOID *Src[2];
_BYTE WorkItem[80];
*(_OWORD *)Src = 0i64;
memset(WorkItem, 0i64, sizeof(WorkItem));
if( !a1 )
return -1073741811;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
PreviousMode = CurrentThread->Tcb.PreviousMode;
if( PreviousMode )
{
if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeLoadDriverPrivilege, PreviousMode) )
return -1073741727;
if( PsIsCurrentThreadInServerSilo() )
return 0;
v4 = 0x7FFFFFFF0000i64;
if( (unsigned __int64)a1 < 0x7FFFFFFF0000i64 )
v4 = (__int64)a1;
v5 = *(_DWORD *)v4;
LODWORD(Src[0]) = v5;
v6 = *(_QWORD *)(v4 + 8);
Src[1] = (VOID *)v6;
if( !(_WORD)v5 )
return -1073741811;
if( (v6 & 1) != 0 )
ExRaiseDatatypeMisalignment();
v7 = v6 + (unsigned __int16)v5;
if( v7 > 0x7FFFFFFF0000i64 || v7 < v6 )
MEMORY[0x7FFFFFFF0000] = 0;
PoolWithQuota_2 = IopVerifierExAllocatePoolWithQuota_2(v6, LOWORD(Src[0]));
memmove(PoolWithQuota_2, Src[1], LOWORD(Src[0]));
Src[1] = PoolWithQuota_2;
}
else
{
*(_OWORD *)Src = *a1;
PoolWithQuota_2 = 0i64;
}
WorkItem[34] = 6;
*(_DWORD *)&WorkItem[36] = 0;
*(_QWORD *)&WorkItem[48] = &WorkItem[40];
*(_QWORD *)&WorkItem[40] = &WorkItem[40];
*(_QWORD *)&WorkItem[56] = 0i64;
*(_QWORD *)&WorkItem[64] = Src;
if( CurrentThread->Tcb.ApcState.Process == PsInitialSystemProcess )
{
IopLoadUnloadDriver(WorkItem);
}
else
{
*(_QWORD *)&WorkItem[16] = IopLoadUnloadDriver;
*(_QWORD *)&WorkItem[24] = WorkItem;
*(_QWORD *)WorkItem = 0i64;
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
KeWaitForSingleObject((UINT64)&WorkItem[32], 6, 0, 0, 0i64);
}
if( PoolWithQuota_2 )
ExFreePoolWithTag(PoolWithQuota_2, 0);
return *(_DWORD *)&WorkItem[72];
}Referenced by:
NtLoadDriver