0

My code. I have put the functions at the end.

    long base = reserve(0x660000, 0x4000); // long reserve(long address, long size)
    commit(base + 0x0000, 0x10); // long commit(long address, long size)
    commit(base + 0x2000, 0x10);
    printQueryInfo(base); //uses QueryVirtualMemoryInformation
    reserve(0x66A000, 0x1000); //VirtualAlloc returns NULL

Console

Trying to allocate region of length 16384 bytes (decimal) at 0x660000.
Returned base address is: 0x660000
Trying to commit region of length 16 bytes (decimal) at 0x660000.
Returned base address is: 0x660000
Trying to commit region of length 16 bytes (decimal) at 0x662000.
Returned base address is: 0x662000
QueryVirtualMemoryInformation at 0x660000
   AllocationBase: 0x660000
   AllocationProtect: 0x4
   Flags: 0x1
   RegionSize: 0x4000
   CommitSize: 0x2000
Trying to allocate region of length 4096 bytes (decimal) at 0x66A000.
Region allocation failed (base == NULL).
Returned base address is: 0x0

This is how I understand what allocating and committing means: enter image description here

Is the rest of these 64kb now unusable, as only the first 5kb are allocated and you can not allocate other parts of that block?

How the functions are implemented in detail. I know that this is not pretty.

long reserve(long address, long size) {
    printf("Trying to allocate region of length %li bytes (decimal) at 0x%lX.\n", size, address);
    LPVOID base1 = VirtualAlloc(address, size, MEM_RESERVE, PAGE_READWRITE);
    if (base1 == NULL) printf("Region allocation failed (base == NULL).\n");
    long baseLong = base1;
    printf("Returned base address is: 0x%lX\n", baseLong);
    return baseLong;
}
long commit(long address, long size) {
    printf("Trying to commit region of length %li bytes (decimal) at 0x%lX.\n", size, address);
    LPVOID base1 = VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE);
    if (base1 == NULL) printf("Region commit failed (base == NULL).\n");
    long baseLong = base1;
    printf("Returned base address is: 0x%lX\n", baseLong);
    return baseLong;
}
void printQueryInfo(long address) {
    WIN32_MEMORY_REGION_INFORMATION regionInformation[2]; //for some extra space... I get an error if it is only sizeof(WIN32_MEMORY_REGION_INFORMATION).
    long l;
    long informationBufferSize;
    BOOL b = QueryVirtualMemoryInformation(
        GetCurrentProcess(),
        address,
        MemoryRegionInfo,
        &regionInformation,
        28,
        &informationBufferSize
    );
    //printf("informationBufferSize: %li\n", informationBufferSize); // prints 28
    if (b == FALSE) {
        DWORD lastError = GetLastError();
        printf("QueryVirtualMemoryInformation returned false, code %i\n", (int)lastError);
    }
    else {
        printf("QueryVirtualMemoryInformation at 0x%lX\n", address);
        printf("   AllocationBase: 0x%lX\n", (long)(*regionInformation).AllocationBase);
        printf("   AllocationProtect: 0x%lX\n", (long)(*regionInformation).AllocationProtect);
        printf("   Flags: 0x%lX\n", (long)(*regionInformation).Flags);
        printf("   RegionSize: 0x%zX\n", (size_t)(*regionInformation).RegionSize);
        printf("   CommitSize: 0x%zX\n", (size_t)(*regionInformation).CommitSize);
    }
}

The regions/commits in x64dbg

AirToTec
  • 19
  • 4
  • 1
    Does this answer your question? [VirtualAlloc failing](https://stackoverflow.com/questions/29873860/virtualalloc-failing) – Raymond Chen Aug 04 '23 at 13:47
  • 1
    no, you can not – RbMm Aug 04 '23 at 15:00
  • Then why can you reserve parts of the virtual memory that are smaller than 64kb at all? Would it not be simpler and more efficient to only give the option to reserve these bigger blocks? – AirToTec Aug 04 '23 at 15:09
  • "Why does malloc let you allocate 1 byte? Would it not be simpler and more efficient to only give the option to malloc multiples of 16 bytes?" – Raymond Chen Aug 04 '23 at 16:50
  • In your case, I would say: no, this is not simpler and more efficient. If I need 1 byte but had to malloc 16, 15 bytes were wasted. – AirToTec Aug 04 '23 at 17:14
  • One might say, in analogy, that it would be better to allow to reserve single pages, but I expect there is a technical reason this is not possible (which I do not know). Now that you can only create regions starting with the granularity, why would you not reserve the entire 64kb? – AirToTec Aug 04 '23 at 17:29
  • My explanation is *MEM_RESERVE* is almost no cost unlike *MEM_COMMIT*. The page size has a heavy impact on system. – YangXiaoPo-MSFT Aug 07 '23 at 06:18

0 Answers0