如何创建具有以下属性的内存 region/section(由 QueryWorkingSetEx 和 VirtualQuery 检查)?

How to create memory region/section with following properties (checked by QueryWorkingSetEx and VirtualQuery)?

我需要使内存 region/section 具有以下属性:

VirtualQuery 在此类区域检查的函数应该 return:

QueryWorkingSetEx 在此类区域检查的函数应该 return:

此外,此区域无法映射到磁盘文件(INVALID_HANDLE_VALUE 创建映射文件部分时)。在只有 PAGE_EXECUTE_READ 访问权限之前,它还应该填充所需的数据。

此外,无法将此类扇区的保护(使用 VirtualProtect 函数)更改为 PAGE_READONLYPAGE_WRITECOPY,尽管它是 PAGE_EXECUTE_READ。它表明它可能没有记录 SEC_NO_CHANGE 属性.

有可能做到这一点,因为它存在于我正在调试的恶意软件中,但我很难复制,而且团队中很少有人失败,如果有人能向我提供有关如何复制的信息,我将印象深刻创建它。

这里没什么难做的 - 我们真的需要用

创建部分
#define SEC_NO_CHANGE 0x00400000

来自 createsec.c

SEC_NO_CHANGE - Once the file is mapped, the protection cannot be changed nor can the view be unmapped. The view is unmapped when the process is deleted. Cannot be used with SEC_IMAGE.

所以只需要用这个标志创建部分。然后首先用 PAGE_READWRITE 页面保护映射它并初始化它的数据。而不是取消映射并使用 PAGE_EXECUTE_READ 保护再次映射。全部。没有什么特别或困难的。

#define SEC_NO_CHANGE 0x00400000

NTSTATUS ghty(PVOID* pBaseAddress, ULONG SectionSize = 0x10000)
{
    HANDLE hSection;
    LARGE_INTEGER MaxSize = { SectionSize };
    NTSTATUS status = ZwCreateSection(&hSection, 
        SECTION_MAP_READ|SECTION_MAP_WRITE|SECTION_MAP_EXECUTE, 0, &MaxSize, 
        PAGE_EXECUTE_READWRITE, SEC_COMMIT|SEC_NO_CHANGE, 0);

    if (0 <= status)
    {
        PVOID BaseAddress = 0;
        SIZE_T ViewSize = 0;

        if (0 <= (status = ZwMapViewOfSection(hSection, NtCurrentProcess(), 
            &BaseAddress, 0, 0, 0, &ViewSize, ViewUnmap, 0, PAGE_READWRITE)))
        {

            memset(BaseAddress, 0xc3, ViewSize);
            ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);

            *pBaseAddress = 0;
            status = ZwMapViewOfSection(hSection, NtCurrentProcess(), 
                pBaseAddress, 0, 0, 0, &(ViewSize = 0), ViewUnmap, 0, PAGE_EXECUTE_READ);
        }

        NtClose(hSection);
    }

    return status;
}

void test()
{
    PVOID BaseAddress;
    if (0 <= ghty(&BaseAddress))
    {
        //++ test
        ULONG op;
        SIZE_T Size = 1;
        PVOID pv = BaseAddress;
        ZwProtectVirtualMemory(NtCurrentProcess(), &pv, &Size, PAGE_READONLY, &op);
        // STATUS_INVALID_PAGE_PROTECTION will be
        // if we use SEC_NO_CHANGE
        // -- test

        ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
    }
}

也刚找到这个linkSelf-Remapping Code。您调试的可能代码做同样的事情。认为这样做是有道理的——你不能在这段代码中设置断点(int 3)——因为内存不可写,也不能被设置为可写。结果不可能插入 bp