IopLoadDriverImage
INT64 __fastcall IopLoadDriverImage(_OWORD *a1){
_ETHREAD *CurrentThread;
INT8 v3;
__int64 v4;
int v5;
unsigned __int64 v6;
unsigned __int64 v7;
UINT8 *PoolWithQuota_2;
void *Src[2];
struct _WORK_QUEUE_ITEM WorkItem;
char Object[4];
int v13;
__int64 v14[4];
unsigned int v15;
*(_OWORD *)Src = 0i64;
memset((INT64)&WorkItem, 0i64);
if( !a1 )
return 3221225485i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v3 = *((_BYTE *)CurrentThread + 562);
if( v3 )
{
if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeLoadDriverPrivilege, v3) )
return 3221225569i64;
if( PsIsCurrentThreadInServerSilo() )
return 0i64;
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 3221225485i64;
if( (v6 & 1) != 0 )
ExRaiseDatatypeMisalignment();
v7 = v6 + (unsigned __int16)v5;
if( v7 > 0x7FFFFFFF0000i64 || v7 < v6 )
MEMORY[0x7FFFFFFF0000] = 0;
PoolWithQuota_2 = (UINT8 *)IopVerifierExAllocatePoolWithQuota_2(v6, LOWORD(Src[0]));
memmove(PoolWithQuota_2, (UINT8 *)Src[1], LOWORD(Src[0]));
Src[1] = PoolWithQuota_2;
}
else
{
*(_OWORD *)Src = *a1;
PoolWithQuota_2 = 0i64;
}
Object[2] = 6;
v13 = 0;
v14[1] = (__int64)v14;
v14[0] = (__int64)v14;
v14[2] = 0i64;
v14[3] = (__int64)Src;
if( *((PEPROCESS *)CurrentThread + 23) == PsInitialSystemProcess )
{
IopLoadUnloadDriver(&WorkItem);
}
else
{
WorkItem.WorkerRoutine = (void(__fastcall *)(void *))IopLoadUnloadDriver;
WorkItem.Parameter = &WorkItem;
WorkItem.List.Flink = 0i64;
ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(Object, UserRequest, 0, 0, 0i64);
}
if( PoolWithQuota_2 )
ExFreePoolWithTag(PoolWithQuota_2, 0);
return v15;
}Referenced by:
NtLoadDriver