5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...


^ 5.1. Методы внедрения

Записать нужные аннотации в исполняемый код можно несколькими методами:


^ 5.1.1. Принципно вероятные 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... методы внедрения

Начать можно со метода, который содержит в себе физическое изменение PE файла на жестком диске. Т.е. еще не загруженный файл мы должны проанализировать, добавить в него наш код, выслать на выполнение 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... и неким методом получать нужную нам информацию. В данном случае файл модифицируется только в один прекрасный момент, но на техническом уровне воплотить это очень трудно из-за того, что полный разбор 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... генерируемого собирателями кода – очень томная задачка, требующая написания эмулятора выполнения, и даже если такая работа будет произведена, это не обережет программку от вероятных ошибок, возникающих после прибавления в нее новых инструкций 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих.... Нужен контроль за действиями программки, которые могут привести к ее краху, и своевременное предупреждение юзера о их.

Дальше разглядим метод, в каком конфигурации вносятся в адресное место процесса, т.е. уже после загрузки 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... исполняемого модуля в память. В данном случае нам раскрывается большущее огромное количество средств для заслуги нашей цели.

Один из вероятных методов внедрения в чужой код – конкретное редактирование физической памяти либо страничного файла 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... (файла подкачки). Этот метод очень привязан к архитектуре системы, и для реализации необходимо иметь полное представление о принципах ее работы. Итак, представим, что программка загружена в память, и мы желаем внести в ее 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... исполняемый код некие конфигурации. Начнем с того, что в хоть какой момент времени, кроме неких случаев (ОС может по тем либо другим причинам воспрещать выгрузку страничек), нужная нам страничка может находиться 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... как в оперативки, так и быть выгруженной на диск. Последующая неувязка заключается в необратимости процесса трансляции виртуального адреса в физический, который был описан в параграфе 1.3.3 “Страничная организация памяти”. Архитектура микропроцессора позволяет проводить 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... преобразование исключительно в одну сторону, в оборотную сторону аппаратной реализации не существует (для промышленных нужд не нужна), потому придется делать это самим. Из-за таких особенностей системы, задачка существенно усложняется. К счастью, в Windows 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... NT существует довольно средств, чтоб избежать настолько близкого общения с операционной системой. К тому же, в Windows прямой доступ к физической памяти (объект Device\PhysicalMemory) из пользовательского режима был 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... запрещен [$17$]. Этот способ можно удачно использовать [$18$] разве что в вирусах и троянах, так как им не надо создавать очень кропотливый анализ памяти: в большинстве случаев они обходятся поиском заблаговременно определенных сигнатур.


^ 5.1.2. Реализуемый способ

В методе, которому 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... посвящена эта работа, мы не будем воспользоваться такими низкоуровневыми особенностями системы и писать собственные драйвера.

Использовать способ можно будет:

В первом случае наш код будет загружаться в адресное место тестируемого процесса средствами OC как DLL модуль при помощи вызова системной 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... API функции – LoadLibrary (этот вызов должен выполняться самой программкой). Потом при выполнении процесс будем останавливать, рассматривать с текущего положения (положение определяется регистром EIP) как это может быть, создавать копию этой части кода с 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... необходимыми нам переменами и продолжать выполнение уже на этом сделанном наборе команд, ждя пока микропроцессор не передаст выполнение на неанализированный код, что повлечет за собой очередной пуск метода анализа бинарного исполняемого 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... кода. Более тщательно процесс внедрения будет описан дальше.

Во 2-м случае довольно особенным методом загрузить вышеуказанную DLL в адресное место процесса. Это будет выполняться с внедрением системных API: выделение памяти в чужом 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... адресном пространстве (VirtualAllocEx), запись данных в эту память (WriteProcessMemory) и создание потока, принадлежащего чужому процессу (CreateRemoteThread).


^ 5.2. Способ модификации кода

В нашем способе мы не будем изменять исполняемый код – мы будем его писать в памяти 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... поновой, только с подходящими нам переменами. Опишем более тщательно этапы работы способа.


^ 5.2.1. Глобальный обработчик исключений

Первым шагом способа будет созданием процедуры, которая получает управление при любом возникающем в процессе исключения.

Существует два механизма 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... Win32 обработки исключений:

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

Весь цикл жизни исключений [$21$] в системе смотрится так:

  1. Микропроцессор генерирует исключение.

  2. Ядро операционной системы 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... перехватывает и обрабатывает сгенерированное исключение.

  3. Управление передается функции KiUserExceptionDispatcher из системной библиотеки ntdll.dll, расположенной на прикладном уровне. В качестве характеристик в стек помещаются структуры, содержащие описание исключения (EXCEPTION_RECORD) и контекст 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... потока на момент генерации микропроцессором исключения (CONTEXT).

  4. Дальше приложение, используя один из 2-ух устройств – SEH либо VEH, обрабатывает исключение (либо не обрабатывает, что приводит к аварийному окончанию программки)

Из 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... этого больше всего нас будет заинтересовывать функция KiUserExceptionDispatcher. Все исключения, которые попадают на пользовательский уровень, проходят через эту функцию. Как следует, необходимо научиться перехватывать ее вызовы.

Введем понятие сплайсинга функций [$22$]. Грубо говоря 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., сплайсинг это замена кода функции. Этот способ нередко применяется при перехвате вызовов API функций: определяется адресок перехватываемой функции, и её 1-ые 5 б заменяются длинноватым JMP – переходом по адресу обработчика.



На схеме видно, что 1-ые три 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... аннотации функции заменяются на одну пятибайтовую аннотацию JMP – переход уже на наш код, в каком можно сделать все что угодно. На примере, изображенном на схеме, мы поначалу сохраняем все 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... регистры в стеке аннотацией PUSHAD (по мере надобности можно еще сохранять там же флаги – аннотация PUSHF), вызываем обработчик, за ранее поместив в стек его характеристики, восстанавливаем значения регистров (аннотация POPAD), а потом начинаем выполнение перекрытых 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... инструкций и остального кода, будто бы и не было никакого внедрения.

Этим приемом воспользуемся и мы. Чтоб перехватить все пользовательские исключения, возникающие в процессе, применим способ сплайсинга API функций 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... для функции KiUserExceptionDispatcher.


^ 5.2.2. Блокировка секций кода

Разглядим функцию VirtualProtect [$26$] из библиотеки kernel32.dll. Она позволяет изменять атрибуты защиты обозначенного региона виртуального адресного места. В качестве 1-го из характеристик ей передается 4-х байтовое число – атрибуты защиты [$27$]:

На всякий случай снова повторимся, что при 32-битной страничной адресации на микропроцессорах конторы Intel атрибуты чтения и выполнения на сто процентов эквивалентны, потому нереально запретить чтение при установленных 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... правах на выполнение и напротив.

Итак, при запуске PE файла, каждой секции, загружаемой в память, проставляются атрибуты защиты, которые зависят от соответственного параметра в заголовке секции. Тот же параметр определяет, содержит ли секция код 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... либо данные (по правде сказать, если проставлен флаг секции кода, то это еще ничего не означает, потому будем полагаться на добросовестность компоновщика).

Итак, вторым шагом в способе будет проставление всем страничкам 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... секций кода атрибута PAGE_NOACCESS, при всем этом хоть какое воззвание к ним будет инициализировать в микропроцессоре исключение #GP либо Access Violation на пользовательском уровне, которое мы сможем перехватить при помощи 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... нашего глобального обработчика исключений.


^ 5.2.3. Инициализация управляющего исключения

После блокировки секций кода, хоть какое воззвание к страничкам памяти, относящимся к этим секциям, будет вызывать исключение. Потому во всех потоках процесса, в каких на 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... этот момент исполняется код данного модуля, будет инициализировано управляющее исключение и управление передастся глобальному обработчику исключений.


^ 5.2.4. Перехват управляющего исключения

Представим, что глобальный обработчик изловил исключение. Проверим, что:

Если не выполнено 1-ое 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... условие, то исключение было вызвано кое-чем другим в программке, не из-за выполненных модификаций. Исключение нужно передать далее функции KiUserExceptionDispatcher.

Если же не выполнено 2-ое условие, то необходимо проверить адресок, к которому происходило воззвание 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих.... В случае, если адресок показывает не на секцию кода, то ошибка произошла не по нашей вине, и необходимо передать исключение далее. В неприятном случае делаем вывод, что в секции 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... кода содержатся данные. Здесь нам ничего не остается, как снять запрет на доступ к страничке либо окончить приложение.

Итак, если оба условия выполнены, то делаем вывод о том, что нам пришло управляющее исключение 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих....


^ 5.2.5. Пошаговый анализ тестируемого кода

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

Начнем со второго варианта – код не обрабатывался. Тогда начинаем анализ машинного кода, начиная с этого адреса. Естественно, необходимо за ранее сохранить раздельно 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... все содержимое секций кода (из-за того, что из заблокированных страничек чтение будет запрещено и нашему коду). Имея на руках дизассемблер длин инструкций (“аппарат”, который рассматривает машинный код микропроцессора только для оценки количества б 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., которые занимает текущая команда, и определяет, когда начинается последующая аннотация), будем просматривать команду за командой, уделяя повышенное внимание операторам перехода:

Для всех переходов существует два метода использования: переход по фиксированному 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... и вычисляемому адресу. Когда адресок фиксирован, то на шаге анализа мы можем проанализировать и код, на который осуществляется переход. Другая ситуация обстоит с вычисляемыми переходами (к примеру, аннотации ”CALL_EAX” либо 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... ”JMP_[ECX_+_0x4]”). Их можно повстречать, к примеру, в реализации виртуальных способов. В данном случае предстоящий статический анализ неосуществим. Но в этом нет ничего ужасного: переход осуществляется по абсолютному адресу, и на 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... этот абсолютный адресок перемещение кода никак воздействовать не может (есть маленькие аспекты в этом утверждении, о их чуток позднее). Т.е. если выполнение такого же кода будет происходить по другому адресу 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., то адресок перехода не поменяется, и после перехода в секцию кода опять будет инициализировано управляющее исключение, после этого можно продолжать анализ.

Принципиально учесть участки в начальном коде, которые уже были проанализированы. При инициации управляющего 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... исключения на их, повторную обработку проводить не надо. Для этого будем неким образом сопоставлять адреса инструкций в PE файле и адреса инструкций в коде, который был сгенерирован во время анализа 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... (с внедренными T-инструкциями), и при перехвате вышеупомянутого исключения довольно будет просто отыскать соответственный адресок в сгенерированном коде и передать на него управление.


^ 5.2.6. Внедрение T-кода

Мы обрисовали процесс анализа кода. Наряду с 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... ним будет проводиться построение измененного кода. Таковой код должен работать точно так же, как и соответственный ему код в PE-файле, но при всем этом должен содержать дополнительные аннотации, задачей которых и будет произведение 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... нужных вычислений, инкрементирование счетчиков.

При тестировании программки мы будем в ней для каждой аннотации определять количество раз, сколько она была исполнена. Для этого в код будут встраиваться команды, которые будут 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... наращивать заблаговременно сделанные счетчики. Но мы не будем вставлять T-инструкции перед каждой аннотацией в тестируемом коде – это очень очень скажется на скорости выполнения программки. Можно создать огромное количество алгоритмов и структур данных 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... для размещения и резвого воззвания к этим счетчикам. При всем этом необходимо учесть последующие нюансы:


^ 5.2.7. Продолжение выполнения программки

Вот мы выстроили и записали в память код с необходимыми нам модификациями. Осталось только передать на него выполнение 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... – сбор инфы будет происходить автоматом!


^ 5.2.8. Маскировка внесенных конфигураций

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

В нашем случае, из-за 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... суровых ограничений на анализируемую программку и из-за очень очевидных конфигураций в коде, программка, которая специально делает проверки целостности, наверное обусловит, что к ней кто-то прицепился. Но у нас малость другая задачка: внести 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... в код нужные нам конфигурации так, чтоб с большой вероятностью он остался рабочим.

Разглядим два варианта, которые могут привести к крушению программки.

1) После того, как выполнение кода переместилось из секций 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... кода PE файла в память, выделенную из кучи, поменялось поведение инструкций CALL – они стали помещать в стек не те адреса, что ранее. Естественно, маловероятно, что эти изменившиеся адреса на что-то воздействую, но не 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... исключено, что некий очень хитрецкий компилятор не решит инспектировать их, чтоб “побороть” вероятную уязвимость переполнения буфера.

Решение. Все CALL аннотации подменять на сочетание инструкций PUSH и JMP – такая подмена эквивалентна, если не 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... учесть флаг NT, который употребляется для переключения задач [$29$]. После того, как выполнится соответственная аннотация RET, управление передастся на заблокированный код, так как в стек аннотацией PUSH был помещен таковой адресок 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... возврата, какой он был бы, если не было бы никаких модификаций. Ну а далее будет вызвано управляющее исключение, и можно продолжать выполнение программки.

2) 2-ой случай состоит в том, что измененный код как и 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... раньше способен генерировать исключения, как штатные, так и внештатные. И лучше приложению не демонстрировать реальный адресок, по которому появилось исключение.

Решение. Будем просто в глобальном обработчике заменять адресок появления исключения и сохраненный 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... регистр EIP. Для этого должна быть реализована оборотная трансляция адреса из измененного кода в адресок в начальном коде.


^ 5.2.9. Уменьшение числа управляющих исключений

Активное внедрение исключений в приложениях может сказаться на ее производительности 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., а откровенное злоупотребление может замедлить так, что программка будет зависать на ровненьком месте. Это вызвано тем, что производится много маленькой работы: проверки и определение, кому далее передавать исключение, запись в стек состояния потока (регистры, флаги 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...) и инфы об исключении, переключение меж режимом ядра и пользовательским режимом и проч. В итоге тратятся тыщи тактов микропроцессора, что, при неких обстоятельствах, может стать очень значимым.

В конце параграфа 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... 5.2.5 “Пошаговый анализ тестируемого кода” упоминалось о сравнении адресов инструкций в начальном и измененном кодах. Это мы и будем использовать для оптимизации использования исключений.

При использовании инструкций переходов по вычисляемым адресам и 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., беря во внимание предшествующий параграф, аннотации RET, происходит переход на код, который принадлежит заблокированной секции кода PE файла, что сразу вызывает управляющее исключение.

В качестве решения этой трудности можно использовать таковой вариант: заместо того, чтоб 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... совершить переход по вычисленному адресу, будем помещать этот адресок в стек (кстати, для варианта с аннотацией RET адресок перехода уже находится в стеке) и вызывать нашу свою функцию, в 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... какой будем находить соответственный адресок в измененном коде и передавать на него управление. Необходимо отметить, что поиск подходящего адреса в любом случае пришлось бы делать, но в таком случае мы не тратим время 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... на ненадобную обработку исключения в ядре системы.


^ 5.2.10. Визуализация результатов профилировки

Итак, наполнив тестируемый код нашими инструкциями, мы получим аналогичную программку, но она, в дополнение ко всему, собирает статистическую информацию о ходе собственного выполнения 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих....

Осталось только сделать ее вывод в комфортном виде. Здесь есть огромное количество вариантов и их композиций:

^ 6. Реализация способа

Программирование описанного способа будет происходить в среде 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... разработки Microsoft Visual Studio 2008 с внедрением языка C++ с ассемблерными вставками.

Как уже упоминалось, вся логика способа будет запрограммирована в одном DLL файле для того, чтоб без особенного труда загрузить в адресное место 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... процесса весь код, что мы будем использовать для анализа.


^ 6.1. Глобальный обработчик исключений

Итак, при загрузке DLL файла в память происходит вызов функции DllMain [$30$]. DllMain – дополнительная точка входа в динамически-подключаемую библиотеку, управление на которую 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... передается тогда, когда процесс либо поток инициализируется либо заканчивает работу, также при вызове функций LoadLibrary и FreeLibrary.

Синтаксис функции DllMain:

BOOL WINAPI DllMain(

__in HINSTANCE hinstDLL, // дескриптор модуля DLL

__in DWORD fdwReason, // причина 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... вызова функции

__in LPVOID lpvReserved // зарезервированный

);

Вот в этой функции мы и будем создавать внедрение перехватчика исключений, когда DLL файл загружается в память процесса (ну и, естественно, нельзя забывать про снятие этого обработчика при 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... выгрузке DLL из памяти).

Поначалу выделим кусок памяти нужный для сплайсинга функции KiUserExceptionDispatcher:

UCHAR code[0x40] = {

0xFF, 0x74, 0x24, 0x04, // 0x00: PUSH [ESP + 4]

0xFF, 0x74, 0x24, 0x04, // 0x04: PUSH [ESP + 4]

0x 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...00, 0x00, 0x00, 0x00, 0x00, // 0x08: CALL handler

0x85, 0xC0, // 0x0D: TEST EAX, EAX

0x74, 0x0F, // 0x0F: JZ not_processed

0x6A, 0x00, // 0x11: PUSH 0x00

0xFF, 0x74, 0x24, 0x08, // 0x13: PUSH [ESP + 8]

0x00, 0x 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...00, 0x00, 0x00, 0x00, // 0x17: CALL NtContinue

0xCC, 0xCC, 0xCC, 0xCC, // 0x1C: code alignment

// not_processed:

0x00, 0x00, 0x00, 0x00 // 0x20: instructions from

// KiUserExceptionDispatcher

// beginning and JMP to

// KiUserExceptionDispatcher

// continue

};

Итак, 1-ые две аннотации записывают в стек 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... аргументы для нашего глобального обработчика исключений. Вот его сигнатура:

BOOL WINAPI GlobalExceptionHandler(

PEXCEPTION_RECORD pExcptRec,

CONTEXT* pContext

);

Дальше оставлено 5 свободных б для аннотации, которая передаст управления обработчику. 1-ый б – 0xE8 (опкод аннотации CALL 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...), а байты со второго по 5-ый должны содержать относительный адресок функции-обработчика. Его можно вычислить так: – – 5.

Дальше происходит проверка возвращенного значения. Если это значение не ноль, то будет вызвана функция NtContinue 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... из библиотеки ntdll.dll, которая восстанавливает состояние, в каком находился поток во время появления исключения. Это сохраненное состояние, состоящее из регистров и флагов, мы с легкостью могли поменять в глобальном обработчике. Если же функция возвратила 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... ноль, то будут произведен переход по метке “not_processed”. Поместим под этой меткой 1-ые аннотации функции KiUserExceptionDispatcher, которые нам придется перекрыть одной аннотацией JMP, занимающей 5 б. И после чего блока инструкций 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... поместим команду JMP для продолжения выполнения функции KiUserExceptionDispatcher.

Осталось только, используя API функцию VirtualProtect, разрешить запись в область памяти, в какой находится KiUserExceptionDispatcher, и переписать 1-ые 5 б, заменив их аннотацией JMP, осуществляющую переход 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... на начало блока code, который был описан выше.

Таким макаром, хоть какое исключение, возникшее в процессе, будет здесь же перехвачено и передано глобальному обработчику.

Принципиально будет упомянуть о том, что на 1-ые 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... 5 б функции KiUserExceptionDispatcher может прийтись нецелое число инструкций. Потому мы будем использовать дизассемблер длин (см. параграф 6.2 “Дизассемблер длин инструкций”) для определения инструкций, которые будут перекрыты командой JMP. Также необходимо разглядеть случай, когда 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... посреди их встречается аннотация перехода. Возможность этого близка к нулю, но все таки нужно добавить надлежащие проверки, чтоб не допустить сплайсинг и сказать юзеру о невозможности внедрения обработчика.


^ 6.2. Дизассемблер длин 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... инструкций

Очень принципиальной составляющей частью анализатора является дизассемблер длин инструкций. Это одна функция, которая определяет, какое количество б занимает текущая аннотация и с какой позиции начинается последующая. Заметим, что при установке глобального 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... обработчика исключений этот инструмент также нужен. Если конкретнее, то его употребляют для определения первых инструкций функции KiUserExceptionDispatcher, которые будут замещены аннотацией JMP.

Для намеченной цели будем использовать стороннюю разработку [$31$]. Она представляет собой одну 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... функцию на языке C++:

bool GetInstructionSize(

PBYTE pOpCode,

PDWORD pdwInstructionSize

);

Функция воспринимает в качестве характеристик указатель на начало аннотации в памяти и указатель на 4-х байтовую переменную, в которую будет записываться результирующая 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... длина аннотации. Возвращаемое значение – удачно ли определена длина.


^ 6.3. Фильтрация управляющих исключений

В параграфе 6.1 “Глобальный обработчик исключений” была упомянута сигнатура глобального обработчика: в качестве характеристик функции передается указатель на структуру EXCEPTION_RECORD (содержит информацию 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... об исключении) и указатель на структуру CONTEXT (сохраненный контекст потока).

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

Во-1-х, исключение должно быть типа Access Violation 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...:

if (pExcptRec -> ExceptionCode == EXCEPTION_ACCESS_VIOLATION)

Константа EXCEPTION_ACCESS_VIOLATION определена в заголовочном файле WinNT.h и равна 0xC0000005.

Во-2-х, адресок появления исключения должен совпадать с адресом, воззвание по которому вызвало ошибку:

if 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... ((DWORD)(pExcptRec -> ExceptionAddress) ==

pExcptRec -> ExceptionInformation[1]))

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


^ 6.4. Внедрение T 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...-кода

Итак, перехватив управляющее исключение и определив адресок аннотации, которая его инициализировала, начинаем анализ начального кода и построение измененного кода, начиная с этой аннотации.


^ 6.4.1. Анализ начального кода

Как уже упоминалось в параграфе 5.2.5 “Пошаговый анализ 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... тестируемого кода”, перед блокировкой страничек секций кода, нужно сделать копию данных, содержащихся в их, т.к. после блокировки доступ к ним будет запрещен как самой программке, так и нашей библиотеке.

Итак 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., у нас есть адресок аннотации, которая вызвала управляющее исключение. Начинаем анализ с нее.

Для намеченной цели довольно будет выслеживать только аннотации, выполнение которых может вызвать переход на аннотацию, находящуюся не конкретно 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... за этой. К такому типу инструкций относятся CALL, JMP, Jxx, LOOP_/_LOOPxx и RET. После выполнения на микропроцессоре других инструкций, регистр EIP передвигается на последующую аннотацию в памяти. Есть, естественно, аннотации 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... SYSENTER, INT_3 и некие другие, которые также нарушают линейность выполнения машинного кода, но из-за особенности построения измененного кода будем относить их к “обыденным” инструкциям.

Сам анализ будет происходить поочередно, аннотация за аннотацией, в 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... том порядке, в каком они находятся в памяти. И для того чтоб иметь возможность рассматривать код, который находится в ветвлениях этого метода, сделаем перечень адресов, хранящий адреса инструкций, с которых следует начинать очередной 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... процесс анализа. Вначале в этот перечень помещается единственный адресок – адресок аннотации, которая инициализировала управляющее исключение. В предстоящем туда будут помещаться адреса команд, на которые осуществляется переход отысканными при анализе инструкциями вышеупомянутого типа 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... (если для их очевидно указан относительный адресок перехода). На каждой итерации будем извлекать из начала этого перечня адресок (сразу удаляя его оттуда). Когда перечень станет пустым, анализ можно считать законченным.

А от 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... самого анализа требуется только поиск и систематизация обозначенных выше инструкций. Эта информация будет употребляться для построения измененного кода.

Основной проход анализа можно отыскать в приложении 10.5 “Процедура анализа”.


^ 6.4.2. Построение измененного кода

Измененный 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... код будем строить в специально выделяемой для этого памяти. Для этого будем при необходимости постранично выделять память. Когда еще одна порция измененного кода не будет помещаться в последнюю выделенную страничку, то 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... необходимо выделить новейшую страничку памяти, записать туда измененный код и связать предшествующую страничку с ней аннотацией перехода JMP.

Ниже приведено описание класса code_row, который будет заниматься построением кода. На каждый исполняемый модуль 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., загруженный в память, создается менее 1-го объекта этого типа.


^ Листинг описания класса code_row (файл code_row.h)


class code_row {

private:

typedef std::map
addr_map;

page_pool pages;

addr_map trans 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., trans_r;

addr_map reloc;

void *curr_page;

int curr_len, curr_pos;

char *get_curr();


void add_page(int add_len);

void add_reloc_addr(PVOID dest, PVOID real_addr);

void add 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..._reloc_jmp(UCHAR op_code, PVOID real_addr);

void add_reloc_calc_jmp(USHORT op_code, PVOID real_addr);


public:

code_row();

void add_instr(PVOID instr, int instr_len, PVOID instr_addr 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих...);

void add_call(PVOID instr, int instr_len, PVOID instr_addr);

void add_jmp(PVOID instr, int instr_len, PVOID instr_addr);

void add_comp_jmp(PVOID instr, int instr_len 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..., PVOID instr_addr);

void add_loop(PVOID instr, int instr_len, PVOID instr_addr);


void update_reloc();


PVOID get_trans_addr(PVOID real_addr);

PVOID get_trans_r_addr(PVOID addr);

};


Адресок в 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... репозитории:

http://willzyx-edu-project.googlecode.com/svn/trunk/Proj1/src/profiler/code_row.h


Опишем поля и способы, что содержатся в этом классе:

loop_start:



LOOP/LOOPE/LOOPNE loop_start

LOOP

LOOPE

LOOPNE

0xE2

0xE1

0xE0

loop_start:



PUSHF

DEC ECX

JZ @1

POPF

JMP loop_start

@1:

POPF

loop 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих..._start:



PUSHF

JNZ @1

DEC ECX

JZ @2

POPF

JMP loop_start

@1:

DEC ECX

@2:

POPF

loop_start:



PUSHF

JZ @1

DEC ECX

JZ @2

POPF

JMP loop_start

@1:

DEC ECX

@2:

POPF

Потому 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... во время анализа для построения кода должны вызываться надлежащие функции прибавления инструкций. После того как весь перечень ответвлений (параграф 6.4.1 “Анализ начального кода”) будет проанализирован, нужно обновить все относительные адреса в сгенерированном 5.1. Способы внедрения - Продолжение исполнения программы Маскировка внесенных изменений Уменьшение числа управляющих... коде.



5-sherohovatost-poverhnostej-metodicheskie-ukazaniya-k-kursovomu-proektirovaniyu-po-tehnicheskoj-i-prikladnoj-mehanike.html
5-sistema-meropriyatij-po-realizacii-kip-modernizacii-monoprofilnogo-muncipalnogo-obrazovaniya-gorod-tinda.html
5-sistemi-demograficheskie-sistemi-posobie-adresovano-studentam-istorikam-magistrantam-aspirantam-v-programmu.html