如何创建具有以下属性的内存 region/section(由 QueryWorkingSetEx 和 VirtualQuery 检查)?
How to create memory region/section with following properties (checked by QueryWorkingSetEx and VirtualQuery)?
我需要使内存 region/section 具有以下属性:
VirtualQuery
在此类区域检查的函数应该 return:
- 分配保护:0x20 [
PAGE_EXECUTE_READ
]
- 保护:0x20 [
PAGE_EXECUTE_READ
]
- 状态:0x1000 [
MEM_COMMIT
]
- 类型:0x40000 [
MAPPED
]
QueryWorkingSetEx
在此类区域检查的函数应该 return:
- 有效:1
- 共享:1
- 分享数:2
- 节点:0
- 大页面:0
- 锁定:0
- 差:0
- Win32 保护:0x20 [
PAGE_EXECUTE_READ
]
此外,此区域无法映射到磁盘文件(INVALID_HANDLE_VALUE
创建映射文件部分时)。在只有 PAGE_EXECUTE_READ
访问权限之前,它还应该填充所需的数据。
此外,无法将此类扇区的保护(使用 VirtualProtect
函数)更改为 PAGE_READONLY
或 PAGE_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
我需要使内存 region/section 具有以下属性:
VirtualQuery
在此类区域检查的函数应该 return:
- 分配保护:0x20 [
PAGE_EXECUTE_READ
] - 保护:0x20 [
PAGE_EXECUTE_READ
] - 状态:0x1000 [
MEM_COMMIT
] - 类型:0x40000 [
MAPPED
]
QueryWorkingSetEx
在此类区域检查的函数应该 return:
- 有效:1
- 共享:1
- 分享数:2
- 节点:0
- 大页面:0
- 锁定:0
- 差:0
- Win32 保护:0x20 [
PAGE_EXECUTE_READ
]
此外,此区域无法映射到磁盘文件(INVALID_HANDLE_VALUE
创建映射文件部分时)。在只有 PAGE_EXECUTE_READ
访问权限之前,它还应该填充所需的数据。
此外,无法将此类扇区的保护(使用 VirtualProtect
函数)更改为 PAGE_READONLY
或 PAGE_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 withSEC_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