VrpHandleIoctlLoadDifferencingHive
NTSTATUS __stdcall VrpHandleIoctlLoadDifferencingHive(
VOID *Data,
UINT64 DataLength,
INT64 RequestorMode,
_GUID *ActivityId,
VOID *ReturnData,
UINT64 *ReturnDataLength){
unsigned int v6;
INT8 v8;
unsigned __int64 v9;
unsigned __int64 v10;
int v11;
unsigned int v12;
unsigned int v13;
VOID *v14;
int JobSilo;
wchar_t *v16;
_SIZE_T v17;
wchar_t *v18;
UINT64 *v19;
VOID **PoolWithTag;
UINT64 Tag;
_SIZE_T Taga;
UINT64 Tagb;
wchar_t *Object;
VOID **Objecta;
_SIZE_T HandleInformation;
wchar_t *v28;
_UNICODE_STRING TargetKeyPath;
_UNICODE_STRING NextLayerKeyPath;
_UNICODE_STRING TargetHivePath;
_EJOB *Silo;
v6 = DataLength;
ReturnData = 0i64;
ReturnDataLength = 0i64;
Silo = 0i64;
NextLayerKeyPath = 0i64;
v8 = RequestorMode;
TargetHivePath = 0i64;
TargetKeyPath = 0i64;
if( !SeSinglePrivilegeCheck(*(_QWORD *)&SeBackupPrivilege, RequestorMode)
|| !SeSinglePrivilegeCheck(*(_QWORD *)&SeRestorePrivilege, v8) )
{
return -1073741727;
}
if( v6 < 0x30 )
return -1073741811;
v9 = *((unsigned __int16 *)Data + 10);
if( (v9 & 1) != 0 )
return -1073741811;
v10 = *((unsigned __int16 *)Data + 11);
if( (v10 & 1) != 0 )
return -1073741811;
v11 = *((unsigned __int16 *)Data + 12);
if( (v11 & 1) != 0 )
return -1073741811;
if( !(_WORD)v9 )
return -1073741811;
if( !(_WORD)v10 )
return -1073741811;
v12 = v9 + 40;
v13 = v12 + v10;
if( v12 > v12 + (unsigned int)v10
|| v13 > v13 + v11
|| v6 < v13 + v11
|| (*((_DWORD *)Data + 3) & 1) != 0 && !(_WORD)v11 )
{
return -1073741811;
}
TargetKeyPath.MaximumLength = *((_WORD *)Data + 10);
TargetKeyPath.Length = v9;
TargetKeyPath.Buffer = (wchar_t *)((char *)Data + 40);
TargetHivePath.MaximumLength = v10;
TargetHivePath.Length = v10;
v14 = *(VOID **)Data;
TargetHivePath.Buffer = (wchar_t *)((char *)Data + 2 * (v9 >> 1) + 40);
NextLayerKeyPath.MaximumLength = v11;
NextLayerKeyPath.Length = v11;
NextLayerKeyPath.Buffer = &TargetHivePath.Buffer[v10 >> 1];
LODWORD(Tag) = 1381395779;
JobSilo = ObReferenceObjectByHandleWithTag(v14, 6ui64, (_OBJECT_TYPE *)PsJobType, v8, Tag, &ReturnData, 0i64);
if( JobSilo >= 0 )
{
JobSilo = PsGetJobSilo((_EJOB *)ReturnData, &Silo);
if( JobSilo >= 0 )
{
if( PsIsThreadInSilo((_ETHREAD *)KeGetCurrentThread(), Silo) )
{
JobSilo = -1073741811;
}
else
{
JobSilo = PsGetPermanentSiloContext(Silo, (unsigned int)VrpSiloContextSlot, (VOID **)&ReturnDataLength);
if( JobSilo < 0 )
goto LABEL_22;
v19 = ReturnDataLength;
VrpLockJobContextExclusive(
(PWCHAR)ReturnDataLength,
v16,
v17,
v18,
Taga,
Object,
HandleInformation,
v28,
*(_SIZE_T *)&TargetKeyPath.Length,
(INT64)TargetKeyPath.Buffer,
*(PWCHAR *)&NextLayerKeyPath.Length);
if( *((_DWORD *)v19 + 21) )
{
JobSilo = -1073741738;
}
else
{
LODWORD(Objecta) = (*((_DWORD *)Data + 3) >> 1) & 1;
LODWORD(Tagb) = *((_DWORD *)Data + 3) & 1;
JobSilo = VrpLoadDifferencingHive(
&TargetKeyPath,
(const VOID **)&TargetHivePath,
&NextLayerKeyPath,
*((unsigned int *)Data + 4),
Tagb,
Objecta);
if( JobSilo >= 0 )
{
PoolWithTag = ExAllocatePoolWithTag(1ui64, (unsigned int)TargetKeyPath.Length + 10, 1734693462i64);
if( PoolWithTag )
{
*((_WORD *)PoolWithTag + 4) = TargetKeyPath.Length;
memmove((char *)PoolWithTag + 10, TargetKeyPath.Buffer, TargetKeyPath.Length);
*PoolWithTag = (VOID *)v19[3];
v19[3] = (UINT64)PoolWithTag;
VrpUnlockJobContextExclusive((INT64)v19);
JobSilo = 0;
goto LABEL_22;
}
JobSilo = -1073741670;
VrpUnloadDifferencingHive(&TargetKeyPath);
}
}
VrpUnlockJobContextExclusive((INT64)v19);
}
}
}
LABEL_22:
if( ReturnData )
ObfDereferenceObjectWithTag(ReturnData, 0x52566D43ui64);
return JobSilo;
}Referenced by:
VrpIoctlDeviceDispatch