Уроки Iczelion'а



Урок 2. Правильность PE файла - часть 3


SEHHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD mov edx,pFrame assume edx:ptr SEH mov eax,pContext assume eax:ptr CONTEXT push [edx].SafeOffset pop [eax].regEip push [edx].PrevEsp pop [eax].regEsp push [edx].PrevEbp pop [eax].regEbp mov ValidPE, FALSE mov eax,ExceptionContinueExecution ret SEHHandler endp end start

Анализ:

Программа открывает файл и проверяет, является ли DOS-заголовок верным, если это так, она проверяет, является ли PE-заголовок верным. Если и это так, она pешает, что данный файл - PE. В этом примере я использовал structured exceрtion handling (SEH), поэтому мы не должны проверять любую возможную ошибку, если ошибка происходит, мы предполагаем, что она произошла из-за того, что файл не являлся верным PE. Windows сама по себе очень интенсивно использует SEH в своих процедурах обработки параметров. Если вы заинтересовались SEH'ом, читайте соответствующую статью Jeremy Gordon'а.

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

assume fs:nothing push fs:[0] pop seh.PrevLink mov seh.CurrentHandler,offset SEHHandler mov seh.SafeOffset,offset FinalExit lea eax,seh mov fs:[0], eax mov seh.PrevEsp,esp mov seh.PrevEbp,ebp

Мы начинаем с того, что устанавливаем pежим использования регистра fs "nothing". Потом мы сохраняем адрес предыдущего SEH-обработчика в нашей структуре для использования Windows. Мы сохраняем адрес нашего SEH-обработчика, адрес где стартует обработка исключения, если происходит ошибка, текущие значения esр и ebр, так что наш SEH-обработчик может получить состояние нормально состояние стека перед тем, как продолжать программу.

mov edi, pMapping assume edi:ptr IMAGE_DOS_HEADER .if [edi].e_magic==IMAGE_DOS_SIGNATURE

После установления SEH'а, мы продолжаем проверку. Мы устанавливаем адрес первого байта файла в edi, который является первым байтом DOS-заголовка. Для простоты сравнения, мы говорим ассемблеру, что он может допустить, что edi указывает на структуру IMAGE_DOS_HEADER (что является правдой). Затем мы сравниваем первое слово DOS-заголовка со строкой "MZ", которая определена в windows.inc под названием IMAGE_DOS_SIGNATURE. Если сравнение положительно, мы переходим к PE-заголовку. Если нет, то мы устанавливаем значение ValidPE в FALSE, то есть что файл не является Portable Executable.




Содержание  Назад  Вперед