C++ 在特定Windows DLL模块中分配内存

C++ 在特定Windows DLL模块中分配内存,c++,windows,memory-management,allocation,C++,Windows,Memory Management,Allocation,我想在进程的特定模块中分配一些内存,而不是一般的进程。以下WindowsC++代码可以在给定进程id的进程内分配内存: #include "pch.h" #include <windows.h> #include <winternl.h> #include <processthreadsapi.h> #include <iostream> #include <conio.h> #pragma comment(lib, "ntdll.

我想在进程的特定模块中分配一些内存,而不是一般的进程。以下
Windows
C++
代码可以在给定进程id的进程内分配内存:

#include "pch.h"

#include <windows.h>
#include <winternl.h>
#include <processthreadsapi.h>
#include <iostream>
#include <conio.h>

#pragma comment(lib, "ntdll.lib")

typedef NTSTATUS (NTAPI *nt_alloc_virtual_memory_func)(HANDLE process_handle, PVOID* base_address, ULONG_PTR zero_bits,
                                                       PSIZE_T region_size, ULONG allocation_type, ULONG protect);
typedef NTSTATUS (NTAPI *nt_free_virtual_memory_func)(HANDLE process_handle, PVOID* base_address, PSIZE_T region_size,
                                                      ULONG free_type);

void enable_allocating_executable_memory()
{
    PROCESS_MITIGATION_DYNAMIC_CODE_POLICY mp;
    ZeroMemory(&mp, sizeof mp);
    mp.ProhibitDynamicCode = FALSE;
    SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &mp, sizeof mp);
}

long allocate_memory(char** arguments, const HANDLE process_handle, PVOID process_memory, SIZE_T& allocation_size)
{
    const auto memory_size = arguments[3];
    allocation_size = strtoul(memory_size, nullptr, 10);

    const auto nt_allocate_virtual_memory = reinterpret_cast<nt_alloc_virtual_memory_func>(GetProcAddress(
        GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory"));

    const auto allocation_status = nt_allocate_virtual_memory(process_handle, &process_memory, 0, &allocation_size,
                                                              MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (NT_SUCCESS(allocation_status))
    {
        std::cout << std::hex << process_memory << std::endl;
    }

    return allocation_status;
}

int free_memory(const int argument_count, char** arguments,
                const HANDLE process_handle, SIZE_T& mem_size)
{
    const auto address_string = arguments[3];
    const auto process_address = strtoull(address_string, nullptr, 16);
    auto process_memory_address = reinterpret_cast<PVOID>(process_address);

    if (argument_count < 4)
    {
        return EXIT_FAILURE;
    }

    const auto memory_size = arguments[4];
    mem_size = strtoul(memory_size, nullptr, 10);

    const auto nt_free_virtual_memory = reinterpret_cast<nt_free_virtual_memory_func>(GetProcAddress(
        GetModuleHandle(L"ntdll.dll"), "NtFreeVirtualMemory"));

    const auto status = nt_free_virtual_memory(process_handle, &process_memory_address, &mem_size, MEM_RELEASE);
    return status;
}

int main(const int argument_count, char* arguments[])
{
    if (argument_count < 4)
    {
        return EXIT_FAILURE;
    }

    const auto process_id_string = arguments[1];
    const auto process_id = strtoul(process_id_string, nullptr, 10);

    enable_allocating_executable_memory();

    const auto process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
    if (process_handle == nullptr)
    {
        std::cout << "Cannot open process with process id " << process_id << std::endl;
        exit(EXIT_FAILURE);
    }

    const PVOID process_memory = nullptr;
    SIZE_T mem_size;

    const auto command = arguments[2];
    if (strcmp(command, "--allocate") == 0)
    {
        allocate_memory(arguments, process_handle, process_memory, mem_size);
    }
    else if (strcmp(command, "--free") == 0)
    {
        return free_memory(argument_count, arguments, process_handle, mem_size);
    }

    return EXIT_SUCCESS;
}
#包括“pch.h”
#包括
#包括
#包括
#包括
#包括
#pragma注释(lib,“ntdll.lib”)
typedef NTSTATUS(NTAPI*nt\U alloc\U virtual\U memory\U func)(句柄进程\U句柄、PVOID*base\U地址、ULONG\U PTR零位、,
PSIZE(区域大小、ULONG分配类型、ULONG保护);
typedef NTSTATUS(NTAPI*nt\U free\U virtual\U memory\U func)(句柄进程\U句柄,PVOID*base\U地址,PSIZE\U区域大小,
ULONG free_型);
无效启用\分配\可执行\内存()
{
过程\缓解\动态\代码\政策mp;
零内存(&mp,大小为mp);
mp.ProhibitDynamicCode=FALSE;
设置ProcessReliationPolicy(ProcessDynamicDepolicy,&mp,sizeof mp);
}
长分配内存(字符**参数、常量句柄进程句柄、PVOID进程内存、大小和分配大小)
{
const auto memory_size=参数[3];
分配大小=strtoul(内存大小,nullptr,10);
const auto nt\u allocate\u virtual\u memory=reinterpret\u cast(GetProcAddress(
GetModuleHandle(L“ntdll.dll”),“nAllocateVirtualMemory”);
const auto allocation_status=nt_allocate_virtual_memory(进程句柄和进程内存、0和分配大小、,
MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if(NT_成功(分配_状态))
{
标准::cout
我想在特定模块内分配一些内存

您不能这样做,当模块映射时,它的内存被分配。您不能在模块内部分配内存,模块存在于其分配的页面中,而不存在于其他任何位置。任何分配的页面都将位于模块外部

或者,如果您想使用已分配但未使用的内存,这称为代码洞。它通常是模块内充满零的内存区域。因此,您可以通过在模块内找到一定长度的冗余零来扫描代码洞,然后您可以写入该内存

这是经常做的,如果页面设置了执行位,那么这尤其有用,因为您不必更改任何可能被认为有风险的权限


在使用“散射贴图”的喷油器中也经常进行此操作它只使用这些代码来注入代码。

从可用空间中只分配可能的内存。如果你链接到ntdll.lib,你就不能从模块中分配内存,因为你使用
GetProcAddress
来实现
NtAllocateVirtualMemory
而不是直接按原样调用它?为什么不说
VirtualAllocEx
使用?DLL不拥有内存,进程拥有。@rustyx:你不能指示进程分配内存放在某个
DLL
模块中吗?@willia-再次-你只能从空闲空间分配内存。你所做的毫无意义。放在某个特定模块中-这个内存已经分配了Cheers FleepHacks;)是的,我结束了使用代码和手动内存分配就可以了。