Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


I'm struggling with system allocation granularity 64bit C++

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Apr 18, 2017 8:12 am    Post subject: I'm struggling with system allocation granularity 64bit C++ Reply with quote

Hello, I'm trying to unmap the sections of a file loaded in memory, and remap them.... but after I've unmapped these, when I try to map again the nt function returns an error (searched it on internet):

ntstatus.h 0xC0000220
#define STATUS_MAPPED_ALIGNMENT
{Mapped View Alignment Incorrect} An attempt was made to map a view of a file, but either the specified base address or the offset into the file were not aligned on the proper allocation granularity.

in fact I don't know really how to properly align the views with the system allocation granularity (which is 64 kb)...
I've already look on some windows related books and I understand that the size must be a multiple of the granularity, but I don't understand how to accomplish that.
I've this kind of code for creating the backend section that will contain the copied PE memory
Code:

HANDLE Sezione = NULL;
   LARGE_INTEGER SecSize = {};
   SecSize.QuadPart = pe.optionalHeader->SizeOfImage;
   
   ntapi::NTSTATUS status = ntapi::NtCreateSection(&Sezione,
      SECTION_ALL_ACCESS,
      NULL,
      &SecSize,
      PAGE_READWRITE,
      SEC_COMMIT,
      NULL);
   
   if (status != ntapi::STATUS_SUCCESS)
   {
      printf("NtCreateSection failed:  0x%08X.\n", status);
      return;
   }

   PVOID copyViewBase = NULL;
   LARGE_INTEGER copySectionOffset = {};
   SIZE_T copyViewSize = 0;
   status = ntapi::NtMapViewOfSection(Sezione,
      GetCurrentProcess(),
      &copyViewBase,
      0,
      pe.optionalHeader->SizeOfImage,
      &copySectionOffset,
      &copyViewSize,
      ntapi::ViewUnmap,
      0,
      PAGE_READWRITE);


Then I use the memcpy to copy the memory of the pe file into this new created section:
Code:

memcpy(copyViewBase, PVOID(pe.optionalHeader->ImageBase), pe.optionalHeader->SizeOfImage);


then after a bunch of code I unmap the PE image
Code:

ntapi::NtUnmapViewOfSection(GetCurrentProcess(), PVOID(pe.optionalHeader->ImageBase));


and after all of these I try to map the new section that I've created before to remap the PE image:

Code:

auto mapPeSection = [&Sezione](SIZE_T BaseAddress,
      SIZE_T RegionSize,
      SIZE_T RegionOffset,
      DWORD Protection)
   {
      PVOID viewBase = PVOID(BaseAddress);
      LARGE_INTEGER sectionOffset = {};
      sectionOffset.QuadPart = RegionOffset;
      SIZE_T viewSize = RegionSize;
      ntapi::NTSTATUS status = ntapi::NtMapViewOfSection(Sezione,
         GetCurrentProcess(),
         &viewBase,
         0,
         viewSize,
         &sectionOffset,
         &viewSize,
         ntapi::ViewUnmap,
         ntapi::SEC_NO_CHANGE,//ntapi::SEC_NO_CHANGE
         Protection);
      if (status != ntapi::STATUS_SUCCESS)
         printf("NtMapViewOfSection failed for view at base %p:  0x%08X.\n", BaseAddress, status);
      else
         printf("remapped   %p  +%016X  %16X\n",
            viewBase,
            sectionOffset.QuadPart,
            viewSize);
   };

   const PIMAGE_SECTION_HEADER text = GetPeSectionByName(pe, ".text");
   const PIMAGE_SECTION_HEADER rdata = GetPeSectionByName(pe, ".rdata");
   const PIMAGE_SECTION_HEADER data = GetPeSectionByName(pe, ".data");
   if (!(text && text < rdata && rdata < data))
      return;

   // Mapped views for the PE Sections.
   // ========================================================================
   // Address Range (RVA)      Content                         Protection
   // ------------------------------------------------------------------------
   // 0x000000 - 0x0FFFFF      PE Header, .text.               PAGE_EXECUTE_READ
   // 0x100000 - 0x2FFFFF      .rdata                          PAGE_READONLY
   // 0x200000 - 0x203FFF      .data, .pdata, .rsrc, .reloc    PAGE_READWRITE
   // ------------------------------------------------------------------------
   mapPeSection(pe.optionalHeader->ImageBase,
      PE_HEADER_SIZE + text->Misc.VirtualSize,
      0,
      PAGE_READONLY);//PAGE_EXECUTE_READWRITE

   mapPeSection(pe.optionalHeader->ImageBase + rdata->VirtualAddress,
      rdata->Misc.VirtualSize,
      rdata->VirtualAddress,
      PAGE_READONLY);

   mapPeSection(pe.optionalHeader->ImageBase + data->VirtualAddress,
      0,
      data->VirtualAddress,
      PAGE_READONLY);

but here at the end there is the error when I try to call the last 3 NtMap functions.

If it's needed I would post the entire code on github because it's huge and I can't post all in here.
Back to top
View user's profile Send private message
Deine Mutter
Expert Cheater
Reputation: 1

Joined: 05 Apr 2006
Posts: 181

PostPosted: Tue Apr 18, 2017 11:57 am    Post subject: Reply with quote

You should not be able to map individual PE sections because your offsets are most likely not 64K aligned (in fact, they won't be aligned to anything because Misc.VirtualSize has no alignment).

Code:
mapPeSection(pe.optionalHeader->ImageBase,
   PE_HEADER_SIZE + text->Misc.VirtualSize, <-- not 64K aligned
   0,
   PAGE_READONLY);//PAGE_EXECUTE_READWRITE

mapPeSection(pe.optionalHeader->ImageBase + rdata->VirtualAddress,
   rdata->Misc.VirtualSize, <-- not 64K aligned
   rdata->VirtualAddress,
   PAGE_READONLY);

mapPeSection(pe.optionalHeader->ImageBase + data->VirtualAddress,
   0, <-- wat?
   data->VirtualAddress,
   PAGE_READONLY);


According to the documentation:
Quote:
SectionOffset:
Pointer to begin of mapped block in section. This value must be rounded up to X64K block size (0x10000 on X86).


So, why don't you just remap the whole pe file at once?

_________________
Back to top
View user's profile Send private message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Apr 18, 2017 12:23 pm    Post subject: Reply with quote

Thank you for the reply!
( I've sent you a PM because you seem to know what's up )

I didn't know the misc.virtualsize isn't aligned , aniway I didn't say that the first map is the only one that works , so I guess " PE_HEADER_SIZE + text->Misc.VirtualSize " is aligned, but the other 2 are wrong... I've seen now that 0 in the size , my bad... aniway it will not change much since I still can't map these, and I don't think that I can map the whole PE file together (maybe if you know , I would appreciate to know that) because I need to map it as it was previously otherwise it will not start ( I can't set a PAGE_EXECUTE on the data section otherwise the process will crash istantly) for a test I've set everything as PAGE_READONLY for protection compatibility. (sometimes I get a few errors for uncompatibility with the previous allocated protections on those sections)

otherwise if you know what values I've to sum to align each view , it would be a good solution :/

P.s.: also mind that I've suspended all the threads in the process otherwise it crashes.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Tue Apr 18, 2017 1:41 pm    Post subject: Reply with quote

You can use 'NtQuerySystemInformation' to obtain the proper allocation granularity for your system (or any system that may use this in the future with your stuff.) The info type you are querying for would be 'SystemBasicInformation'. The 'SYSTEM_BASIC_INFORMATION' returned will have the info that you need. (MSDN's documentation for this structure is not correct/complete so you will have to find it on other sites instead.)

Here is an old phrack article that covers how to do the alignment:
http://phrack.org/issues/59/16.html

Some common macros used to do aligments:
Code:

#define ALIGN_DOWN_BY(size, align) \
    ((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1))

#define ALIGN_UP_BY(size, align) \
    (ALIGN_DOWN_BY(((ULONG_PTR)(size) + align - 1), align))


Where size is the address you are using, and the align is the alignment granularity you are using. (ie. from the NtQuerySystemInformation result.)

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Deine Mutter
Expert Cheater
Reputation: 1

Joined: 05 Apr 2006
Posts: 181

PostPosted: Tue Apr 18, 2017 1:55 pm    Post subject: Reply with quote

Btw, there was a typo in my answer because I highlighted the wrong parameters:

Code:

mapPeSection(pe.optionalHeader->ImageBase,
   PE_HEADER_SIZE + text->Misc.VirtualSize,
   0,  <-- 64K aligned
   PAGE_READONLY);//PAGE_EXECUTE_READWRITE

mapPeSection(pe.optionalHeader->ImageBase + rdata->VirtualAddress,
   rdata->Misc.VirtualSize,
   rdata->VirtualAddress,  <-- not 64K aligned
   PAGE_READONLY);

mapPeSection(pe.optionalHeader->ImageBase + data->VirtualAddress,
   0, <-- wat?
   data->VirtualAddress, <-- not 64K aligned
   PAGE_READONLY);


As you can see, the first call suceeds because 0 is 64K aligned. You really should not be able to map individual PE sections like that because the virtual addresses of the sections will be aligned to the section alignment which usually differs from 64K. Can't you map the whole PE file and then change the permissions of the areas where the sections are located?

_________________
Back to top
View user's profile Send private message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Apr 18, 2017 2:14 pm    Post subject: Reply with quote

Thank you both, atomos I'll try that btw I know the system allocation granularity from a code like this

Code:

SYSTEM_INFO si;
    GetSystemInfo(&si);

    auto isAligned = [&si](const PIMAGE_SECTION_HEADER Section)
    {
      
      return Section->VirtualAddress % si.dwAllocationGranularity == 0;
    };

    return isAligned(rdata) && isAligned(data);


Deine mutter why do you say that the rdata and data virtual addresses are not aligned? I mean these are the original from the PE header, I think you meant the size of those? I mean I must use them otherwise the sections will be mapped in the wrong places?
I will try atomos macros...
btw I don't get why If I copy the view of a file and store it inside a section , why that isn't properly aligned? I mean when I run the PE file these sections must be aligned, why if I copy them and reuse them they are not aligned? This is kinda strange for me.
Back to top
View user's profile Send private message
Deine Mutter
Expert Cheater
Reputation: 1

Joined: 05 Apr 2006
Posts: 181

PostPosted: Wed Apr 19, 2017 12:27 pm    Post subject: Reply with quote

Viloresi wrote:
Deine mutter why do you say that the rdata and data virtual addresses are not aligned?

They are aligned to the section alignment specified in the PE header but they are not aligned the allocation granularity of your system. Section alignment and allocation granularity are usually different.

_________________
Back to top
View user's profile Send private message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Fri Apr 21, 2017 2:33 pm    Post subject: Reply with quote

Deine Mutter wrote:
Viloresi wrote:
Deine mutter why do you say that the rdata and data virtual addresses are not aligned?

They are aligned to the section alignment specified in the PE header but they are not aligned the allocation granularity of your system. Section alignment and allocation granularity are usually different.

contacted the author of part of the code,
figured out that 0 meaning from MSDN:

MSDN wrote:

ViewSize [in, out]
If the initial value of this variable is zero, ZwMapViewOfSection maps a view of the section that starts at SectionOffset and continues to the end of the section.


btw I've tried atomos macro and I've tried some other stuff too but It doesn't work because as you said the offsets (that you've marked) are not alligned to the system granularity...
But I don't understand if I change even slightly those offsets I get another error of bad viewsize, even that... I guess If I change these offsets the views get mapped in the wrong place? I don't know how to fix this, it doesn't make sense to me I'm still blocked sorry.
Back to top
View user's profile Send private message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Mon Apr 24, 2017 11:45 am    Post subject: Reply with quote

Up , so nobody knows how to do this?
The fact is that I can forget this code, and just write another one... my intention is just to remap a process while in run-time without the use of a driver ...
Is it possible? I've taken a look to phrack guide that atomos suggested, but that's about mapping a file, and also creating a process and mapping it before starting it....(that's not what I'm trying to do)..
I've also taken a look at BlackBone (which is a big library about hacking windows environment) and there is a re-map feature but it's used with a driver... so it doesn't have user-mode...

The problem that I've seen (maybe not the only one) is that after a program is loaded and its process has been created and mapped, for me there is no way to delete its "main" section and recreate it (maybe because I'm missing something).
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites