2012-03-15 10 views
2

Можно создать дубликат:
Why won't the loader load at the desired locationЧто возвращает MapViewOfFile?

«MapViewOfFile», делает эта функция отображения файла в виртуальной памяти и возвращает базовый адрес отображаемой памяти ?? Если «да», то следующий код должен выводить 0X400000, по умолчанию по умолчанию, exe загружаются в этом месте, но вывод 0X360000. Зачем??

#include<iostream> 
#include<Windows.h> 
#include<stdio.h> 
#include<WinNT.h> 


int main() 
{ 


HANDLE hFile,hFileMapping; 
LPVOID lpFileBase; 


if((hFile = CreateFile(TEXT("c:\\linked list.exe"),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)) == INVALID_HANDLE_VALUE) 
    std::cout<<"unable to open"; 

if((hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL)) == 0) 
{ 
    CloseHandle(hFile); 
    std::cout<<"unable to open for mapping"; 
} 

if((lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0))== 0) 
{ 
    CloseHandle(hFile); 
    CloseHandle(hFileMapping); 
    std::cout<<"couldn't map view of file"; 
} 

printf("%x\n",lpFileBase); 

} 
+1

Да, код *, который вы написали *, отображается на 0x400000 (без учета ASLR). Не файл, который вы загружаете позже, он не может быть сопоставлен с этим адресом, поскольку он уже используется вашим кодом. Linker, Advanced, Base Address, чтобы переместить код в другом месте. –

+0

Получил это спасибо .. – user1232138

ответ

1

Изучаемый 0X400000 не имеет никакого отношения к нормальному сопоставлению файлов.

Вы можете себе представить, MapViewOfFile как таНос + тетср файл открываемых, не более (под капотом у него есть обратный: таНос может использовать slab'ed отображение памяти). Таким образом, MapViewOfFile обычно выбирает адрес, в котором он может поместиться в байтах представления файла непрерывно в памяти.

Что вы, вероятно, хотите (поскольку вы пытаетесь создать карту .exe), необходимо создать новый процесс с ним CreateProcess.

Если вам действительно нужен файл для сопоставления по конкретному адресу, вы можете использовать MapViewOfFileEx, но никаких гарантий нет.

+0

Ну, на самом деле я не хочу отображать файл в основную память, я просто хочу работать с копией файла на диске, но большинство адресов в заголовках PE - это RVA, и я не знаю, как преобразовать RVA в смещение файла ... – user1232138

+0

RVA ** ** - смещение внутри файла, поэтому вам не нужно преобразовывать. Только когда Windows загружает exe для вас, он преобразует RVA в кучи-адреса. –

+0

Я думаю, вы уже читаете этот http://msdn.microsoft.com/en-us/magazine/cc301805.aspx, потому что это просто лучший ресурс по этой теме.В зависимости от ваших потребностей вы также можете посмотреть http://msdn.microsoft.com/en-us/library/windows/desktop/ms680218%28v=vs.85%29.aspx –

0

Да, MapViewOfFile возвращает базовый адрес виртуальной памяти, где было загружено изображение. Значение (содержимое) этого адреса зависит от того, было ли изображение успешно загружено на его предопределенный адрес (который был установлен компоновщиком) или было ли перемещено изображение (поскольку желаемый предварительно определенный адрес уже занят или потому, что у изображения есть выбор для поддержки ASLR).

0

Чтобы преобразовать RVA в смещение файла, найдите дельта и используйте это. Я предполагаю, что вы пытаетесь сделать что-то вроде того, как RVA в структуре dataDirectory файла PE указывает, после того, как файл памяти отображает карту памяти? Посмотрите на IMAGE_SECTION_HEADER структуры:

typedef struct _IMAGE_SECTION_HEADER { 
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; 
union { 
      DWORD PhysicalAddress; 
      DWORD VirtualSize; 
    } Misc; 
    DWORD VirtualAddress; 
    DWORD SizeOfRawData; 
    DWORD PointerToRawData; 
    DWORD PointerToRelocations; 
    DWORD PointerToLinenumbers; 
    WORD NumberOfRelocations; 
    WORD NumberOfLinenumbers; 
    DWORD Characteristics; 
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 

Вы хотите сделать дельту найти разницу в секции VirtualAddress и PointerToRawData значение. Затем, для RVA в данный раздел, отмените дельта, чтобы получить смещение файла.

По моему опыту это различно для каждого раздела. Поэтому, если у вас есть RVA во втором разделе, указанном в таблице разделов, дельта будет отличаться от второго раздела, указанного в таблице разделов. Для этого он помогает определить функцию раздела RVA. И вы должны отредактировать свой вопрос, чтобы показать, что это вопрос, который вы задаете.

Смежные вопросы