I am trying to use memory-mapped files as:
hFile = ::CreateFile(State.Path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN, 0);//open the file
if(hFile !=INVALID_HANDLE_VALUE){
hMap= ::CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);//create Mem mapping for the file in virtual memory
if( hMap!=NULL){
base = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);//load the mapped file into the RAM
//start to compare some bytes (values) from mspaint.exe file in Win7
if( *((BYTE *)base + 0x1C3DF0)== 0x05 )
i++;
if( *((BYTE *)base + 0x25250C)== 0x21 )
i++;
if( *((BYTE *)base + 0x25272A)== 0x97 )
i++;
if(i==3){
// the file is malicious
}
Once the file size be in Gigabytes, the MapViewOfFile
function stop working and the application will be crashed! Is there any limitation to use MapViewOfFile
? Any suggestion?
You need to check the return value! The other reason for a crash can be found in the MapViewOfFile remarks section on MSDN:
To guard against EXCEPTION_IN_PAGE_ERROR exceptions, use structured
exception handling to protect any code that writes to or reads from a
memory mapped view of a file other than the page file.
As far as other limitations go; clearly the view has to fit in the virtual memory space of your process and a 32 bit process normally only has 2gb in total. If you are working with gigabyte sized files you need to map smaller views and not the whole file at once...
Your application is crashing, because you're not checking MapViewOfFile
for errors -- the function returns 0 if it fails.
As for the limitations, the function cannot map a block that is larger than the largest contiguous free block of your virtual memory space. If your program is 32-bit, then you have only about 2GB of available virtual memory; the largest contiguous free block will be smaller as your program binary, DLLs, your main thread stack and your heap will be allocated at various places across the memory space.
You are trying to map the entire file into memory at one time. You don't have enough virtual memory to do that. Map just the portion that you actually need. That is why CreateFileMapping() and MapViewOfFile() allow you to specify sizes and offsets for mapping. I use MMFs to access multi-GB files, you definately have to keep the size of the mapping to a minimum, just slide the view around where you need it.