Неверные адреса функций в MAP-файле Visual Studio - PullRequest
2 голосов
/ 08 октября 2008

адреса функций (Rva + Base) в моем MAP-файле из Visual Studio не совпадают с теми, которые я вижу в отладчике (или когда я вручную проверяю свой кадр стека).

Что может быть причиной этого?

/ * A.B. 1005 *

Ответы [ 4 ]

2 голосов
/ 08 октября 2008

Проблема в исполняемом файле или DLL?

Если это DLL, какой ее предпочтительный адрес загрузки? Если это конфликтует с какой-либо другой DLL, то она будет перезагружена загрузчиком, и это может привести к тому, что вы видите.

Как часть вашего процесса сборки, вы должны убедиться, что все ваши библиотеки DLL перебазированы (для этого есть инструмент), чтобы их адресные пространства не конфликтовали (это освобождает некоторое пространство подкачки и улучшает время загрузки ).

1 голос
/ 08 октября 2008

И exe, и dll могут быть перемещены, если вы не укажете параметр командной строки / FIXED при компоновке. Я использую следующий способ, чтобы определить реальный адрес, чтобы определить, где был загружен мой exe-файл, чтобы я мог вычислить смещение относительно файла карты.

static void KnownFunctionAddress(){}

...

// check an address of a known function
// and compare this to the value read from the map file

intptr_t CheckRelocationOffset(MapFile map)
{
  intptr_t mapAddress = map.PhysicalAddress("?KnownFunctionAddress@@YAXXZ");
  intptr_t realAddress = (intptr_t)KnownFunctionAddress;

  return realAddress-mapAddress;
}
0 голосов
/ 14 марта 2012

По какой-то причине я не могу ответить прямо на ответ Сума, но вы также можете просто сделать следующее:

extern "C" struct IMAGE_DOS_HEADER __ImageBase; // On platforms other than Win32/Win64, this MAY be a different header type...
...
printf_s("base: %p", &__ImageBase);

__ ImageBase определяется компоновщиком (по крайней мере, VC ++), и его адрес даст вам базовый адрес модуля (EXE / DLL), даже если он перемещен во время выполнения.

Там также

printf_s("calling module's base: %p\n", GetModuleHandle(NULL));

, который может дать вам то же базовое значение адреса ... но есть и другие предостережения для GetModuleHandle (плюс для этого требуется windows.h), поэтому я рекомендую просто придерживаться __ImageBase.

Как уже упоминали другие, ваша проблема, вероятно, связана с перемещением Windows вашего модуля. Если в файле модуля нет секции .reloc, то этот файл нельзя перемещать, и в этом случае это похоже на то, что вы бегаете на батутах или что-то вроде предложенного rwong.

0 голосов
/ 22 декабря 2011

Когда вы находитесь в отладчике и входите в код, можете ли вы проверить, находится ли адрес кода в пределах диапазона, который вы видите в окне «Модули»? Иногда один и тот же фрагмент кода может существовать в нескольких модулях с одинаковыми / разными именами.

После того как вы определили «Модуль», который содержит код, используйте базовый адрес из окна «Модули», чтобы получить (вычитая) адрес точки входа DLL.

Наконец, есть также эффект таблиц переходов при входе (батут), который является своего рода косвенным вызовом вызова функции, который может быть добавлен во время компиляции или во время выполнения. Таким образом, адрес «точки входа» может быть дымовой завесой и не соответствует адресу для тела функции.

(Мое понимание структуры DLL ограничено, поэтому в моем ответе могут быть неточности.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...