MyBooks.club
Все категории

Kris Kaspersky - Тонкости дизассемблирования

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Kris Kaspersky - Тонкости дизассемблирования. Жанр: Программирование издательство неизвестно,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
Тонкости дизассемблирования
Автор
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
17 сентябрь 2019
Количество просмотров:
149
Читать онлайн
Kris Kaspersky - Тонкости дизассемблирования

Kris Kaspersky - Тонкости дизассемблирования краткое содержание

Kris Kaspersky - Тонкости дизассемблирования - описание и краткое содержание, автор Kris Kaspersky, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Очень часто под рукой не оказывается ни отладчика, ни дизассемблера, ни даже компилятора, чтобы набросать хотя бы примитивный трассировщик. Разумеется, что говорить о взломе современных защитных механизмов в таких условиях просто смешно, но что делать если жизнь заставляет?..

Тонкости дизассемблирования читать онлайн бесплатно

Тонкости дизассемблирования - читать книгу онлайн бесплатно, автор Kris Kaspersky

Одно плохо — все эти приемы не работают под Windows и другими операционными системами. Это вызвано тем, что обработка исключения типа «Общее нарушение защиты» всецело лежит на ядре операционной системы, что не позволяет приложениям распоряжаться им по своему усмотрению. Забавно, но в режиме эмуляции MS-DOS некоторые EMS-драйверы ведут себя в этом случае совершенно непредсказуемо. Часто при этом они не генерируют ни исключения 0Ch, ни 0Dh. Это следует учитывать при разработке защит, основанных на приведенных выше приемах.

Обратим внимание так же и на последовательности типа 0x66 0x66 [xxx]. Хотя фирма intel не гарантирует корректную работу своих процессоров в такой ситуации, но фактически все они правильно интерпретируют такую ситуацию. Иное дело некоторые отладчики и дизассемблеры, которые спотыкаются и начинают некорректно вести себя.

Есть еще один интересный момент связанный с работой декодера микропроцессора.

Декодер за один раз считывает только 16 байт и, если команда «не уместиться», то он просто не сможет считать «продолжение» и сгенерирует исключение «Общее нарушение защиты». Однако, иначе ведут себя эмуляторы, которые корректно обрабатывают «длинные» инструкции.

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

Префиксы переопределения сегмента могут встречаться перед любой командой, в том числе и не обращающейся к памяти, например, CS:NOP вполне успешно выполнится. А вот некоторые дизассемблеры сбиться могут. К счастью, IDA Pro к ним не относится. Самое интересное, что комбинация 'DS: FS: FG: CS: MOV AX,[100]' работает вполне нормально (хотя это и не гарантируется фирмой Intel). При этом последний префикс в цепочке перекрывает все остальные. Некоторые отладчики, наоборот, ориентируются на первый префикс в цепочке, что дает неверный результат. Этот пример хорош тем, что великолепно выполняется под Windows и другими операционными системами. К сожалению, на декодирование каждого префикса тратится один такт, и все это может медленно работать.

Вернемся к формату кода операции. Выше была описана структура первого байта. Отметим, что она фактически не документирована, и Intel этому уделяет всего два слова. Формат разнится от одной команды к другой, однако, можно выделить и некоторые общие правила. Практически для каждой команды, если регистром-приемником фигурирует AX (AL), существует специальный однобайтовый код, который содержит в трех младших битах регистр-источник. Этот факт следует учитывать при оптимизации. Так, среди двух инструкций XCHGAX,BX и XCHG BX,DX следует всегда выбирать первую, т.к. она на байт короче. (Кстати, инструкция XCHGAX,AX более известна нам как NOP. О достоверности этого факта часто спорят в конференциях, но на странице 340 руководства №24319101 «Instruction Set Reference Manual» фирмы Intel это утверждается совершенно недвусмысленно. Любопытно, что, выходит, никто из многочисленных спорщиков не знаком даже с оригинальным руководством производителя).

Для многих команд условного перехода четыре младших бита обозначают условие операции. Точнее говоря, условие задается в битах 1-3, а установка бита 0 приводит к его инверсии (таблица 1).



Как видим, условий совсем немного, и проблем с их запоминанием обычно не возникает. Теперь уже не нужно мучительно вспоминать 'jz' — это 74h или 75h. Так как младший бит первого равен нулю, то 'jz' — это 74h, а 'jnz', соответственно, 75h.

Далеко не все коды операций смогли поместиться в первый байт. Инженеры Intel задумались о поиске дополнительного места для размещения еще нескольких бит и обратили внимание на байт modR/M. Подробнее он описан ниже, а пока рассмотрим приведенный выше рисунок (рис. 1). Трех-битовое поле reg, содержащие регистр-источник, очевидно, не используется, если вслед за ним идет непосредственный операнд. Так почему бы его не использовать для задания кода операции? Однако, процессору требуется указать на такую ситуацию. Это делает префикс '0Fh', размещенный в первом байте кода. Да, именно префикс, хотя документация Intel этого прямо и не подтверждает. При этом на не-MMX процессорах для его декодирования требуется дополнительный такт. Intel же предпочитает называть первый байт основным, а второй уточняющим кодом операции. Заметим, что это же поле используют многие инструкции, оперирующие одним операндом (jmр, call). Все это очень сильно затрудняет написание собственного ассемблера/дизассемблера, но зато дает простор для создания самомодифицирующегося кода и, кроме того, вызывает восхищение инженерами Intel, до минимума сокративших размеры команд. Конечно, это досталось весьма непростой ценой. И далеко не все дизассемблеры работают правильно. С другой стороны именно благодаря этому и существуют защиты, успешно противостоящие им.

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

К тонкостям кодирования команд мы еще вернемся, а пока приготовимся к разбору поля modR/M. Два трехбитовых поля могут задавать код регистра общего назначения по следующей таблице (таблица 2):




Опять можно восхищаться лаконичностью инженеров Intel, которые ухитрились всего в трех битах закодировать столько регистров. Это, кстати, объясняет, почему нельзя выборочно обращаться к старшим и младшим байтам регистров SР, BР, SI, DI и, аналогично, к старшему слову всех 32-битных регистров. Во всем «виновата» оптимизация и архитектура команд. Просто нет свободных полей, в которые можно было бы «вместить» дополнительные регистры. Сегодня мы вынуждены расхлебывать результаты архитектурных решений, выглядевшими такими удачными всего лишь десятилетие назад.

Обратите внимание на порядок регистров: AX, CX, DX, BX, SР, BР, SI, DI. Немного не по алфавиту, верно? И особенно странно в этом отношении выглядит регистр BX. Но, если понять причины, то никакой нужны запоминать это исключение не будет, т.к. все станет на свои места: BX — это индексный регистр, и первым стоит среди индексных.

Таким образом, мы уже можем «вручную» без дизассемблера распознавать в шестнадцатеричном дампе регистры-операнды. Очень неплохо для начала! Или писать самомодифицирующийся код. Например:



Он изменит 6 строку на XOR SP,SP. Это «завесит» многие отладчики, и, кроме того, не позволит дизассемблерам отслеживать локальные переменные адресуемые через SР. Хотя IDA Pro и позволяет скорректировать стек вручную, для этого надо сначала понять, что SР обнулился. В приведенном примере это очевидно (но в глаза, кстати, не бросается), а если это произойдет в многопоточной системе? Тогда изменение кода очень трудно будет отследить, особенно в листинге дизассемблера. Однако, нужно помнить, что самомодифицирующийся код все же уходит в историю. Сегодня он встречается все реже и реже.



Первоначально сегментные регистры кодировались всего двумя битами и этого с вполне хватало, т.к. их было всего четыре. Позже, когда количество их увеличилось, перешли на трехбитную кодировку. При этом две кодовые комбинации (110b и 111b) в настоящее время не применяются и вряд ли будут добавлены в ближайшем будущем. Но что же будет, если попытаться их использовать? Генерация INT 06h. А вот отладчики-эмуляторы могут вести себя странно. Одни не генерируют при этом прерывания, чем себя и выдают, а другие — ведут себя непредсказуемо, т.к. при этом требуемый регистр может находится в области памяти, занятой другой переменной (это происходит, когда ячейка памяти определяется по индексу регистра, при этом считываются три бита и суммируются с базой, но никак не проверяются пределы).



Кстати, IDA Pro вообще отказывается анализировать весь последующий код. Как это можно использовать? Да очень просто — если эмулировать еще два сегментных регистра в обработчике INT 06h, то очень трудно это будет как отлаживать, так и ди-зассемблировать программу. Однако, это опять-таки не работает под win32!

Управляющие/отладочные регистры кодируются нижеследующим образом:



Заметим, что коды операций mov, манипулирующих этими регистрами, различны, поэтому-то и возникает кажущееся совпадение имен. С управляющими регистрами связана одна любопытная мелочь. Регистр CR1, как известно большинству, в настоящее время зарезервирован и не используется. Во всяком случае, так написано в русскоязычной документации. На самом деле регистр CR1 просто не существует! И любая попытка обращения к нему вызывает генерацию исключение INT 06h. Например, cuр386 в режиме эмуляции процессора этого не учитывает и неверно исполняет программу. А все дизассемблеры, за исключением IDA Pro, неправильно дизассемблируют этот несуществующий регистр:


Kris Kaspersky читать все книги автора по порядку

Kris Kaspersky - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


Тонкости дизассемблирования отзывы

Отзывы читателей о книге Тонкости дизассемблирования, автор: Kris Kaspersky. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.