Я скомпилировал программу на C и связал ее с компоновщиком Microsoft link.exe .
Компоновщик сгенерировал файл * .map. Ниже приведены некоторые фрагменты:
Start Length Name Class
0001:00000000 00000180H .text CODE
0001:00000180 00049158H .text$mn CODE
0002:00000000 000090c4H .rdata DATA
0002:000090c4 00000130H .rdata$zzzdbg DATA
0003:00000000 00002060H .data DATA
0003:00002060 00001370H .bss DATA
0004:00000000 00002790H .pdata DATA
0005:00000000 000003e4H .xdata DATA
Address Publics by Value Rva+Base Lib:Object
0002:000000c0 _gVar 0000000000049660 MyLib:File1.obj
Насколько я понимаю:
Секция .rdata
имеет индекс 0002
с длиной 0x90c4
.
Глобальная переменная _gVar
имеет адрес, подобный 0002:000000c0
, поэтому она живет в .rdata
секундах со смещением секции 0xc0
.
Базовый адрес раздела .rdata
определяется загрузчиком во время выполнения .
Моя путаница связана с колонкой Rva+Base
.
Я проверил двоичный файл по смещению 0x49660
. Он содержит именно то значение, которое я присвоил _gVar
. Так что Rva+Base
- это смещение от начала файла .
Но я думаю, что Rva + Base
должно равняться absolute virtual address
, что может быть только , определенное загрузчиком во время выполнения .
Как это может быть смещение файла? Или неудачная опечатка в названии колонки?
(Кстати, я много искал авторитетную ссылку на файл .map, сгенерированный link.exe. Но пока не повезло. Если кто-то сможет поделиться каким-то ресурсом, он будет глубоко признателен.)
ДОБАВИТЬ 1 - 5:31 PM 4/8/2019
На основании комментария 500 - Internal Server Error
я использую CFF Explorer для проверки разделов PE. Это выглядит ниже:
В соответствии с PE sepc :
Виртуальный адрес : для исполняемых образов - адрес первого байта раздела относительно базы изображений , когда раздел
загружен в память.
Raw Address / PointerToRawData : Указатель файла на первую страницу раздела в файле COFF.
Эти 2 столбца содержат одинаковые данные в моем сценарии.
А в опциональном заголовке PE, ImageBase - 0 (это из-за моего флага ссылки /BASE:0
):
Когда компоновщик сгенерировал файл .map, он не знает, куда будет загружаться изображение во время выполнения. Так что должен использовать ImageBase=0
для вычисления столбца Rva+Base
.
Абсолютный виртуальный адрес _gVar
= ImageBase (0) + Виртуальный адрес .rdata (0x495A0) + смещение в .rdata (0xc0) = 0x49660
В моем случае
- Столбец
Virtual Address
имеет то же значение, что и столбец Raw Address
.
- А
ImageBase = 0
имеет тот же эффект file beginning offset = 0
Таким образом, окончательный absolute virtual address
равен file offset
, , но это относится только к моему сценарию .