首页
社区
课程
招聘
7
[原创]Windows10代码还原汇编特征汇总(附NTDLL CreateHeap还原代码)
发表于: 2025-2-13 20:55 8847

[原创]Windows10代码还原汇编特征汇总(附NTDLL CreateHeap还原代码)

2025-2-13 20:55
8847

大家好,我是武汉科锐逆向CR49期的一名学员,我写这篇文章的目的是想帮助刚开始或者准备开始研究windows系统的人员,此篇文章仅作为经验分享,是我在逆向还原windows10堆API CreateHeapAllocateHeap以及AllocateHeapInternal源代码时总结的一些经验,如有错误请各位前辈斧正。我们仅分享其windows10 ntdll中常见的一些汇编特征优化,如若不涉及的优化请各位自行翻阅资料学习。

分析环境: Windows11
工具: Windbg, IDA7.5
分析目标平台: Windows10
分析目标文件: C:\Windows\SysWow64\ntdll.dll(32位)
版本信息:10.0.19041.5007 (WinBuild.160101.0800)
SHA-1:9C3A55D17C022D7B32EE558E8941C4C9938696CA

对于常见的Release版编译的优化此篇文章涉及到的有
CPU流水线优化
真正的CPU流水线优化有许多概念且十分复杂,但是体现在代码中的我们只需要关注一些会影响我们分析的内容,比如乱序执行我们以最经典的三级流水线为例举出例子方便大家简易回顾一下流水线优化。如下三个操作分别由三个不同的CPU组件同步执行
● 取指令
● 译码
● 执行
在CPU中形如如下流程,但是流水线优化只会优化无相关关联的代码譬如:mov eax, imm32 mov ebx, imm32 等,而如果出现一个指令序列其中的前后代码相关联则会破坏该处的流水线优化,对于3级流水线来讲最好情况是3行代码互相无关。
下面我们给出相关图例辅助理解
图片描述
一旦出现的一组代码(A组)可以组成流水线优化则意味着该组代码A的执行顺序与组内其他代码无关,且改组代码也有可能与其他组代码无关,此时编译器有可能将该组代码提前(延后)到某组代码(B组)后执行且不会影响程序的逻辑,最简单的情况就是__cdecl后的调用方的平栈代码add esp, imm在ntdll中如果出现调用函数为__cdecl就有可能出现这种优化可能会在后面的代码中穿插一条平栈代码,在还原代码时我们只需要跳过即可。
加法优化(比例因子优化)
对于加法通常我们能看到利用lea指令进行优化,譬如eax + eax + 1在优化版中会出现形如lea eax, [eax+eax+1]等优化类型但是在此次还原中出现较少。

在逆向的过程中我们经常能看到如下片段
图片描述
对于这种情况我们在初次见到时如果发现前面的esi原先为某个变量值但是被赋值覆盖掉了原值,然后中间经过一系列操作运算传入了某个函数或者放入了某个变量,则有可能是编译过程编译器将临时变量优化掉了导致的譬如如下C代码

在这种情况下就有可能将中间代码dwRet当作临时变量优化掉变成如下汇编形式

当我们出现如下情况时考虑出现了临时变量优化尽量看此寄存器是否用作他用,如果是传参则可以还原为传入参数写表达式,如果是变量赋值则可以写作将表达式赋值为变量。

对于0值寄存器传递是我在逆向CreateHeap API的时候发现的, 图片描述
这里的EBX寄存器在整个函数中都被当作0值进行赋值操作,譬如在返回失败空值的时候对返回值esi的赋0处理
图片描述

对于这个应该也属于是常见优化里面的但是笔者还是提出来单独分析一下,对于大家习惯用的ida如果F5之后发现函数参数不对多半就是因为编译器将原本的__stdcall优化为__fastcall譬如
图片描述
对于见到在调用前给EDX和ECX等赋值的行为我们需要进入其调用的函数中查看
图片描述
如果被调用的函数中直接使用了EDX或者ECX寄存器则考虑将该函数翻译为__stdcall或者照例翻译为__fastcall具体情况应该视可读性和可维护性而定。

在讨论这个汇编特征之前我们先看一下VS2019对if语句的优化如下

图示
图片描述
在正常的VS2019编译器中Release将会把汇编优化为取反跳的形式但是在ntdll中如果出现了跳转分支在平坦流片段中的情况则需要翻译为条件不取反如果跳转后的平坦流片段中紧接判断还可以考虑将其整合翻译为条件表达式 + if语句的形式
在还原过程中还有一种情况就是条件表达式融合到平坦流中,在这种情况下同样需要翻译为条件不去反然后将平坦流中的代码翻译到条件语句块中,一般这种情况会经历两次跳转,一次是跳入另一次是在平坦流跳出,如果有else语句则有可能跳出到出口前面。
我们来看下面的例子,首先是外层 图片描述
然后是内层
图片描述
在ntdll中我们会遇到大量这种形式的代码,唯独在较为短小的条件判断语句中能看到正常取反跳的优化身影,我们需要多往后看看比对跳转的汇编标签是否和平坦流内部的跳转相同,辅以上下文依据可读性进行判断。

对于这种情况多半是寄存器不够用了,这种情况后面多半会接一个call或者较为复杂的比较逻辑,如下示例
图片描述

对于windows的逆向需要熟悉其内部编译器的汇编代码优化特征才能更好的进行还原,我仅PO出我逆向还原的CreateHeap API代码,而AllocateHeap等其他API代码就不发了。注意:此代码仅作学习用途,且由于是项目原因,所以我给出粗糙版的代码,某些结构体就不发出来了(偏移还在),如果各位感兴趣可以自己进行逆向 还原

DWORD add(DWORD a, DWORD b)
{
    DWORD dwRet = a + b;
    return dwRet;
}
DWORD add(DWORD a, DWORD b)
{
    DWORD dwRet = a + b;
    return dwRet;
}
mov eax, [ebp + a]
add eax, [ebp + b]
mov eax, [ebp + a]
add eax, [ebp + b]
; if (a >= 0)
; {
;       printf("hello world");
;   }
mov edx, [a]
test edx, edx
jns xxxx ; 这里会取反
  ; 这里则是语句块中的代码
  push str_xxx ;HelloWorld
  call subxxxxx;printf
  add esp, 8; 平栈
xxxx:
  ;这里一般为后面的代码
; if (a >= 0)
; {
;       printf("hello world");
;   }
mov edx, [a]
test edx, edx
jns xxxx ; 这里会取反
  ; 这里则是语句块中的代码
  push str_xxx ;HelloWorld
  call subxxxxx;printf
  add esp, 8; 平栈
xxxx:
  ;这里一般为后面的代码
typedef struct _SYSTEM_BASIC_INFORMATION {
    ULONG Reserved;                     // 保留字段,通常为 0
    ULONG TimerResolution;              // 系统定时器的分辨率(以微秒为单位)
    ULONG PageSize;                     // 页面大小(以字节为单位)
    ULONG NumberOfPhysicalPages;        // 物理页面的数量
    ULONG LowestPhysicalPageNumber;     // 物理页面的最低编号
    ULONG HighestPhysicalPageNumber;    // 物理页面的最高编号
    ULONG AllocationGranularity;        // 内存分配粒度
    ULONG MinimumUserModeAddress;       // 用户模式下的最小地址
    ULONG MaximumUserModeAddress;       // 用户模式下的最大地址
    ULONG ActiveProcessorsAffinityMask; // 活动处理器的亲和性掩码
    UCHAR NumberOfProcessors;           // 处理器的数量
} SYSTEM_BASIC_INFORMATION;
 
 
 
/*
* Flags : 指定堆的可选属性的标志。
这些选项会影响通过调用堆函数(RtlAllocateHeap和RtlFreeHeap)对新堆的后续访问。
    一共有3个值
    1. HEAP_GENERATE_EXCEPTIONS 指定系统引发异常而不是通过返回空值即异常堆
    2. HEAP_GROWABLE 可增长堆如果HeapBase为空必须指定
    3. HEAP_NO_SERIALIZE 指定当堆函数从此堆分配和释放内存时不使用互斥。
                        当未指定 HEAP_NO_SERIALIZE 时,默认是序列化对堆的访问。
                        序列化堆访问允许两个或多个线程同时从同一堆分配和释放内存。
* HeapBase: 非空情况下就是将指定分配的地址,如果空的情况下则会在进程空间随机分配
* ReserveSize:
*
*
*/
 
ULONG g_initVar1ByInitalizeProccess = 0;
ULONG g_initVar2ByAvrfLoadDll = 0;
typedef  int(__thiscall* PFN_4B3A32F4)(DWORD, DWORD, DWORD, DWORD, DWORD, PVOID);
 
PFN_4B3A32F4 g_4B3A32F4;
 
 
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
)
{
    DWORD var_12C;
    DWORD var_120;
    DWORD var_110[10];
    PVOID pLock = Lock;
    ULONG ulFlags = Flags;
    PVOID pBase = HeapBase;
    PVOID pBase2 = HeapBase;
    SIZE_T stReserver = ReserveSize;
    DWORD var_BC;
    SIZE_T stCommit = CommitSize;
    PVOID pLock2 = Lock;
    DWORD var_CC;
    DWORD CriticalSectionFlag;
    DWORD var_D8;
    DWORD BaseAddress;
    BOOL ntGlobalFlag = ((PPEB)__readfsdword(0x30))->NtGlobalFlag;
    ULONG ulUnknow1 = 0;
    DWORD dwRegionSize = 0;
    ULONG ulUnknow2 = 0;
    ULONG ulUnknow3 = 0;
    DWORD pHeapHandle2;
    BYTE var_A8[0x30];
    DWORD dwCommiteSize;
 
    SYSTEM_BASIC_INFORMATION SystemInformation;
    DWORD var_58;
    CPPEH_RECORD ms_exc;
    // 模拟组
    DWORD eax = 0;
    DWORD ecx = 0;
    DWORD edx = (DWORD)Flags;
    DWORD ebx = 0;
    DWORD esi = 0;
    DWORD edi = (DWORD)Parameters;
 
    // 进程默认堆
    if (g_initVar1ByInitalizeProccess != NULL
        && pBase == NULL
        && pLock == NULL)
    {
        // 不允许应用程序更改策略
        RtlpHpAppCompatDontChangePolicy();
        // 如果用户设置了Commit指针则通过Commit指针来获取堆结果
        esi = g_4B3A32F4(ulFlags, 0, stReserver, stCommit, 0, Parameters);
        if (esi != 0)
        {
            goto RELEASE_SRC;
        }
        if (edi != 0xFFFFFFFF)
        {
            edi = (DWORD)pBase;
            esi = 0;
            goto RELEASE_SRC;
        }
    }
    else
    {
        if (g_initVar2ByAvrfLoadDll != 0
            && (DWORD)Parameters == 1)
        {
            /*
            mov     eax, edx
            and     eax, 100h       ; if ((eax & 100h) != 0)
                                    ; eax = 100h
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0
            neg     eax             ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0
            sbb     eax, eax        ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0
            not     eax             ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1 -> 0
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0 -> -1
            and     edi, eax        ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1 -> 0 -> 0
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0 -> -1 -> edi
            */
            edi = (edx & 100) == 0 ? 0 : edi;
 
        }
 
    }
    //edx = edx & 0xF1FFFFFF;
    ulFlags = ulFlags & 0xF1FFFFFF;
 
    if ((ulFlags & 0x100) != 0)
    {
        if (!(LOWORD(ulFlags) & 2)
            || (DWORD)pBase != ebx
            || ecx
            || stCommit != ebx
            || (DWORD)pLock != ebx)
        {
            goto RELEASE_SRC;
        }
 
        if (edi == 0xFFFFFFFF)
        {
            edi = !g_initVar2ByAvrfLoadDll ? 0 : edi;
        }
        if (edi != 0)
        {
            esi = edi;
            // 参数的验证
            if (!RtlpHpParametersVerify(edi))
            {
                // goto
 
            }
            edx = ulFlags;
        }
        else
        {
            esi = pHeapHandle2;
        }
 
    }
    else if (_RtlpHpHeapFeatures != 1)
    {
        if (((((LOWORD(edx) & 2)
            && (DWORD)pBase == ebx))
            // 判断堆参数是否支持
            && RtlpHpParametersSupported(edi))
            || edi == 0
            )
        {
            eax = 2;
            if ((DWORD)pLock2 == ebx)
            {
                esi = (DWORD)&pHeapHandle2;
            }
 
        }
    }
 
    if (esi != 0)
    {
        eax = (DWORD)&pHeapHandle2;
        if (esi == eax)
        {
            memset((PBYTE)esi, 0, 0x30u);
            *(WORD*)esi = 2;
            *(WORD*)((BYTE*)esi + 2) = 0x30;
            *(DWORD*)((BYTE*)esi + 0xC) = 1;
            *(DWORD*)((BYTE*)esi + 0x10) |= 0xFFFFFFFF;
        }
        if ((*((BYTE*)(esi + 0x4)) & 1))
        {
            if (g_initVar2ByAvrfLoadDll == 0)
            {
                esi = 0;
                goto RELEASE_SRC;
            }
            RtlpHpAppCompatDontChangePolicy();
            esi = g_4B3A32F4(ulFlags, 0, stReserver, stCommit, 0, Parameters);
            goto RELEASE_SRC;
        }
        else
        {
            eax = (DWORD)RtlpHpEnvGetEnvHandleFromParams(esi);
            edi = (DWORD)stReserver;
            if (edi == 0) // 如果Reserver 是0则给出Commit的大小
            {
                edi = stCommit;
            }
 
            if (eax > edi)
            {
                eax = edi;
            }
 
            // 通过RtlpHpHeapCreate创建堆然后将堆移动到堆链表中去
            if (!RtlpHpHeapCreate(
                RtlpHpConvertCreationFlags(ulFlags,
                    ntGlobalFlag),
                edi,
                eax,
                ecx,
                edx))
            {
                goto RELEASE_SRC;
            }
            // 移动链表
            RtlpMoveHeapBetweenLists(esi, edx, 1, ebx);
            if (*(WORD*)(esi + 0x14) == LOWORD(ebx))
            {
                goto RELEASE_SRC;
            }
 
            RtlpHpHeapDestroy(esi);
            esi = ebx;
            goto RELEASE_SRC;
 
        }
 
    }
 
    if (!(ulFlags & 0x10000000))
    {
        if (_RtlpHeapErrorHandlerThreshold >= 2
            && (ulFlags & 0xFFF80C00))
        {
            if (((PPEB)__readfsdword(0x30))->Ldr)
            {
                //_DbgPrint();
                // 这里正常来讲应该是一个结构体而不是强转 + 偏移
                // 但是为了赶项目进度暂时翻译为偏移的形式
                printf("HEAP[%wZ]: ", *(DWORD*)(*(DWORD*)(__readfsdword(0x30) + 0xc) + 0xc) + 0x2c);
            }
            else
            {
                // dbg p
                printf("HEAP: ");
            }
            // dbg p
            printf("!(CheckedFlags & ~HEAP_CREATE_VALID_MASK)");
 
            //
            if (byte_4B3A5DA8 == 0)
            {
                RtlpReportHeapFailure(2);
            }
            //edx = ulFlags;
        }
        /*if (edx & 0xFFF80C00)
        {
            edx &= 0x7F3FF;
        }*/
        if (ulFlags & 0xFFF80C00)
        {
            ulFlags &= 0x7F3FF;
        }
    }
    // ebx 万年老0, 这里推断var_A8是个结构体
    // 或许初始化为 STRUCT var_A8 { 0 };
    // 不过考虑到WINDOWS是C语言开发的
    // 也不清楚微软内部编译器支持的语言规范版本
    // 暂时设置为memset
    memset(var_A8, 0, 0x30);
 
    if (edi != 0)
    {
        // 这里对SEH进行一些设置
        ms_exc.registration.TryLevel = 0;
        if (edi == esi)
        {
            memcpy((PBYTE)edi, var_A8, 0xc);
        }
        ms_exc.registration.TryLevel = 0xFFFFFFFE;
    }
    // 这里的汇编为test    cl, 20h 但是ntGlobalFlag
    // 4字节我不想翻译为强转只能祈祷编译器对取低位有优化
    if (ntGlobalFlag & 0xff & 0x10)
    {
        ulFlags |= 0x20;
    }
 
    if (ntGlobalFlag & 0xff & 0x20)
    {
        ulFlags |= 0x40;
    }
 
    if (ntGlobalFlag & 0x200000)
    {
        ulFlags |= 0x80;
    }
 
    if (ntGlobalFlag & 0xff & 0x40)
    {
        ulFlags |= 0x40000000;
    }
 
 
    if (ntGlobalFlag & 0xff & 0x80)
    {
        ulFlags |= 0x20000000;
    }
 
 
    if (ntGlobalFlag & 0x1000)
    {
        ulFlags |= 0x8000000;
    }
 
    ecx = __readfsdword(0x30);
 
    // 这里的var_a8应该是个结构体之后要改一下可以通过PEB的成员反推
    // var_a8的成员
    if (!var_A8[1])
    {
        var_A8[1] = *(DWORD*)(ecx + 0x78);
    }
    if (!var_A8[2])
    {
        var_A8[2] = *(DWORD*)(ecx + 0x7c);
    }
    if (!var_A8[3])
    {
        var_A8[3] = *(DWORD*)(ecx + 0x84);
    }
    if (!var_A8[4])
    {
        var_A8[4] = *(DWORD*)(ecx + 0x80);
    }
 
    if (!dword_4B3A6940)
    {
        dword_4B3A6944 = 0x10000;
        // 首先是查询系统信息
        if (NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS::SystemBasicInformation,
            &SystemInformation, 0x2c, 0) < 0)
        {
            goto RELEASE_SRC;
        }
        dword_4B3A6940 = var_58;
        edx = 0x1000;
    }
    // 接下来是对页段的操作
    // 貌似这里是在对页进行处理-0x1000的操作正是在将
    // 前面的设置为页首
    if (!var_A8[5])
    {
        var_A8[5] = dword_4B3A6940 - dword_4B3A6944 - 0x1000;
    }
    // 最大值为0x7F000
    if (!var_A8[6] || var_A8[6] > 0x7F000)
    {
        var_A8[6] = 0x7F000;
    }
 
    // 加了一些什么值
    if (stCommit)
    {
        stCommit = (stCommit + 0xFFF) & 0xFFFFF000;
    }
 
    /*edi = stReserver;
    if (edi != 0)
    {
        ecx = edi + 0XFFF;
        ecx &= 0xFFFFF000;
        var_BC = ecx;
    }*/
    if (stReserver)
    {
        var_BC = (stReserver + 0xFFF) & 0xFFFFF000;
    }
    else
    {
        var_BC = (stCommit + 0xFFFF) & 0xFFFF0000;
    }
 
    /*
     mov     [ebp+var_BC], ecx ; ecx = var_BC
     mov     esi, edx        ; edx = dwCommiteSize
                             ; esi = dwCommiteSize
     cmp     edx, ecx
     ja      markif19
    */
 
    // 计算得到最大堆块大小:最大堆块大小实际上是 0x7f000,即 0x80000 减去一个页面。
    // 最大块大小为 0xfe00,粒度偏移为 3
    if (stCommit > var_BC)
    {
        stCommit = var_BC;
        esi = var_BC;
    }
    //获取传入的堆参数块,根据PEB设置堆参数块的值,
    // 根据PEB->NtGlobalFlag设置堆块的标志
    // ebx = 0
    if (!(ulFlags & 0xff & 2) && pBase != NULL)
    {
        ntGlobalFlag = 0;
    }
    else
    {
        ntGlobalFlag = 0x1000;
        ulUnknow1 = 2;
        //eax = var_BC - 0x1000;
        if (stCommit < var_BC - 0x1000)
        {
            var_BC = (var_BC + 0x10fff) & 0xffff0000;
        }
    }
 
    if (!stCommit || !var_BC)
    {
        esi = 0;
        goto RELEASE_SRC;
    }
 
    // 返回调试堆
    if (ulFlags & 0x61000000)
    {
        if (!(ulFlags & 0x10000000))
        {
                return (PVOID)RtlDebugCreateHeap(ulFlags, pBase, var_BC, stCommit, pLock2, &var_A8);
        }
    }
 
    stReserver = 0x258;
    if (!(ulFlags & 0xff & 1))
    {
        if (pLock2)
        {
            ulFlags |= 0x80000000;
        }
        CriticalSectionFlag = (DWORD)(pLock2 ? pLock2 : 0);
        stReserver = !pLock2 ? 0x270 : 0x252;
    }
    else
    {
        if (pLock2 != 0)
        {
            esi = 0;
            goto RELEASE_SRC;
        }
    }
 
    // 如果调用者提供的堆基地址为0,调用ZwAllocateVirtualMemory从内存管理器分配内存
    if (pBase == 0)
    {
        BaseAddress = 0;
        if (var_A8[9] != (DWORD)pBase)
        {
            esi = 0;
            goto RELEASE_SRC;
        }
        pLock = (PVOID)RtlpHeapGenerateRandomValue32();
 
        var_BC = ebx;
        // eax = RtlpSecMemFreeVirtualMemory(ecx, edx, &var_BC, 0x8000)
        // | BaseAddress & 0x1f << 0x10;
        var_D8 = RtlpHeapGenerateRandomValue32()
            | BaseAddress & 0x1f << 0x10;
 
        dwRegionSize = var_D8 + var_BC;
 
        if (dwRegionSize < var_BC)
        {
            dwRegionSize = var_BC;
            var_D8 = BaseAddress;
        }
 
         
        if (NtAllocateVirtualMemory(-1,
            &BaseAddress,
            0,
            &dwRegionSize,
            0x2000,
            (ulFlags & 0x40000) == 0 ? 4 : 64) < 0)
        {
            esi = 0;
            goto RELEASE_SRC;
        }
         
        pHeapHandle2 = BaseAddress;
        var_BC = dwRegionSize;
        if (var_D8 != 0)
        {
            RtlpSecMemFreeVirtualMemory(var_BC, &BaseAddress, &var_D8, 0x8000);
            pHeapHandle2 = BaseAddress + var_D8;
            var_BC = dwRegionSize - var_D8;
        }
        var_CC = BaseAddress + var_D8;
        stCommit = BaseAddress + var_D8;
    }
    else
    {
        if (var_A8[0] != 0)
        {
            if (var_A8[6] == 0 || var_A8[7] == 0 || var_A8[6] > var_A8[7] || ulFlags & 0xff != 2)
            {
                esi = 0;
                goto RELEASE_SRC;
            }
            var_CC = (DWORD)pBase;
            stCommit = (DWORD)pBase + (DWORD)pLock2;
            var_BC = var_A8[7];
            memset(pBase, 0, 0x1000);
            esi = ulFlags;
        }
        else
        {
            //pBase2需要切换为结构体
 
            if (NtQueryVirtualMemory(-1, pBase, 0, &var_110, 0x1c, 0) < 0
                || var_110[0] != stCommit
                || var_110[3] == 0x10000)
            {
                esi = 0;
                goto RELEASE_SRC;
            }
            // 根据传入的ReserveSize和CommitSize设置堆块的保留页面和提交页面
            var_CC = (DWORD)var_110;
            if (var_110[3] == 0x1000)
            {
                var_BC = var_110[2];
                if (stCommit > var_BC)
                {
                    stCommit = var_BC;
                }
                if (stCommit < 0x1000)
                {
                    esi = 0;
                    goto RELEASE_SRC;
                }
                esi = ulFlags;
            }
            else
            {
                if ((ulFlags & 0x40000))
                {
                    if (var_110[4] & 0x40)
                    {
                        goto RELEASE_SRC;
                    }
                }
                // 此时,已获得一个堆指针、已提交的基址、未提交的基址、段标志、
                // 提交大小和保留大小。
                // 如果已提交和未提交的基地址相同,那么我们需要调用ZwAllocateVirtualMemory提交由ComitSize指定的数量
                memset(var_110, 0, 0x1000);
                if (NtQueryVirtualMemory(-1, pBase, 3, &var_12C, 0x1c, 0) < 0)
                {
                    esi = 0;
                    goto RELEASE_SRC;
                }
 
                var_BC = var_120;
                stCommit = var_110[2];
                dwCommiteSize = stCommit + var_CC;
            }
 
        }
        var_110[10] |= 1;
        pHeapHandle2 = (DWORD)pBase;
        ulFlags &= 0x40000;
        ecx = stCommit;
        eax = var_CC;
    }
    // edi = pBase
    if (var_CC == stCommit)
    {
        if (NtAllocateVirtualMemory(-1, &var_CC, 0, &dwCommiteSize, 0x1000, (ulFlags & 40000) == 0 ? 4 : 64) < 0)
        {
            esi = 0;
            goto RELEASE_SRC;
        }
 
        if (RtlGetCurrentServiceSessionId())
        {
            eax = __readfsdword(0x30);
            ecx = *(DWORD*)(eax + 0x50);
            ecx += 0x226;
        }
        else
        {
            // 从这里进入0
            ecx = 0x7FFE0380;
        }
        if (*(BYTE*)ecx != 0)
        {
            if (*(BYTE*)(__readfsdword(0x30) + 0x240) != 1)
            {
                RtlpLogHeapCommit(pHeapHandle2, var_CC, dwCommiteSize, 1);
            }
        }
        stCommit = stCommit + dwCommiteSize;
 
    }
 
 
    // edi = HeapHandle + 258h
    if (*(DWORD*)(__readfsdword(0x30) + 0x68) != 0x800)
    {
        /*
        ;ecx = *(DWORD*)(pHeapHandle2 + 0x258 + 0x7) & 0xFFFFFFF8;
        *(DWORD*)(pHeapHandle2 + 0xBC) = ecx;
        stReserver = ecx;
        edi = *(DWORD*)(pHeapHandle2 + 0xBC) + ecx;
        ulFlags |= 0x4000000;
        esi = ulFlags;
        */
        *(DWORD*)(pHeapHandle2 + 0xBC) = *(DWORD*)(pHeapHandle2 + 0x258 + 0x7) & 0xFFFFFFF8;
        stReserver = *(DWORD*)(pHeapHandle2 + 0x258 + 0x7) & 0xFFFFFFF8;
        edi = *(DWORD*)(pHeapHandle2 + 0xBC) + *(DWORD*)(pHeapHandle2 + 0x258 + 0x7) & 0xFFFFFFF8;;
        ulFlags |= 0x4000000;
        esi = ulFlags;
 
    }
    var_110[9] = (stReserver + 7) & 0xFFFFFFF8;
    // ecx = var_110[9] / 8;
    *(WORD*)pHeapHandle2 = var_110[9] / 8;
    *(WORD*)(pHeapHandle2 + 2) = 1;
    *(WORD*)(pHeapHandle2 + 7) = 1;
    *(DWORD*)(pHeapHandle2 + 0x60) = 0xEEFFEEFF;
    *(DWORD*)(pHeapHandle2 + 0x40) = ulFlags & 0xEFFFFFFF;
    *(DWORD*)(pHeapHandle2 + 0x58) = 0;
    memset((BYTE*)pHeapHandle2 + 0x1F4, 0, 0x5C);
    // 实际上这里的参数应该为 *_HEAP_HANDLE
    // 这里是对堆头进行加密
    RtlpCreateHeapEncoding((PVOID)pHeapHandle2);
    *(DWORD*)(pHeapHandle2 + 0x234) = 1;
 
    if (*(DWORD*)(pHeapHandle2 + 0x40) & 0x8000000)
    {
        // 这里或许是获取拦截器索引
        /*
            基于此猜测我们给出如下的一些定义
            typedef DWORD(__stdcall* INTERCEPTOR_PFN)(DWORD, DWORD, DWORD, DWORD);
 
            DWORD
            NTAPI
            RtlpGetHeapInterceptorIndex(INTERCEPTOR_PFN);
 
            INTERCEPTOR_PFN RtlpStackTraceDatabaseLogPrefix;
 
        */
        /*
          mov     ecx, offset _RtlpStackTraceDatabaseLogPrefix@16 ; RtlpStackTraceDatabaseLogPrefix(x,x,x,x)
          call    _RtlpGetHeapInterceptorIndex@4 ; RtlpGetHeapInterceptorIndex(x)
          movzx   eax, ax 值得注意的是这里用了movzx但是对于movzx来讲是取用了低位所以我们有必要考虑
          // 返回的是一个4字节的结构体而非一个DWORD,但是我们不知道语义所以这里给出LOWORD来取代结构体
          mov     [esi+58h], eax
        */
         
        *(DWORD*)(pHeapHandle2 + 0x58) = (DWORD)LOWORD(RtlpGetHeapInterceptorIndex(RtlpStackTraceDatabaseLogPrefix));
        *(DWORD*)(pHeapHandle2 + 0x40) = 0xFFFFFFBF;
    }
    *(DWORD*)(pHeapHandle2 + 0x44) = ulFlags & 0x6001007D;
    // 这里的还原存疑
    /*
    edi 来源
    lea     edi, [edx+258h] ; edx = heapHandle
    ...
     mov     ecx, edi ; edi = heapHandle + 0x258
     mov     eax, [ebp+HeapHandle]
     sub     ecx, eax ; ecx = 0x258
     mov     [eax+7Eh], cx
        mov     eax, [ebp+HeapHandle]
    */
    *(WORD*)(pHeapHandle2 + 0x7E) = LOWORD(0x258);
    // ebx 万年老0
    *(DWORD*)(pHeapHandle2 + 0x80) = 0;
     
     
    //eax = pHeapHandle2 + 0xc0;
    //*(DWORD*)(eax + 4) = eax;
    *(DWORD*)(pHeapHandle2 + 0xc4) = pHeapHandle2 + 0xc0;
    *(DWORD*)(pHeapHandle2 + 0xc0) = pHeapHandle2 + 0xc0;
     
 
 
    //eax = pHeapHandle2 + 0x9c;
    //*(DWORD*)(eax + 4) = eax;
    //*(DWORD*)(eax) = eax;
    *(DWORD*)(pHeapHandle2 + 0x9c + 4) = pHeapHandle2 + 0x9c;
    *(DWORD*)(pHeapHandle2 + 0x9c) = pHeapHandle2 + 0x9c;
 
    *(DWORD*)(pHeapHandle2 + 0xA4 + 4) = pHeapHandle2 + 0xA4;
    *(DWORD*)(pHeapHandle2 + 0xA4) = pHeapHandle2 + 0xA4;
 
    *(DWORD*)(pHeapHandle2 + 0x8C + 4) = pHeapHandle2 + 0x8C;
    *(DWORD*)(pHeapHandle2 + 0x8C) = pHeapHandle2 + 0x8C;
 
    if (!CriticalSectionFlag && !(ulFlags & 0xff & 1))
    {
        //CriticalSectionFlag = edi;
        CriticalSectionFlag = pHeapHandle2 + 0x258;
        if (RtlInitializeCriticalSectionEx(CriticalSectionFlag, 0, 0x10000000) < 0)
        {
 
            //return 0;
            esi = 0;
            goto RELEASE_SRC;
        }
        edi += 0x18;
        ecx = CriticalSectionFlag;
    }
    *(DWORD*)(pHeapHandle2 + 0xC8) = CriticalSectionFlag;
    *(DWORD*)(pHeapHandle2 + 0x48) |= 0x80000000;
 
 
    if (!(RtlpInitializeHeapSegment(pHeapHandle2,
        pHeapHandle2,
        var_110[9] + 0x238,
        CriticalSectionFlag,
        var_110[0xA],
        var_CC,
        stCommit,
        var_CC - var_110[0xE] + var_BC) & 0xff))
    {
        esi = 0;
        goto RELEASE_SRC;
    }
    esi = 0x80;
    if (pBase != 0)
    {
        memset((BYTE*)pHeapHandle2 + 0x258 + 0x18, 0, 0x80);
    }
    *(DWORD*)(pHeapHandle2 + 0x258 + 0x4) = 0x80;
    *(DWORD*)(pHeapHandle2 + 0x258 + 0x1c) = pHeapHandle2 + 0x258 + 0x24;
    *(DWORD*)(pHeapHandle2 + 0x258 + 0x18) = pHeapHandle2 + 0xc0;
    *(DWORD*)(pHeapHandle2 + 0x258 + 0x20) = pHeapHandle2 + 0x258 + 0x24 + 0x10;
 
    RtlpPopulateListIndex(pHeapHandle2, pHeapHandle2 + 0x258);
    *(WORD*)(pHeapHandle2 + 0x7c) = 0;
    *(DWORD*)(pHeapHandle2 + 0x64) = var_A8[0];
    *(DWORD*)(pHeapHandle2 + 0x68) = var_A8[1];
    *(DWORD*)(pHeapHandle2 + 0x6c) = var_A8[2] / 8;
    *(DWORD*)(pHeapHandle2 + 0x70) = var_A8[3] / 8;
    *(DWORD*)(pHeapHandle2 + 0x78) = var_A8[4] / 8;
    *(DWORD*)(pHeapHandle2 + 0x5c) = (var_A8[5] + 7) / 8;
    *(DWORD*)(pHeapHandle2 + 0xcc) = (var_A8[8] ^ _RtlpHeapKey);
    *(DWORD*)(pHeapHandle2 + 0x250) = 4;
    *(DWORD*)(pHeapHandle2 + 0x254) = 0xFE000;
 
    if (_RtlpDisableHeapLookaside != 1)
    {
        //test    byte ptr _RtlpDisableHeapLookaside, dl
        *(DWORD*)(pHeapHandle2 + 0x48) = 1;
    }
 
    if (!(ulFlags & 0x10000))
    {
        *(DWORD*)(pHeapHandle2 + 0x94) = 0xf;
        *(DWORD*)(pHeapHandle2 + 0x98) = 0xFFFFFFF8;
    }
 
    if (*(DWORD*)(pHeapHandle2 + 0x40) & 0x20)
    {
        *(DWORD*)(pHeapHandle2 + 0x94) += 8;
    }
    *(DWORD*)(pHeapHandle2 + 0xE4) = 0;
    *(WORD*)(pHeapHandle2 + 0xE8) = 0;
    *(WORD*)(pHeapHandle2 + 0xEA) = 0;
    *(WORD*)(pHeapHandle2 + 0xEB) = 0;
    *(DWORD*)(pHeapHandle2 + 0xE8) = 0;
 
    // 根据快表的标志初始化块表
    if (((ulFlags & 3) == 2) && ((_RtlpDisableHeapLookaside & 1) == 0))
    {
        *(DWORD*)(pHeapHandle2 + 0xEC) = RtlAllocateHeap((PMY_HEAPSTRUCT)pHeapHandle2, 0x80000A, 0x100);
        if (!(*(DWORD*)(pHeapHandle2 + 0xEC)))
        {
            goto RELEASE_SRC;
        }
        *(BYTE*)(pHeapHandle2 - 1) = 1;
        *(BYTE*)(pHeapHandle2 + 0xf0) = 0x80;
    }
     
    // 函数指针传入
    /*
    * 暂时给出如下定义
        typedef DWORD(__stdcall*RtlpProcessHeapsListLock_PFN)();
 
        DWORD
        NTAPI
        RtlEnterCriticalSection(RtlpProcessHeapsListLock_PFN);
 
        RtlpProcessHeapsListLock_PFN _RtlpProcessHeapsListLock;
     
    */
    RtlEnterCriticalSection(_RtlpProcessHeapsListLock);
    // 添加堆到链表
    RtlpAddHeapToUnprotectedList(pHeapHandle2);
 
    // 离开临界区
    RtlLeaveCriticalSection(_RtlpProcessHeapsListLock);
     
 
    if (!*(DWORD*)(pHeapHandle2 + 0x7c))
    {
        esi = 0;
        goto RELEASE_SRC;
    }
    if (RtlGetCurrentServiceSessionId())
    {
        eax = __readfsdword(0x30);
        eax = *(DWORD*)(eax + 0x50);
        eax += 0x226;
    }
    else
    {
        eax = 0x7FFE0380;
    }
 
    if (*(BYTE*)eax != 0 && (*(BYTE*)(__readfsdword(0x30) + 0x240) & 1))
    {
        if (RtlGetCurrentServiceSessionId())
        {
            esi = *(DWORD*)(__readfsdword(0x30) + 0x50) + 0x226;
        }
        RtlpLogHeapCreateEvent(pHeapHandle2, ulFlags, var_BC, dwCommiteSize, (DWORD) * (BYTE*)esi);
    }
    else
    {
        esi = ulFlags;
    }
 
    if (RtlGetCurrentServiceSessionId())
    {
        eax = __readfsdword(0x30);
        eax = *(DWORD*)(eax + 0x50);
        eax += 0x230;
    }
    else
    {
        eax = 0x7FFE0388;
    }
 
    if (*(BYTE*)eax != 0)
    {
        // 记录创建的堆范围
        RtlpHeapLogRangeCreate(pHeapHandle2, var_BC, ulFlags);
    }
 
    *(DWORD*)(pHeapHandle2 + 0x48) &= 0x7FFFFFFF;
    *(DWORD*)(pHeapHandle2 + 0xd0) = 0;
    esi = pHeapHandle2; // 返回值
    pHeapHandle2 = 0;
    CriticalSectionFlag = 0;
 
    /*
    *
    这里为统一出口用于释放资源与返回值
    此函数返回值为HeapHandle
    */
 
RELEASE_SRC:
    // todo
    edi = (DWORD)pBase;
    edx = (DWORD)pLock2;
    eax = ulUnknow3;
    if (eax != 0
        && eax != edx)
    {
        RtlDeleteCriticalSection(eax);
    }
 
    if (ulUnknow2 != 0
        && edi == 0)
    {
        var_BC = 0;
        // eax = RtlpSecMemFreeVirtualMemory(ecx, edx, &var_BC, 0x8000)
        // | BaseAddress & 0x1f << 0x10;
        var_D8 = RtlpSecMemFreeVirtualMemory(ecx, (PVOID)edx, &var_BC, 0x8000)
            | BaseAddress & 0x1f << 0x10;
 
 
    }
RET:
    return (PVOID)esi;
}
typedef struct _SYSTEM_BASIC_INFORMATION {
    ULONG Reserved;                     // 保留字段,通常为 0
    ULONG TimerResolution;              // 系统定时器的分辨率(以微秒为单位)
    ULONG PageSize;                     // 页面大小(以字节为单位)
    ULONG NumberOfPhysicalPages;        // 物理页面的数量
    ULONG LowestPhysicalPageNumber;     // 物理页面的最低编号
    ULONG HighestPhysicalPageNumber;    // 物理页面的最高编号
    ULONG AllocationGranularity;        // 内存分配粒度
    ULONG MinimumUserModeAddress;       // 用户模式下的最小地址
    ULONG MaximumUserModeAddress;       // 用户模式下的最大地址
    ULONG ActiveProcessorsAffinityMask; // 活动处理器的亲和性掩码
    UCHAR NumberOfProcessors;           // 处理器的数量
} SYSTEM_BASIC_INFORMATION;
 
 
 
/*
* Flags : 指定堆的可选属性的标志。
这些选项会影响通过调用堆函数(RtlAllocateHeap和RtlFreeHeap)对新堆的后续访问。
    一共有3个值
    1. HEAP_GENERATE_EXCEPTIONS 指定系统引发异常而不是通过返回空值即异常堆
    2. HEAP_GROWABLE 可增长堆如果HeapBase为空必须指定
    3. HEAP_NO_SERIALIZE 指定当堆函数从此堆分配和释放内存时不使用互斥。
                        当未指定 HEAP_NO_SERIALIZE 时,默认是序列化对堆的访问。
                        序列化堆访问允许两个或多个线程同时从同一堆分配和释放内存。
* HeapBase: 非空情况下就是将指定分配的地址,如果空的情况下则会在进程空间随机分配
* ReserveSize:
*
*
*/
 
ULONG g_initVar1ByInitalizeProccess = 0;
ULONG g_initVar2ByAvrfLoadDll = 0;
typedef  int(__thiscall* PFN_4B3A32F4)(DWORD, DWORD, DWORD, DWORD, DWORD, PVOID);
 
PFN_4B3A32F4 g_4B3A32F4;
 
 
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
)
{
    DWORD var_12C;
    DWORD var_120;
    DWORD var_110[10];
    PVOID pLock = Lock;
    ULONG ulFlags = Flags;
    PVOID pBase = HeapBase;
    PVOID pBase2 = HeapBase;
    SIZE_T stReserver = ReserveSize;
    DWORD var_BC;
    SIZE_T stCommit = CommitSize;
    PVOID pLock2 = Lock;
    DWORD var_CC;
    DWORD CriticalSectionFlag;
    DWORD var_D8;
    DWORD BaseAddress;
    BOOL ntGlobalFlag = ((PPEB)__readfsdword(0x30))->NtGlobalFlag;
    ULONG ulUnknow1 = 0;
    DWORD dwRegionSize = 0;
    ULONG ulUnknow2 = 0;
    ULONG ulUnknow3 = 0;
    DWORD pHeapHandle2;
    BYTE var_A8[0x30];
    DWORD dwCommiteSize;
 
    SYSTEM_BASIC_INFORMATION SystemInformation;
    DWORD var_58;
    CPPEH_RECORD ms_exc;
    // 模拟组
    DWORD eax = 0;
    DWORD ecx = 0;
    DWORD edx = (DWORD)Flags;
    DWORD ebx = 0;
    DWORD esi = 0;
    DWORD edi = (DWORD)Parameters;
 
    // 进程默认堆
    if (g_initVar1ByInitalizeProccess != NULL
        && pBase == NULL
        && pLock == NULL)
    {
        // 不允许应用程序更改策略
        RtlpHpAppCompatDontChangePolicy();
        // 如果用户设置了Commit指针则通过Commit指针来获取堆结果
        esi = g_4B3A32F4(ulFlags, 0, stReserver, stCommit, 0, Parameters);
        if (esi != 0)
        {
            goto RELEASE_SRC;
        }
        if (edi != 0xFFFFFFFF)
        {
            edi = (DWORD)pBase;
            esi = 0;
            goto RELEASE_SRC;
        }
    }
    else
    {
        if (g_initVar2ByAvrfLoadDll != 0
            && (DWORD)Parameters == 1)
        {
            /*
            mov     eax, edx
            and     eax, 100h       ; if ((eax & 100h) != 0)
                                    ; eax = 100h
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0
            neg     eax             ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0
            sbb     eax, eax        ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0
            not     eax             ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1 -> 0
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0 -> -1
            and     edi, eax        ; if ((eax & 100h) != 0)
                                    ; eax = 100h -> FFFF FEFF -> -1 -> 0 -> 0
                                    ; if ((eax & 100h) == 0)
                                    ; eax = 0 -> 0 -> 0 -> -1 -> edi
            */
            edi = (edx & 100) == 0 ? 0 : edi;
 
        }
 
    }
    //edx = edx & 0xF1FFFFFF;
    ulFlags = ulFlags & 0xF1FFFFFF;
 
    if ((ulFlags & 0x100) != 0)
    {
        if (!(LOWORD(ulFlags) & 2)
            || (DWORD)pBase != ebx
            || ecx
            || stCommit != ebx
            || (DWORD)pLock != ebx)
        {
            goto RELEASE_SRC;
        }
 
        if (edi == 0xFFFFFFFF)
        {
            edi = !g_initVar2ByAvrfLoadDll ? 0 : edi;
        }
        if (edi != 0)
        {
            esi = edi;
            // 参数的验证
            if (!RtlpHpParametersVerify(edi))
            {
                // goto
 
            }
            edx = ulFlags;
        }
        else
        {
            esi = pHeapHandle2;
        }
 
    }
    else if (_RtlpHpHeapFeatures != 1)
    {
        if (((((LOWORD(edx) & 2)
            && (DWORD)pBase == ebx))
            // 判断堆参数是否支持
            && RtlpHpParametersSupported(edi))
            || edi == 0
            )
        {
            eax = 2;
            if ((DWORD)pLock2 == ebx)
            {
                esi = (DWORD)&pHeapHandle2;
            }
 
        }
    }
 
    if (esi != 0)
    {
        eax = (DWORD)&pHeapHandle2;
        if (esi == eax)
        {
            memset((PBYTE)esi, 0, 0x30u);
            *(WORD*)esi = 2;
            *(WORD*)((BYTE*)esi + 2) = 0x30;
            *(DWORD*)((BYTE*)esi + 0xC) = 1;
            *(DWORD*)((BYTE*)esi + 0x10) |= 0xFFFFFFFF;
        }
        if ((*((BYTE*)(esi + 0x4)) & 1))
        {
            if (g_initVar2ByAvrfLoadDll == 0)
            {
                esi = 0;
                goto RELEASE_SRC;
            }
            RtlpHpAppCompatDontChangePolicy();
            esi = g_4B3A32F4(ulFlags, 0, stReserver, stCommit, 0, Parameters);
            goto RELEASE_SRC;
        }
        else
        {
            eax = (DWORD)RtlpHpEnvGetEnvHandleFromParams(esi);
            edi = (DWORD)stReserver;
            if (edi == 0) // 如果Reserver 是0则给出Commit的大小
            {
                edi = stCommit;
            }
 
            if (eax > edi)
            {
                eax = edi;
            }
 
            // 通过RtlpHpHeapCreate创建堆然后将堆移动到堆链表中去
            if (!RtlpHpHeapCreate(
                RtlpHpConvertCreationFlags(ulFlags,
                    ntGlobalFlag),
                edi,
                eax,
                ecx,
                edx))
            {
                goto RELEASE_SRC;
            }
            // 移动链表
            RtlpMoveHeapBetweenLists(esi, edx, 1, ebx);
            if (*(WORD*)(esi + 0x14) == LOWORD(ebx))
            {
                goto RELEASE_SRC;
            }
 
            RtlpHpHeapDestroy(esi);
            esi = ebx;
            goto RELEASE_SRC;
 
        }
 
    }
 
    if (!(ulFlags & 0x10000000))
    {
        if (_RtlpHeapErrorHandlerThreshold >= 2
            && (ulFlags & 0xFFF80C00))
        {
            if (((PPEB)__readfsdword(0x30))->Ldr)
            {
                //_DbgPrint();
                // 这里正常来讲应该是一个结构体而不是强转 + 偏移
                // 但是为了赶项目进度暂时翻译为偏移的形式
                printf("HEAP[%wZ]: ", *(DWORD*)(*(DWORD*)(__readfsdword(0x30) + 0xc) + 0xc) + 0x2c);
            }
            else
            {
                // dbg p
                printf("HEAP: ");
            }
            // dbg p
            printf("!(CheckedFlags & ~HEAP_CREATE_VALID_MASK)");
 
            //
            if (byte_4B3A5DA8 == 0)
            {
                RtlpReportHeapFailure(2);
            }
            //edx = ulFlags;
        }
        /*if (edx & 0xFFF80C00)
        {
            edx &= 0x7F3FF;
        }*/
        if (ulFlags & 0xFFF80C00)
        {
            ulFlags &= 0x7F3FF;
        }
    }
    // ebx 万年老0, 这里推断var_A8是个结构体
    // 或许初始化为 STRUCT var_A8 { 0 };
    // 不过考虑到WINDOWS是C语言开发的
    // 也不清楚微软内部编译器支持的语言规范版本
    // 暂时设置为memset
    memset(var_A8, 0, 0x30);
 
    if (edi != 0)
    {
        // 这里对SEH进行一些设置
        ms_exc.registration.TryLevel = 0;
        if (edi == esi)
        {
            memcpy((PBYTE)edi, var_A8, 0xc);
        }
        ms_exc.registration.TryLevel = 0xFFFFFFFE;
    }
    // 这里的汇编为test    cl, 20h 但是ntGlobalFlag
    // 4字节我不想翻译为强转只能祈祷编译器对取低位有优化
    if (ntGlobalFlag & 0xff & 0x10)
    {
        ulFlags |= 0x20;
    }
 
    if (ntGlobalFlag & 0xff & 0x20)
    {
        ulFlags |= 0x40;
    }
 
    if (ntGlobalFlag & 0x200000)
    {
        ulFlags |= 0x80;
    }
 
    if (ntGlobalFlag & 0xff & 0x40)
    {
        ulFlags |= 0x40000000;
    }
 
 
    if (ntGlobalFlag & 0xff & 0x80)
    {
        ulFlags |= 0x20000000;
    }
 
 
    if (ntGlobalFlag & 0x1000)
    {
        ulFlags |= 0x8000000;
    }
 
    ecx = __readfsdword(0x30);
 
    // 这里的var_a8应该是个结构体之后要改一下可以通过PEB的成员反推
    // var_a8的成员
    if (!var_A8[1])
    {
        var_A8[1] = *(DWORD*)(ecx + 0x78);
    }
    if (!var_A8[2])
    {
        var_A8[2] = *(DWORD*)(ecx + 0x7c);
    }
    if (!var_A8[3])
    {
        var_A8[3] = *(DWORD*)(ecx + 0x84);
    }
    if (!var_A8[4])
    {
        var_A8[4] = *(DWORD*)(ecx + 0x80);
    }
 
    if (!dword_4B3A6940)
    {
        dword_4B3A6944 = 0x10000;
        // 首先是查询系统信息
        if (NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS::SystemBasicInformation,
            &SystemInformation, 0x2c, 0) < 0)
        {
            goto RELEASE_SRC;
        }
        dword_4B3A6940 = var_58;
        edx = 0x1000;
    }
    // 接下来是对页段的操作
    // 貌似这里是在对页进行处理-0x1000的操作正是在将
    // 前面的设置为页首
    if (!var_A8[5])
    {
        var_A8[5] = dword_4B3A6940 - dword_4B3A6944 - 0x1000;
    }
    // 最大值为0x7F000
    if (!var_A8[6] || var_A8[6] > 0x7F000)
    {
        var_A8[6] = 0x7F000;
    }
 
    // 加了一些什么值
    if (stCommit)
    {
        stCommit = (stCommit + 0xFFF) & 0xFFFFF000;
    }
 
    /*edi = stReserver;
    if (edi != 0)
    {
        ecx = edi + 0XFFF;
        ecx &= 0xFFFFF000;
        var_BC = ecx;
    }*/
    if (stReserver)
    {
        var_BC = (stReserver + 0xFFF) & 0xFFFFF000;
    }
    else
    {
        var_BC = (stCommit + 0xFFFF) & 0xFFFF0000;
    }
 
    /*
     mov     [ebp+var_BC], ecx ; ecx = var_BC
     mov     esi, edx        ; edx = dwCommiteSize
                             ; esi = dwCommiteSize
     cmp     edx, ecx
     ja      markif19
    */
 
    // 计算得到最大堆块大小:最大堆块大小实际上是 0x7f000,即 0x80000 减去一个页面。
    // 最大块大小为 0xfe00,粒度偏移为 3
    if (stCommit > var_BC)
    {
        stCommit = var_BC;
        esi = var_BC;
    }
    //获取传入的堆参数块,根据PEB设置堆参数块的值,
    // 根据PEB->NtGlobalFlag设置堆块的标志
    // ebx = 0
    if (!(ulFlags & 0xff & 2) && pBase != NULL)
    {
        ntGlobalFlag = 0;
    }
    else
    {
        ntGlobalFlag = 0x1000;
        ulUnknow1 = 2;
        //eax = var_BC - 0x1000;
        if (stCommit < var_BC - 0x1000)
        {
            var_BC = (var_BC + 0x10fff) & 0xffff0000;
        }
    }
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2025-2-14 16:00 被TeddyBe4r编辑 ,原因: 修改介绍
收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
米龙·0xFFFE
+1
你的分享对大家帮助很大,非常感谢!
2025-2-15 15:57
mb_aimnntrv
+1
感谢你分享这么好的资源!
2025-2-14 11:12
backer
你的帖子非常有用,感谢分享!
2025-2-13 23:04
mb_mkhkgduq
感谢你分享这么好的资源!
2025-2-13 22:33
W1ndowsXP
为你点赞!
2025-2-13 21:50
xichang13
+1
感谢你的积极参与,期待更多精彩内容!
2025-2-13 21:27
mb_bcrzdpsm
你的分享对大家帮助很大,非常感谢!
2025-2-13 21:06
最新回复 (7)
雪    币: 3211
活跃值: (4474)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你的分享对大家帮助很大,非常感谢!
2025-2-13 21:32
1
雪    币: 67
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
大佬牛逼!
2025-2-13 21:48
0
雪    币: 220
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
alu
4
历害了!点赞!
2025-2-14 11:29
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
可以寻求帮助吗
2025-2-15 19:33
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
mb_nkihouey 可以寻求帮助吗
历害了!点赞!
2025-2-16 16:24
0
雪    币: 2545
活跃值: (3404)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
人肉F5吗
2025-2-18 11:17
0
雪    币: 892
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
一个大大的服字,牛逼了。
2025-2-18 22:25
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册