ExpProfileCreate
NTSTATUS __stdcall ExpProfileCreate(
VOID **ProfileHandle,
VOID *Process,
VOID *RangeBase,
UINT64 RangeSize,
UINT64 BucketSize,
UINT64 *Buffer,
UINT64 BufferSize,
_KPROFILE_SOURCE ProfileSource,
UINT16 GroupCount,
_GROUP_AFFINITY *AffinityArray,
UINT8 ArrayProbed){
_GROUP_AFFINITY *v15;
NTSTATUS result;
unsigned __int64 v17;
char PreviousMode;
__int64 v19;
__int64 v20;
int inserted;
char *v22;
UINT64 Tag;
PVOID *Object;
POBJECT_HANDLE_INFORMATION HandleInformation;
UINT64 NonPagedPoolCharge;
int v27;
PVOID v28;
VOID *Address;
PVOID v30;
PVOID Handle;
VOID **v32;
_GROUP_AFFINITY GroupAffinity;
__int128 v34;
__int64 v35;
_OBJECT_ATTRIBUTES ObjectAttributes;
_KAFFINITY_EX Source;
v32 = ProfileHandle;
Address = Buffer;
v15 = AffinityArray;
memset(Source.Bitmap, 0i64, sizeof(Source.Bitmap));
GroupAffinity = 0i64;
Handle = 0i64;
memset(&ObjectAttributes, 0, sizeof(ObjectAttributes));
v28 = 0i64;
v30 = 0i64;
v34 = 0i64;
v35 = 0i64;
if( !(_DWORD)BufferSize )
return -1073741579;
if( (unsigned int)(BucketSize - 2) > 0x1D )
return -1073741811;
v17 = (RangeSize >> BucketSize) + 1;
if( !(RangeSize % (1i64 << BucketSize)) )
v17 = RangeSize >> BucketSize;
if( v17 > (unsigned __int64)(unsigned int)BufferSize >> 2 )
return -1073741789;
if( (unsigned __int64)RangeBase + RangeSize < RangeSize )
return -2147483643;
LODWORD(v34) = ProfileSource;
v27 = 0;
if( ((int(__fastcall *)(__int64, __int64, __int128 *, int *))off_140C00A68[0])(1i64, 24i64, &v34, &v27) < 0
|| v27 != 24
|| !BYTE4(v34) )
{
return -1073741637;
}
PreviousMode = KeGetCurrentThread()->PreviousMode;
if( PreviousMode )
{
v19 = (__int64)ProfileHandle;
if( (unsigned __int64)ProfileHandle >= 0x7FFFFFFF0000i64 )
v19 = 0x7FFFFFFF0000i64;
*(_QWORD *)v19 = *(_QWORD *)v19;
ProbeForWrite((UINT64)Address, (unsigned int)BufferSize, 4i64);
if( !ArrayProbed )
{
v20 = GroupCount;
if( v20 * 16 )
{
if( ((unsigned __int8)AffinityArray & 3) != 0 )
ExRaiseDatatypeMisalignment();
if( (unsigned __int64)&AffinityArray[v20] > 0x7FFFFFFF0000i64 || &AffinityArray[v20] < AffinityArray )
MEMORY[0x7FFFFFFF0000] = 0;
}
}
}
*(_DWORD *)&Source.Count = 1310721;
memset(&Source.Reserved, 0i64, 0xA4u);
while( GroupCount )
{
if( !PreviousMode || ArrayProbed )
GroupAffinity = *v15;
else
GroupAffinity = *v15;
if( !KeVerifyGroupAffinity(&GroupAffinity, 0) )
return -1073741811;
if( Source.Count <= GroupAffinity.Group )
Source.Count = GroupAffinity.Group + 1;
Source.Bitmap[GroupAffinity.Group] |= GroupAffinity.Mask;
--GroupCount;
++v15;
}
if( Process )
{
LODWORD(Tag) = 1716549701;
result = ObReferenceObjectByHandleWithTag(
Process,
0x400ui64,
(_OBJECT_TYPE *)PsProcessType,
PreviousMode,
Tag,
&v28,
0i64);
if( result < 0 )
return result;
}
else
{
if( (unsigned __int64)RangeBase <= 0x7FFFFFFEFFFFi64
&& PreviousMode
&& !SeSinglePrivilegeCheck(*(_QWORD *)&SeSystemProfilePrivilege, PreviousMode) )
{
return -1073741727;
}
v28 = 0i64;
}
if( (unsigned int)ExIsRestrictedCaller(PreviousMode)
&& RangeSize
&& ((unsigned __int64)RangeBase + RangeSize > 0x7FFFFFFF0000i64 || (char *)RangeBase + RangeSize < RangeBase) )
{
MEMORY[0x7FFFFFFF0000] = 0;
}
ObjectAttributes.Length = 48;
ObjectAttributes.RootDirectory = 0i64;
ObjectAttributes.Attributes = 32;
ObjectAttributes.ObjectName = 0i64;
*(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
LODWORD(NonPagedPoolCharge) = 488;
LODWORD(HandleInformation) = 0;
LODWORD(Object) = 240;
inserted = ObCreateObject(
0,
ExProfileObjectType,
&ObjectAttributes,
PreviousMode,
0i64,
(UINT64)Object,
(UINT64)HandleInformation,
NonPagedPoolCharge,
&v30);
if( inserted < 0 )
{
if( v28 )
ObfDereferenceObjectWithTag(v28, 0x66507845ui64);
}
else
{
v22 = (char *)v30;
*(_QWORD *)v30 = v28;
*((_QWORD *)v22 + 1) = RangeBase;
*((_QWORD *)v22 + 2) = RangeSize;
*((_QWORD *)v22 + 3) = Address;
*((_DWORD *)v22 + 8) = BufferSize;
*((_DWORD *)v22 + 9) = BucketSize;
*((_QWORD *)v22 + 6) = 0i64;
*((_DWORD *)v22 + 16) = 0;
*((_DWORD *)v22 + 17) = ProfileSource;
KeCopyAffinityEx((_KAFFINITY_EX *)(v22 + 72), &Source);
inserted = ObInsertObject(v22, 0i64, 1, 0i64, 0i64, &Handle);
LODWORD(Address) = inserted;
if( inserted >= 0 )
*v32 = Handle;
}
return inserted;
}Referenced by:
NtCreateProfile
NtCreateProfileEx