-
-
[分享]Win10的RtlCreateHeap分析
-
发表于: 2025-2-21 00:41 5706
-
自己分析了一下Win10的堆,但是有很多地方有不明白的。也可能分析错误,不要见怪,请求指正。
系统堆
判断是否是系统堆,如果是,则在判断系统兼容性(RtlpHpAppCompatDontChangePolicy())后创建段堆(Segment Heap)。
段堆
如果不是系统堆则判断HEAP_CREATE_SEGMENT_HEAP(0x100)标志,如果是则调用(_RtlpHpEnvGetEnvHandleFromParams)获取上下文后调用(_RtlpHpHeapCreate())创建段堆,否则创建普通堆。
普通堆
NTSYSAPI
PVOID
RtlCreateHeap(
[in]
ULONG
Flags,
[in, optional]
PVOID
HeapBase,
[in, optional]
SIZE_T
ReserveSize,
[in, optional]
SIZE_T
CommitSize,
[in, optional]
PVOID
Lock,
[in, optional] PRTL_HEAP_PARAMETERS Parameters
);
NTSYSAPI
PVOID
RtlCreateHeap(
[in]
ULONG
Flags,
[in, optional]
PVOID
HeapBase,
[in, optional]
SIZE_T
ReserveSize,
[in, optional]
SIZE_T
CommitSize,
[in, optional]
PVOID
Lock,
[in, optional] PRTL_HEAP_PARAMETERS Parameters
);
PVOID
RtlAllocateHeap(
[in]
PVOID
HeapHandle,
[in, optional]
ULONG
Flags,
[in]
SIZE_T
Size
) {
if
(HeapHandle == NULL) {
/*
// 记录错误日志
RtlpLogHeapFailure(0x13,0,0,0,0,0);
*/
}
if
(*((
DWORD
*)HeapHandle + 2) == 0xDDEEDDEE) {
/*
// 分配内存与异常处理
return RtlpHpAllocWithExceptionProtection(HeapHandle,Size,Flags);
*/
}
if
(_RtlpHpHeapFeatures & 2 != 0) {
/*
// 分配内存
RtlpHpTagAllocateHeap(HeapHandle,Size,Flags);
*/
}
// 分配内存
return
RtlpAllocateHeapInternal(HeapHandle, Size, Flags, 0);
}
PVOID
RtlAllocateHeap(
[in]
PVOID
HeapHandle,
[in, optional]
ULONG
Flags,
[in]
SIZE_T
Size
) {
if
(HeapHandle == NULL) {
/*
// 记录错误日志
RtlpLogHeapFailure(0x13,0,0,0,0,0);
*/
}
if
(*((
DWORD
*)HeapHandle + 2) == 0xDDEEDDEE) {
/*
// 分配内存与异常处理
return RtlpHpAllocWithExceptionProtection(HeapHandle,Size,Flags);
*/
}
if
(_RtlpHpHeapFeatures & 2 != 0) {
/*
// 分配内存
RtlpHpTagAllocateHeap(HeapHandle,Size,Flags);
*/
}
// 分配内存
return
RtlpAllocateHeapInternal(HeapHandle, Size, Flags, 0);
}
BOOL
RtlFreeHeap(
[in]
PVOID
HeapHandle,
[in, optional]
ULONG
Flags,
_Frees_ptr_opt_
PVOID
BaseAddress
) {
if
(!BaseAddress)
return
1;
if
(!HeapHandle)
/*
// 记录错误日志
RtlpLogHeapFailure(HeapHandle,0,0,0,0,0);
*/
if
(*(
DWORD
*)((
DWORD
)HeapHandle + 8) == 0xDDEEDDEE)
/*
// 在异常保护中释放内存
return RtlpHpFreeWithExceptionProtection(HeapHandle,BaseAddress,Flags);
*/
if
((RtlpHpHeapFeatures & 2) != 0)
/*
// LFH 快速堆分配的释放
return RtlpHpTagFreeHeap(HeapHandle, BaseAddress,Flags);
*/
/*
// 释放内存
return RtlpFreeHeapInternal(HeapHandle, BaseAddress, Flags, 0, 0);
*/
return
FALSE;
}
BOOL
RtlFreeHeap(
[in]
PVOID
HeapHandle,
[in, optional]
ULONG
Flags,
_Frees_ptr_opt_
PVOID
BaseAddress
) {
if
(!BaseAddress)
return
1;
if
(!HeapHandle)
/*
// 记录错误日志
RtlpLogHeapFailure(HeapHandle,0,0,0,0,0);
*/
if
(*(
DWORD
*)((
DWORD
)HeapHandle + 8) == 0xDDEEDDEE)
/*
// 在异常保护中释放内存
return RtlpHpFreeWithExceptionProtection(HeapHandle,BaseAddress,Flags);
*/
if
((RtlpHpHeapFeatures & 2) != 0)
/*
// LFH 快速堆分配的释放
return RtlpHpTagFreeHeap(HeapHandle, BaseAddress,Flags);
*/
/*
// 释放内存
return RtlpFreeHeapInternal(HeapHandle, BaseAddress, Flags, 0, 0);
*/
return
FALSE;
}
DWORD
dword_4B3A32DC = 0;
DWORD
dword_4B3A32F4 = 0;
// 函数?
DWORD
dword_4B3A32E4 = 0;
// 堆特性
DWORD
RtlpHpHeapFeatures = 0;
// 堆的错误处理行为
DWORD
RtlpHeapErrorHandlerThreshold = 0;
DWORD
dwAllocationGranularity = 0;
DWORD
_RtlHeapKey = 0;
DWORD
RtlpDisableHeapLookaside = 0;
DWORD
_RtlpDisableHeapLookaside = 0;
DWORD
_RtlpProcessHeapsListLock = 0;
PVOID
RtlCreateHeap(
ULONG
Flags,
PVOID
HeapBase,
SIZE_T
ReserveSize,
SIZE_T
CommitSize,
PVOID
Lock,
PRTL_HEAP_PARAMETERS Parameters
) {
DWORD
SizeOfHeap;
DWORD
var_C0 = CommitSize;
DWORD
RandValue;
_PEB32* peb = (_PEB32*)NtCurrentTeb()->ProcessEnvironmentBlock;
DWORD
NtGlobalFlag = peb->NtGlobalFlag;
DWORD
var_E4 = 0;
_HEAP* pHeapBase = 0;
DWORD
var_D0 = 0;
DWORD
var_4C;
DWORD
var_DC;
DWORD
var_D8;
DWORD
var_E0;
DWORD
var_CC;
DWORD
edi = (
DWORD
)Parameters;
DWORD
esi = 0;
DWORD
eax = 0;
if
(dword_4B3A32DC != 0) {
// 是否是系统堆
if
(HeapBase == 0 && Lock == 0) {
/*
RtlpHpAppCompatDontChangePolicy() // 不允许应用程序更改兼容性策略
DWORD Result = dword_4B3A32F4(Flags, 0, ReserveSize, CommitSize, 0, edi);
if(Result != 0)
return Result;
if(edi != 0xFFFFFFFF)
return NULL;
*/
edi = 0;
}
}
else
{
if
(dword_4B3A32E4 != 0) {
if
(edi == 1) {
if
((Flags & 0x100) != 0)
edi = 0;
}
}
}
Flags &= 0xF1FFFFFF;
if
((Flags & 0x100) != 0) {
//HEAP_CREATE_SEGMENT_HEAP 0x00000100
if
(Flags & 0x2 == 0 || HeapBase != 0 || ReserveSize != 0
|| CommitSize != 0 || Lock != 0)
return
NULL;
if
(edi == 0xFFFFFFFF && dword_4B3A32E4 != 0) {
edi = 0;
}
if
(edi == 0) {
esi = (
DWORD
)&var_4C;
}
else
{
esi = edi;
/*
// 检查参数是否合法
if(!RtlpHpParametersVerify(edi))
return NULL;
*/
}
}
else
if
(RtlpHpHeapFeatures & 1 != 0) {
if
(Flags & 0x2 != 0 && HeapBase == 0) {
if
(edi != 0) {
/*
// 检查参数是否合法
if(!RtlpHpParametersVerify(edi))
goto return53;
*/
}
eax = 2;
if
(Lock == 0)
esi = (
DWORD
)&var_4C;
}
}
return53:
eax = 2;
return52:
if
(esi != 0) {
// 创建一个有异常保护的堆
// return RtlpHpCreateHeap;
}
if
(Flags & 0x10000000 == 0) {
if
(RtlpHeapErrorHandlerThreshold >= eax) {
// 打印日志
}
if
(Flags & 0xFFF80C00 != 0) {
Flags &= 0x7F3FF;
}
}
RTL_HEAP_PARAMETERS stParameters = { 0 };
DWORD
var_4;
if
(Parameters != 0) {
var_4 = 0;
if
(Parameters->Length == 48) {
memcpy
(&stParameters, Parameters, 12);
}
var_4 = 0xFFFFFFFE;
}
// 修改flag
if
(NtGlobalFlag & 0x10 != 0) {
Flags |= 0x20;
}
if
(NtGlobalFlag & 0x20 != 0) {
Flags |= 0x40;
}
if
(NtGlobalFlag & 0x200000 != 0) {
Flags |= 0x80;
}
if
(NtGlobalFlag & 0x40 != 0) {
Flags |= 0x40000000;
}
if
(NtGlobalFlag & 0x80 != 0) {
Flags |= 0x20000000;
}
if
(NtGlobalFlag & 0x1000 != 0) {
Flags |= 0x8000000;
}
// 填充结构体
if
(stParameters.SegmentReserve == 0)
stParameters.SegmentReserve = peb->HeapSegmentReserve;
if
(stParameters.SegmentCommit == 0)
stParameters.SegmentCommit = peb->HeapSegmentCommit;
if
(stParameters.DeCommitFreeBlockThreshold == 0)
stParameters.DeCommitFreeBlockThreshold = peb->HeapDeCommitFreeBlockThreshold;
if
(stParameters.DeCommitTotalFreeThreshold == 0)
stParameters.DeCommitTotalFreeThreshold = peb->HeapDeCommitTotalFreeThreshold;
if
(dwAllocationGranularity == 0) {
/*
// 获取分配粒度
NtQuerySystemInformation
dwAllocationGranularity = dwAllocationGranularity;
// 失败
return NULL;
*/
}
if
(stParameters.MaximumAllocationSize == 0)
stParameters.MaximumAllocationSize = dwAllocationGranularity - 0x11000;
if
(stParameters.VirtualMemoryThreshold == 0 || stParameters.VirtualMemoryThreshold > 0x7F000)
stParameters.VirtualMemoryThreshold = 0x7F000;
DWORD
var_C4 = (CommitSize + 0xFFF) & 0xFFFFF000;
DWORD
var_BC = (var_C4 + 0xFFF) & 0xFFFFF000;
if
(ReserveSize != 0) {
var_BC = (ReserveSize + 0xFFF) & 0xFFFFF000;
}
if
(var_C4 > var_BC) {
var_C4 = var_BC;
}
esi = var_C4;
edi = (
DWORD
)HeapBase;
if
(Flags & 2 != 0 && HeapBase == 0) {
NtGlobalFlag = 0x1000;
var_E4 = 2;
if
(var_BC - 0x1000 < var_C4) {
var_BC += 0x10FFF;
var_BC &= 0xFFFF0000;
}
}
else
{
NtGlobalFlag = 0;
}
DWORD
ecx = var_BC;
if
(esi == 0)
return
NULL;
if
(var_BC == 0)
return
NULL;
if
(Flags & 0x61000000 != 0 && Flags & 0x10000000 != 0) {
/*
return RtlDebugCreateHeap(x,x,x,x,x,x);
*/
}
SizeOfHeap = 0x258;
if
(Flags & 1 != 0) {
if
(Lock == 0)
goto
return28;
return
NULL;
}
if
(Lock != 0) {
Flags |= 0x80000000;
}
var_D0 = (
DWORD
)Lock == 0 ? 0 : (
DWORD
)Lock;
SizeOfHeap = (
DWORD
)Lock == 0 ? 0x270 : 0x258;
return28:
if
(edi != 0) {
if
(stParameters.CommitRoutine != 0) {
if
(stParameters.InitialCommit == 0
|| stParameters.InitialReserve == 0
|| stParameters.InitialCommit > stParameters.InitialReserve
|| Flags & 2 != 0)
return
NULL;
var_CC = edi;
var_C0 = edi + stParameters.InitialCommit;
var_BC = stParameters.InitialReserve;
memset
((
void
*)edi, 0, 0x1000);
}
else
{
MEMORY_BASIC_INFORMATION32 MemInfo1 = { 0 };
MEMORY_BASIC_INFORMATION32 MemInfo2 = { 0 };
int
Ret = 0;
/*
// 查询 HeapBase 内存页面信息
Ret = NtQueryVirtualMemory(0xFFFFFFFF,(DWORD)HeapBase,3,&MemInfo1,0x1C,0);
*/
if
(Ret < 0) {
return
NULL;
}
var_C0 = MemInfo1.BaseAddress;
if
(MemInfo1.BaseAddress != edi) {
return
NULL;
}
if
(MemInfo1.State == 0x10000)
return
NULL;
var_CC = MemInfo1.BaseAddress;
if
(MemInfo1.State != 0x1000) {
var_BC = MemInfo1.RegionSize;
if
(var_C4 > MemInfo1.RegionSize) {
var_C4 = MemInfo1.RegionSize;
}
if
(var_C4 < 0x1000) {
return
NULL;
}
}
else
{
if
(Flags & 0x40000 != 0 && MemInfo1.Protect & 0x40 == 0)
return
NULL;
/*
// 查询 HeapBase 内存页面信息
Ret = NtQueryVirtualMemory(0xFFFFFFFF,(DWORD)HeapBase,3,&MemInfo2,0x1C,0);
*/
if
(Ret < 0) {
return
NULL;
}
var_BC = MemInfo2.RegionSize;
var_C4 = MemInfo1.RegionSize;
var_C0 = MemInfo1.RegionSize + var_CC;
}
}
var_E4 |= 1;
pHeapBase = (_HEAP*)edi;
edi = Flags & 0x40000;
ecx = var_C0;
eax = var_CC;
}
else
{
var_DC = 0;
if
(stParameters.CommitRoutine != 0)
return
NULL;
/*
// 生成随机数
RandValue = RtlpHeapGenerateRandomValue32();
*/
RandValue = 0;
/*
var_D8 = (RtlpHeapGenerateRandomValue32() & 1Fh) << 0x10;
*/
var_D8 = 0;
var_E0 = var_D8 + var_BC;
if
(var_E0 < var_BC) {
var_E0 = var_BC;
var_D8 = 0;
}
/*
// 申请内存
int result = NtAllocateVirtualMemory(0xFFFFFFFF, &var_DC, 0, &var_E0, 0x2000, Flags & 0x40000 == 0 ? 0 : 0x40);;
if(result < 0)
return 0;
*/
pHeapBase = (_HEAP*)var_DC;
var_BC = var_E0;
if
(var_D8 != 0) {
/*
// 释放内存
RtlpSecMemFreeVirtualMemory(&var_DC,var_BC,&var_D8,0x8000);
*/
pHeapBase = (_HEAP*)(var_DC + var_D8);
var_BC = var_E0 - var_D8;
}
var_CC = (
DWORD
)pHeapBase;
var_C0 = (
DWORD
)pHeapBase;
}
if
(var_CC == var_C0) {
char
* p = NULL;
/*
// 申请内存
int result = NtAllocateVirtualMemory(0xFFFFFFFF, &var_CC, 0, &var_C4, 0x1000, Flags & 0x40000 == 0 ? 0 : 0x40);;
if(result < 0)
return 0;
// 获取会话ID
char *p = NULL;
if(RtlGetCurrentServiceSessionId()){
p = _PEB.SharedData + 0x226;
}else{
p = 0x7FFE0380;
}
*/
if
(*p != 0) {
if
(peb->___u71.TracingFlags != 1) {
/*
// 记录堆提交操作
RtlpLogHeapCommit(pHeapBase,var_CC,var_C4,1);
*/
}
}
var_C0 += var_C4;
}
edi = (
DWORD
)pHeapBase + 0x258;
if
(peb->NtGlobalFlag & 0x800 != 0) {
// 进程被调试
pHeapBase->PseudoTagEntries = (_HEAP_PSEUDO_TAG_ENTRY * )(((
DWORD
)pHeapBase + 0x25F) & 0x0FFFFFFF8);
SizeOfHeap = 0x60C;
edi = (
DWORD
)pHeapBase->PseudoTagEntries + 0x60C;
Flags |= 0x4000000;
esi = Flags;
}
RandValue = (SizeOfHeap + 7) & 0xFFFFFFF8;
pHeapBase->___u0.Segment.Entry.___u0.__s1.Size = (RandValue >> 3) & 0xFFFF;
pHeapBase->___u0.Segment.Entry.___u0.__s1.Flags = 1;
pHeapBase->___u0.Segment.Entry.___u0.ExtendedEntry.ExtendedBlockSignature = 1;
pHeapBase->Signature = 0xEEFFEEFF;
pHeapBase->Flags = esi;
pHeapBase->Interceptor = 0;
memset
(&pHeapBase->Counters, 0,
sizeof
(pHeapBase->Counters));
/*
// 初始化 Encoding 成员
RtlpCreateHeapEncoding(pHeapBase);
*/
pHeapBase->Counters.HeapPollInterval = 1;
if
(pHeapBase->Flags & 0x8000000 != 0) {
int
result = 0;
/*
// 记录调试日志
result = RtlpGetHeapInterceptorIndex(&RtlpStackTraceDatabaseLogPrefix);
*/
pHeapBase->Interceptor &= (result & 0xFFFF);
}
pHeapBase->ForceFlags = Flags & 0x6001007D;
pHeapBase->HeaderValidateLength = edi - (
DWORD
)pHeapBase;
pHeapBase->HeaderValidateCopy = NULL;
pHeapBase->FreeLists.Blink = &pHeapBase->FreeLists;
pHeapBase->FreeLists.Flink = &pHeapBase->FreeLists;
pHeapBase->VirtualAllocdBlocks.Blink = &pHeapBase->VirtualAllocdBlocks;
pHeapBase->VirtualAllocdBlocks.Flink = &pHeapBase->VirtualAllocdBlocks;
pHeapBase->SegmentList.Blink = &pHeapBase->SegmentList;
pHeapBase->SegmentList.Flink = &pHeapBase->SegmentList;
pHeapBase->UCRList.Blink = &pHeapBase->UCRList;
pHeapBase->UCRList.Flink = &pHeapBase->UCRList;
if
(var_D0 == 0 && Flags & 1 == 0) {
var_D0 = edi;
int
Ret = 0;
/*
// 线程同步
Ret = RtlInitializeCriticalSectionEx(var_D0,0,0x10000000);
*/
if
(Ret < 0) {
return
NULL;
}
edi += 0x18;
ecx = var_D0;
}
pHeapBase->LockVariable = (_HEAP_LOCK * )var_D0;
pHeapBase->CompatibilityFlags |= 0x80000000;
int
Ret = 0;
/*
// 初始化堆段
Ret = RtlpInitializeHeapSegment((DWORD)pHeapBase,(DWORD)pHeapBase,RandValue + 0x238,pHeapBase->LockVariable,var_E4,var_CC,var_C0,var_CC - NtGlobalFlag + var_BC);
*/
if
(Ret == 0) {
return
NULL;
}
esi = 0x80;
if
(pHeapBase->___u0.Segment.Entry.___u0.__s5.InterceptorValue != 0) {
memset
((
void
*)edi, 0, 0x80);
}
char
* p = (
char
*)edi;
*(
DWORD
*)(p + 4) = 0x80;
*(
DWORD
*)(p + 0x1C) = (
DWORD
)(p+0x24);
*(
DWORD
*)(p + 0x18) = (
DWORD
)&pHeapBase->FreeLists;
*(
DWORD
*)(p + 0x20) = (
DWORD
)(p + 0x34);
/*
// 初始化堆块
RtlpPopulateListIndex(pHeapBase,edi);
*/
pHeapBase->ProcessHeapsListIndex = 0;
pHeapBase->SegmentReserve = stParameters.SegmentReserve;
pHeapBase->SegmentCommit = stParameters.SegmentCommit;
pHeapBase->DeCommitFreeBlockThreshold = stParameters.DeCommitFreeBlockThreshold >> 3;
pHeapBase->DeCommitTotalFreeThreshold = stParameters.DeCommitTotalFreeThreshold >> 3;
pHeapBase->MaximumAllocationSize = stParameters.MaximumAllocationSize;
pHeapBase->VirtualMemoryThreshold = (stParameters.VirtualMemoryThreshold + 7) >> 3;
*(
DWORD
*)pHeapBase->CommitRoutine = (
DWORD
)stParameters.CommitRoutine ^ _RtlHeapKey;
pHeapBase->TuningParameters.CommittThresholdShift = 4;
pHeapBase->TuningParameters.MaxPreCommittThreshold = 0xFE000;
if
(RtlpDisableHeapLookaside & 1 != 0) {
pHeapBase->CompatibilityFlags = 1;
}
if
(Flags & 0x10000 == 0) {
pHeapBase->AlignRound = 0xF;
pHeapBase->AlignMask = 0xFFFFFFF8;
}
else
{
pHeapBase->AlignRound = 0x17;
pHeapBase->AlignMask = 0xFFFFFFF0;
}
if
(pHeapBase->Flags & 0x20 != 0) {
pHeapBase->AlignRound += 8;
}
pHeapBase->FrontEndHeap = 0;
pHeapBase->FrontHeapLockCount = 0;
pHeapBase->FrontEndHeapType = 0;
pHeapBase->RequestedFrontEndHeapType = 0;
pHeapBase->UCRIndex = 0;
if
((Flags & 3) == 2 ? 1 : 0 & _RtlpDisableHeapLookaside & 1 == 0 ? 1 : 0 != 0) {
wchar_t
* Ret = 0;
/*
// 申请内存
Ret = RtlAllocateHeap(pHeapBase,0x80000A,0x256);
*/
pHeapBase->FrontEndHeapUsageData = Ret;
if
(pHeapBase->FrontEndHeapUsageData == 0) {
return
NULL;
}
*(pHeapBase->FrontEndHeapUsageData - 1) = 1;
pHeapBase->FrontEndHeapMaximumIndex = 0x80;
}
/*
// 进入临界区
RtlEnterCriticalSection(&_RtlpProcessHeapsListLock);
// 添加到堆列表
RtlpAddHeapToUnprotectedList(pHeapBase);
// 退出临界区
RtlEnterCriticalSection(&_RtlpProcessHeapsListLock);
*/
if
(pHeapBase->ProcessHeapsListIndex == 0) {
return
NULL;
}
DWORD
SessionId = 0;
/*
// 获取会话ID
SessionId = RtlGetCurrentServiceSessionId();
*/
if
(SessionId != 0) {
SessionId = (
DWORD
)peb->SharedData + 0x226;
}
else
{
SessionId = 0x7FFE0380;
}
if
(*(
char
*)SessionId != 0 && peb->___u71.TracingFlags & 1 != 0) {
/*
// 获取会话ID
SessionId = RtlGetCurrentServiceSessionId();
*/
if
(SessionId != 0) {
SessionId = (
DWORD
)peb->SharedData + 0x226;
}
/*
// 记录日志
RtlpLogHeapCreateEvent(pHeapBase,Flags,var_BC,var_C4,*(char*)SessionId);
*/
}
else
{
esi = Flags;
}
/*
// 获取会话ID
SessionId = RtlGetCurrentServiceSessionId();
*/
if
(SessionId != 0) {
SessionId = (
DWORD
)peb->SharedData + 0x230;
}
else
{
SessionId = 0x7FFE038A;
}
if
(*(
char
*)SessionId != 0) {
/*
// 获取会话ID
SessionId = RtlGetCurrentServiceSessionId();
*/
if
(SessionId != 0) {
SessionId = (
DWORD
)peb->SharedData + 0x230;
}
/*
// 记录日志
RtlpLogHeapCreateEvent(pHeapBase,Flags,var_BC,var_C4,*(char*)SessionId);
*/
}
/*
// 获取会话ID
SessionId = RtlGetCurrentServiceSessionId();
*/
if
(SessionId != 0) {
SessionId = (
DWORD
)peb->SharedData + 0x22E;
}
else
{
SessionId = 0x7FFE0388;
}
if
(*(
char
*)SessionId != 0) {
/*
RtlpHeapLogRangeCreate(pHeapBase,var_BC,Flags);
*/
}
pHeapBase->CompatibilityFlags = 0x7FFFFFFF;
pHeapBase->StackTraceInitVar.Ptr = NULL;
return
(
PVOID
)pHeapBase;
}
DWORD
dword_4B3A32DC = 0;
DWORD
dword_4B3A32F4 = 0;
// 函数?
DWORD
dword_4B3A32E4 = 0;
// 堆特性
DWORD
RtlpHpHeapFeatures = 0;
// 堆的错误处理行为
DWORD
RtlpHeapErrorHandlerThreshold = 0;
DWORD
dwAllocationGranularity = 0;
DWORD
_RtlHeapKey = 0;
DWORD
RtlpDisableHeapLookaside = 0;
DWORD
_RtlpDisableHeapLookaside = 0;
DWORD
_RtlpProcessHeapsListLock = 0;
PVOID
RtlCreateHeap(
ULONG
Flags,
PVOID
HeapBase,
SIZE_T
ReserveSize,
SIZE_T
CommitSize,
PVOID
Lock,
PRTL_HEAP_PARAMETERS Parameters
) {
DWORD
SizeOfHeap;
DWORD
var_C0 = CommitSize;
DWORD
RandValue;
_PEB32* peb = (_PEB32*)NtCurrentTeb()->ProcessEnvironmentBlock;
DWORD
NtGlobalFlag = peb->NtGlobalFlag;
DWORD
var_E4 = 0;
_HEAP* pHeapBase = 0;
DWORD
var_D0 = 0;
DWORD
var_4C;
DWORD
var_DC;
DWORD
var_D8;
DWORD
var_E0;
DWORD
var_CC;
DWORD
edi = (
DWORD
)Parameters;
DWORD
esi = 0;
DWORD
eax = 0;
if
(dword_4B3A32DC != 0) {
// 是否是系统堆
if
(HeapBase == 0 && Lock == 0) {
/*
RtlpHpAppCompatDontChangePolicy() // 不允许应用程序更改兼容性策略
DWORD Result = dword_4B3A32F4(Flags, 0, ReserveSize, CommitSize, 0, edi);
if(Result != 0)
return Result;
if(edi != 0xFFFFFFFF)
return NULL;
*/
edi = 0;
}
}
else
{
if
(dword_4B3A32E4 != 0) {
if
(edi == 1) {
if
((Flags & 0x100) != 0)
edi = 0;
}
}
}
Flags &= 0xF1FFFFFF;
if
((Flags & 0x100) != 0) {
//HEAP_CREATE_SEGMENT_HEAP 0x00000100
if
(Flags & 0x2 == 0 || HeapBase != 0 || ReserveSize != 0
|| CommitSize != 0 || Lock != 0)
return
NULL;
if
(edi == 0xFFFFFFFF && dword_4B3A32E4 != 0) {
edi = 0;
}
if
(edi == 0) {
esi = (
DWORD
)&var_4C;
}
else
{
esi = edi;
/*
// 检查参数是否合法
if(!RtlpHpParametersVerify(edi))
return NULL;
*/
}
}
else
if
(RtlpHpHeapFeatures & 1 != 0) {
if
(Flags & 0x2 != 0 && HeapBase == 0) {
if
(edi != 0) {
/*
// 检查参数是否合法
if(!RtlpHpParametersVerify(edi))
goto return53;
*/
}
eax = 2;
if
(Lock == 0)
esi = (
DWORD
)&var_4C;
}
}
return53:
eax = 2;
return52:
if
(esi != 0) {
// 创建一个有异常保护的堆
// return RtlpHpCreateHeap;
}
if
(Flags & 0x10000000 == 0) {
if
(RtlpHeapErrorHandlerThreshold >= eax) {
// 打印日志
}
if
(Flags & 0xFFF80C00 != 0) {
Flags &= 0x7F3FF;
}
}
RTL_HEAP_PARAMETERS stParameters = { 0 };
DWORD
var_4;
if
(Parameters != 0) {
var_4 = 0;
if
(Parameters->Length == 48) {
memcpy
(&stParameters, Parameters, 12);
}
var_4 = 0xFFFFFFFE;
}
// 修改flag
if
(NtGlobalFlag & 0x10 != 0) {
Flags |= 0x20;
}
if
(NtGlobalFlag & 0x20 != 0) {
Flags |= 0x40;
}
if
(NtGlobalFlag & 0x200000 != 0) {
Flags |= 0x80;
}
if
(NtGlobalFlag & 0x40 != 0) {
Flags |= 0x40000000;
}
if
(NtGlobalFlag & 0x80 != 0) {
Flags |= 0x20000000;
}
if
(NtGlobalFlag & 0x1000 != 0) {
Flags |= 0x8000000;
}
// 填充结构体
if
(stParameters.SegmentReserve == 0)
stParameters.SegmentReserve = peb->HeapSegmentReserve;
if
(stParameters.SegmentCommit == 0)
stParameters.SegmentCommit = peb->HeapSegmentCommit;
if
(stParameters.DeCommitFreeBlockThreshold == 0)
stParameters.DeCommitFreeBlockThreshold = peb->HeapDeCommitFreeBlockThreshold;
if
(stParameters.DeCommitTotalFreeThreshold == 0)
stParameters.DeCommitTotalFreeThreshold = peb->HeapDeCommitTotalFreeThreshold;
if
(dwAllocationGranularity == 0) {
/*
// 获取分配粒度
NtQuerySystemInformation
dwAllocationGranularity = dwAllocationGranularity;
// 失败
return NULL;
*/
}
if
(stParameters.MaximumAllocationSize == 0)
stParameters.MaximumAllocationSize = dwAllocationGranularity - 0x11000;
if
(stParameters.VirtualMemoryThreshold == 0 || stParameters.VirtualMemoryThreshold > 0x7F000)
stParameters.VirtualMemoryThreshold = 0x7F000;
DWORD
var_C4 = (CommitSize + 0xFFF) & 0xFFFFF000;
DWORD
var_BC = (var_C4 + 0xFFF) & 0xFFFFF000;
if
(ReserveSize != 0) {
var_BC = (ReserveSize + 0xFFF) & 0xFFFFF000;
}
if
(var_C4 > var_BC) {
var_C4 = var_BC;
}
esi = var_C4;
edi = (
DWORD
)HeapBase;
if
(Flags & 2 != 0 && HeapBase == 0) {
NtGlobalFlag = 0x1000;
var_E4 = 2;
if
(var_BC - 0x1000 < var_C4) {
var_BC += 0x10FFF;
var_BC &= 0xFFFF0000;
}
}
else
{
NtGlobalFlag = 0;
}
DWORD
ecx = var_BC;
if
(esi == 0)
return
NULL;
if
(var_BC == 0)
return
NULL;
if
(Flags & 0x61000000 != 0 && Flags & 0x10000000 != 0) {
/*
return RtlDebugCreateHeap(x,x,x,x,x,x);
*/
}
SizeOfHeap = 0x258;
if
(Flags & 1 != 0) {
if
(Lock == 0)
goto
return28;
return
NULL;
}
if
(Lock != 0) {
Flags |= 0x80000000;
}
var_D0 = (
DWORD
)Lock == 0 ? 0 : (
DWORD
)Lock;
SizeOfHeap = (
DWORD
)Lock == 0 ? 0x270 : 0x258;
return28:
if
(edi != 0) {
if
(stParameters.CommitRoutine != 0) {
if
(stParameters.InitialCommit == 0
|| stParameters.InitialReserve == 0
|| stParameters.InitialCommit > stParameters.InitialReserve
|| Flags & 2 != 0)
return
NULL;
var_CC = edi;
var_C0 = edi + stParameters.InitialCommit;
var_BC = stParameters.InitialReserve;
memset
((
void
*)edi, 0, 0x1000);
}
else
{
MEMORY_BASIC_INFORMATION32 MemInfo1 = { 0 };
MEMORY_BASIC_INFORMATION32 MemInfo2 = { 0 };
int
Ret = 0;
/*
// 查询 HeapBase 内存页面信息
Ret = NtQueryVirtualMemory(0xFFFFFFFF,(DWORD)HeapBase,3,&MemInfo1,0x1C,0);
*/
if
(Ret < 0) {
return
NULL;
}
var_C0 = MemInfo1.BaseAddress;
if
(MemInfo1.BaseAddress != edi) {
return
NULL;
}
if
(MemInfo1.State == 0x10000)
return
NULL;
var_CC = MemInfo1.BaseAddress;
if
(MemInfo1.State != 0x1000) {
var_BC = MemInfo1.RegionSize;
if
(var_C4 > MemInfo1.RegionSize) {
var_C4 = MemInfo1.RegionSize;
}
if
(var_C4 < 0x1000) {
return
NULL;
}
}
else
{
if
(Flags & 0x40000 != 0 && MemInfo1.Protect & 0x40 == 0)
return
NULL;
/*
// 查询 HeapBase 内存页面信息
Ret = NtQueryVirtualMemory(0xFFFFFFFF,(DWORD)HeapBase,3,&MemInfo2,0x1C,0);
*/
if
(Ret < 0) {
return
NULL;
}
var_BC = MemInfo2.RegionSize;
var_C4 = MemInfo1.RegionSize;
var_C0 = MemInfo1.RegionSize + var_CC;
}
}
var_E4 |= 1;
pHeapBase = (_HEAP*)edi;
edi = Flags & 0x40000;
ecx = var_C0;
eax = var_CC;
}
else
{
var_DC = 0;
if
(stParameters.CommitRoutine != 0)
return
NULL;
/*
// 生成随机数
RandValue = RtlpHeapGenerateRandomValue32();
*/
RandValue = 0;
/*
var_D8 = (RtlpHeapGenerateRandomValue32() & 1Fh) << 0x10;
*/
var_D8 = 0;
var_E0 = var_D8 + var_BC;
if
(var_E0 < var_BC) {
var_E0 = var_BC;
var_D8 = 0;
}
/*
// 申请内存
int result = NtAllocateVirtualMemory(0xFFFFFFFF, &var_DC, 0, &var_E0, 0x2000, Flags & 0x40000 == 0 ? 0 : 0x40);;
if(result < 0)
return 0;
*/
pHeapBase = (_HEAP*)var_DC;
var_BC = var_E0;
if
(var_D8 != 0) {
/*
// 释放内存
RtlpSecMemFreeVirtualMemory(&var_DC,var_BC,&var_D8,0x8000);
*/
pHeapBase = (_HEAP*)(var_DC + var_D8);
var_BC = var_E0 - var_D8;
}
var_CC = (
DWORD
)pHeapBase;
var_C0 = (
DWORD
)pHeapBase;
}
if
(var_CC == var_C0) {
char
* p = NULL;
/*
// 申请内存
int result = NtAllocateVirtualMemory(0xFFFFFFFF, &var_CC, 0, &var_C4, 0x1000, Flags & 0x40000 == 0 ? 0 : 0x40);;
if(result < 0)
return 0;
// 获取会话ID
char *p = NULL;
if(RtlGetCurrentServiceSessionId()){
p = _PEB.SharedData + 0x226;
}else{
p = 0x7FFE0380;
}
*/
if
(*p != 0) {
if
(peb->___u71.TracingFlags != 1) {
/*
// 记录堆提交操作
RtlpLogHeapCommit(pHeapBase,var_CC,var_C4,1);
*/
}
}
var_C0 += var_C4;
}
edi = (
DWORD
)pHeapBase + 0x258;
if
(peb->NtGlobalFlag & 0x800 != 0) {
// 进程被调试
pHeapBase->PseudoTagEntries = (_HEAP_PSEUDO_TAG_ENTRY * )(((
DWORD
)pHeapBase + 0x25F) & 0x0FFFFFFF8);
SizeOfHeap = 0x60C;
edi = (
DWORD
)pHeapBase->PseudoTagEntries + 0x60C;
Flags |= 0x4000000;
esi = Flags;
}
RandValue = (SizeOfHeap + 7) & 0xFFFFFFF8;
pHeapBase->___u0.Segment.Entry.___u0.__s1.Size = (RandValue >> 3) & 0xFFFF;
pHeapBase->___u0.Segment.Entry.___u0.__s1.Flags = 1;
pHeapBase->___u0.Segment.Entry.___u0.ExtendedEntry.ExtendedBlockSignature = 1;
pHeapBase->Signature = 0xEEFFEEFF;
pHeapBase->Flags = esi;
pHeapBase->Interceptor = 0;
memset
(&pHeapBase->Counters, 0,
sizeof
(pHeapBase->Counters));
/*
// 初始化 Encoding 成员
RtlpCreateHeapEncoding(pHeapBase);
*/
pHeapBase->Counters.HeapPollInterval = 1;
if
(pHeapBase->Flags & 0x8000000 != 0) {
int
result = 0;
/*
// 记录调试日志
result = RtlpGetHeapInterceptorIndex(&RtlpStackTraceDatabaseLogPrefix);
*/
pHeapBase->Interceptor &= (result & 0xFFFF);
}
pHeapBase->ForceFlags = Flags & 0x6001007D;
pHeapBase->HeaderValidateLength = edi - (
DWORD
)pHeapBase;
pHeapBase->HeaderValidateCopy = NULL;
pHeapBase->FreeLists.Blink = &pHeapBase->FreeLists;
pHeapBase->FreeLists.Flink = &pHeapBase->FreeLists;
pHeapBase->VirtualAllocdBlocks.Blink = &pHeapBase->VirtualAllocdBlocks;
pHeapBase->VirtualAllocdBlocks.Flink = &pHeapBase->VirtualAllocdBlocks;
pHeapBase->SegmentList.Blink = &pHeapBase->SegmentList;
pHeapBase->SegmentList.Flink = &pHeapBase->SegmentList;
pHeapBase->UCRList.Blink = &pHeapBase->UCRList;
pHeapBase->UCRList.Flink = &pHeapBase->UCRList;
if
(var_D0 == 0 && Flags & 1 == 0) {
var_D0 = edi;
int
Ret = 0;
/*
// 线程同步
Ret = RtlInitializeCriticalSectionEx(var_D0,0,0x10000000);
*/
if
(Ret < 0) {
return
NULL;
}
edi += 0x18;
ecx = var_D0;
}
pHeapBase->LockVariable = (_HEAP_LOCK * )var_D0;
pHeapBase->CompatibilityFlags |= 0x80000000;
int
Ret = 0;
/*
// 初始化堆段
Ret = RtlpInitializeHeapSegment((DWORD)pHeapBase,(DWORD)pHeapBase,RandValue + 0x238,pHeapBase->LockVariable,var_E4,var_CC,var_C0,var_CC - NtGlobalFlag + var_BC);
*/
if
(Ret == 0) {
return
NULL;
}
esi = 0x80;
if
(pHeapBase->___u0.Segment.Entry.___u0.__s5.InterceptorValue != 0) {
memset
((
void
*)edi, 0, 0x80);
}
char
* p = (
char
*)edi;
*(
DWORD
*)(p + 4) = 0x80;
*(
DWORD
*)(p + 0x1C) = (
DWORD
)(p+0x24);
*(
DWORD
*)(p + 0x18) = (
DWORD
)&pHeapBase->FreeLists;
*(
DWORD
*)(p + 0x20) = (
DWORD
)(p + 0x34);
/*
// 初始化堆块
RtlpPopulateListIndex(pHeapBase,edi);
*/
pHeapBase->ProcessHeapsListIndex = 0;
pHeapBase->SegmentReserve = stParameters.SegmentReserve;
pHeapBase->SegmentCommit = stParameters.SegmentCommit;
pHeapBase->DeCommitFreeBlockThreshold = stParameters.DeCommitFreeBlockThreshold >> 3;
pHeapBase->DeCommitTotalFreeThreshold = stParameters.DeCommitTotalFreeThreshold >> 3;
pHeapBase->MaximumAllocationSize = stParameters.MaximumAllocationSize;
pHeapBase->VirtualMemoryThreshold = (stParameters.VirtualMemoryThreshold + 7) >> 3;
*(
DWORD
*)pHeapBase->CommitRoutine = (
DWORD
)stParameters.CommitRoutine ^ _RtlHeapKey;
pHeapBase->TuningParameters.CommittThresholdShift = 4;
pHeapBase->TuningParameters.MaxPreCommittThreshold = 0xFE000;
if
(RtlpDisableHeapLookaside & 1 != 0) {
pHeapBase->CompatibilityFlags = 1;
}
if
(Flags & 0x10000 == 0) {
赞赏记录
参与人
雪币
留言
时间
Cherzsh
你的分享对大家帮助很大,非常感谢!
2025-2-23 23:24
顽劣
感谢你的贡献,论坛因你而更加精彩!
2025-2-21 11:43
赞赏
赞赏
雪币:
留言: