Re[7]: Программа крэшится до точки входа, на стадии загрузки
От: okman Беларусь https://searchinform.ru/
Дата: 01.03.18 08:04
Оценка: 8 (3)
Здравствуйте, CaptainFlint, Вы писали:

CF>...

CF>Эх, как бы эти "третьи силы" теперь ущучить… желательно без ядерного отладчика и без "раздевания" системы от всех установленных программ…

Кажется, я начинаю догадываться, в чем может быть дело.
У приложения нет секции .reloc (релоков), т.е. исполняемый модуль не поддерживает загрузку по произвольному адресу:

(все лишнее поскипано)

> !dh hideconsole_hdls
       
SECTION HEADER #1
   .text name

       0 file pointer to relocation table
       0 number of relocations

SECTION HEADER #2
  .rdata name

SECTION HEADER #3
  .pdata name

SECTION HEADER #4
   .rsrc name


Но при этом указаны флаги 'Dynamic base' и 'High entropy VA supported', работа которых основывается как раз
на релокациях исполняемого модуля в памяти по рандомным адресам:

OPTIONAL HEADER VALUES

    8160  DLL characteristics
            High entropy VA supported
            Dynamic base
            NX compatible
            Terminal server aware


Также важно, что в заголовке не указан флаг 'Relocations stripped' (см. опцию /FIXED компоновщика), по которому
система могла бы точно понять, что приложение должно загружаться по строго фиксированному адресу:

FILE HEADER VALUES

      22 characteristics
            Executable
            App can handle >2gb addresses
         -> нету здесь больше ничего :)


Косвенно на проблему указывает это: "когда я ради эксперимента переделал проект на CRT-шный, проблемы прекратились".
Как я понимаю, CRT добавляет секцию .reloc.

И еще одно наблюдение (подсмотрено в дампе).

Команда !dh выдает 13f310000 image base, т.е. 13f310000 — предпочтительный адрес загрузки модуля в память.
Сам модуль был загружен (и релоцирован) по адресу 13f720000 (команда lmv m hideconsole_hdls).
А исключение возникло при попытке доступа к адресу 13fb31000 (см. !analyze -v).

Так вот, 13f720000 — 13f310000 = 410000.
Но что интересно, 13fb31000 — 13f720000 = 411000.
Т.е. разница между предпочтительным и реальным адресом загрузки модуля такая же, как между реальным адресом
загрузки и адресом, где произошло исключение. 1000 не в счет, это оффсет от начала загрузки модуля до точки входа.

Вот только я уж и не знаю, баг ли это в системе или в Visual Studio, которая позволяет
задавать "противоречивые" настройки компоновки...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.