Поврежденное смещение в инструкции вызова

Последние несколько дней были потрачены на отладку очень странной проблемы. Приложение, созданное для i386, работающее в Windows, аварийно завершает работу, верхняя часть стека вызовов полностью повреждена, а указатель инструкций находится в бессмысленном месте.

После некоторых усилий я перестроил стек вызовов и смог определить, как IP-адрес оказался в бессмысленном месте. Инструкция в коде общего указателя boost пытается вызвать функцию, определенную в моей таблице адресов импорта DLL, используя неправильное смещение. Инструкция выглядит так:

call dword ptr [nonsense offset into import address table]

В результате выполнение оказалось в плохом месте, которое, к сожалению, было исполняемым. Затем выполнение продолжилось, поглощая вершину стека, пока в конечном итоге не завершилось сбоем.

Запустив идентичное приложение на моем ПК и вступив в проблемный код, я могу найти ту же инструкцию вызова и увидеть, что она должна выполняться, вызывая «новый» оператор msvc100.

Далее, сравнивая минидамп с ПК клиента на свой ПК, я обнаружил, что мой ПК вызывает функцию со смещением 0x0254 в адресной таблице. На клиентском ПК код пытается вызвать функцию со смещением 0x8254.

Что еще больше сбивает с толку, так это то, что это смещение исходит не из регистра или другого места в памяти. Смещение является константой в дизассемблировании. Итак, разборка выглядит так:

call dword ptr [ 0x50018254 ]

не как:

call dword ptr [ edx ]

Кто-нибудь знает, как это может произойти?


person Andrew    schedule 20.08.2011    source источник
comment
Вы открыли для себя ASLR, рандомизацию адресного пространства. Функция, созданная для того, чтобы вредоносное ПО не могло установить исправление программы. Ищите более типичную причину такой проблемы: переполнение буфера стека, которое уничтожило фрейм стека и перезаписало адрес возврата.   -  person Hans Passant    schedule 20.08.2011


Ответы (2)


Это однобитовый флип:

0x0254 = 0b0000001001010100
0x8254 = 0b1000001001010100

Возможно, повреждена память, поврежден диск, гамма-излучение от солнца...?

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

person HostileFork says dont trust SE    schedule 20.08.2011
comment
Мой коллега воспроизвел то, что выглядело как идентичный сбой на своем ПК, который затем перестал происходить. Мы тоже думали о плохой памяти, пока это не произошло. Я не эксперт в том, как Windows загружает библиотеки DLL и заполняет адрес, используемый в инструкции вызова, поэтому я не уверен, каким образом он может быть поврежден. - person Andrew; 20.08.2011

Мне кажется, это аппаратная ошибка, в основном ошибка памяти. Как отметил @Hostile_Fork, это просто немного флип.

Есть ли в вашей памяти функция ECC? это делает это, убедитесь, что он включен. Я бы прошел тест памяти с помощью memtest86, чтобы посмотреть, что произойдет, держу пари, у вас неисправный чип памяти, это не похоже на ошибку.

person ruhalde    schedule 20.08.2011