Главная страница
Навигация по странице:

  • 6.2. Дизассемблирование программ с помощью интерактивного дизассемблера

  • Рис. 6.2. Рабочий интерфейс дизассемблера Ida Pro

  • Рис. 6.3. Код исследуемого файла

  • Лекции. Введение. Защита программного обеспечения от несанкционированного использования с помощью программноаппаратных средств


    Скачать 4.72 Mb.
    НазваниеВведение. Защита программного обеспечения от несанкционированного использования с помощью программноаппаратных средств
    АнкорЛекции
    Дата19.11.2022
    Размер4.72 Mb.
    Формат файлаdoc
    Имя файлаLektsii_PASOIB.doc
    ТипДокументы
    #797594
    страница11 из 12
    1   ...   4   5   6   7   8   9   10   11   12

    Рис. 6.1. Рабочее окно отладчика SoftICE
    Экран SoftICE – основной инструмент при отладке приложения. Он подразделяется на 7 окон и строку подсказки, позволяющие контролировать различные стороны процесса отладки. В таблице 6.1. перечислены все окна в порядке убывания их значимости.

    Окно SoftICE

    Описание

    Окно команд

    Ввод команд и выдача сообщений

    Окно кода

    Вывод машинных инструкций и/или исходных кодов

    Окно локальных переменных

    Вывод содержимого текущего кадра стека

    Окно слежения

    Вывод значений переменных, указанных командой WATCH

    Окно регистров

    Вывод и изменение содержимого регистров и флагов. Если в ходе выполнения команды были изменены какие-либо регистры, то SoftICE подсвечивает их другим цветом.

    Окно данных

    Отображение и изменение содержимого участка памяти

    Окно стека сопроцессора

    Вывод содержимого стека (регистров) сопроцессора или MMX-регистров

    Строка подсказки

    Краткая информация о командах SoftICE

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

    Команда открытия/закрытия

    Команда переключения в окно

    Окно

    WC

    Alt+C

    Окно кода

    WD

    Alt+D

    Окно данных

    WF

    Невозможно

    Окно стека сопроцессора

    WL

    Alt+L

    Окно локальных переменных

    WR

    Alt+R

    Окно регистров

    WW

    Alt+W

    Окно слежения

    Команды отладчику SoftICE можно вводить только тогда, когда курсор находится в окне команд либо кода.

    Синтаксис команд

    Команды SoftICE имеют следующие общие правила построения:

    1. Все команды представляют собой нечувствительные в регистру строки длиной от 1 до 6 символов.

    2. Адрес в SoftICE может быть представлен парой селектор:смещение или сегмент:смещение, либо одним смещением.

    3. В используемых выражениях могут использоваться:

    Символы группировки – круглые скобки ‘(‘, ‘)’.

    Числа в шестнадцатиричном или десятичном формате.

    Адреса.

    Номера строк.

    Строковые литералы.

    Идентификаторы.

    Операторы.

    Встроенные функции.

    Регистры.

    В окне регистров детально представлено, также, значение регистра флагов.

    Флаг

    Описание

    Флаг

    Описание

    o

    Флаг переполнения

    z

    Флаг нуля

    d

    Флаг направления

    a

    Флаг дополнительного переноса

    i

    Флаг разрешения прерывания

    p

    Флаг четности

    s

    Флаг знака

    с

    Флаг переноса

    Строчный неподсвеченный символ означает, что флаг не установлен и имеет значение “0”. Выделенный заглавный символ показывает, что флаг имеет значение “1”. Например, o d I s Z a p c.

    Переключение значения флага, когда курсор находится в одном из них осуществляется клавишей INSERT.

    Использование прерываний в SoftICE

    Одновременно в SoftICE можно установить до 256 прерываний. SoftICE поддерживает следующие типы контрольных точек.

    1. Прерывания на инструкции, располагающиеся по конкретным адресам в памяти. Данные типы прерываний устанавливаются командой BPX (либо щелчком мыши на команде). SoftICE заменяет существующие инструкции командами INT 3.

    2. Прерывания на обращение к памяти. SoftICE использует отладочные регистры для прерывания работы, когда читается (или исполняется) определенный байт, слово или двойное слово в памяти, или по этому адресу производится запись. Данный тип прерываний основан на использовании отладочных регистров DRx и чрезвычайно полезен для выяснения вопроса, когда и где происходит изменение программных переменных, а также для установки контрольных точек в исполняемом коде, размещенном в памяти «только для чтения». Для установки такого типа прерываний используется команда BPM.

    3. Контрольные точки на прерываниях. SoftICE перехватывает прерывания, модифицируя таблицу дескрипторов прерываний. Для таких контрольных точек используется команда BPINT.

    4. Прерывания ввода/вывода. SoftICE использует расширения отладочных регистров процессоров Pentium и Pentium Pro, чтобы отслеживать инструкции IN и OUT по заданному номеру порта. Этот тип прерываний устанавливается командой BPIO.

    5. Прерывания на сообщения Windows. SoftICE отслеживает поступление в окно определенного сообщения (или сообщений из заданного диапазона). Для установки такой точки прерывания используется команда BMSG.

    Любое из данных прерываний может быть задано со следующими дополнительными параметрами.

    Условное выражение [IF выражение]. Для возникновения прерывания выражение должно иметь в результате ненулевое значение TRUE.

    Действие при прерывании [DO “команда1; команда2; …”]. При возникновении прерывания будет автоматически выполнена указанная последовательность команд.

    Форматы команд

    Команда BPX

    BPX [адрес] [IF выражение] [DO “команда1; команда2; …”]

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

    Например, BPX MessageBoxA,

    Команда BPM

    BPM [B|W|D] адрес [R|W|RW|X] [отладочный регистр] [IF выражение] [DO “команда1; команда2; …”]

    BPM, BPMB – прерывание по обращение к заданному байту, BPMW – к слову, BPMD – к двойному слову.

    R, W, RW – прерывание по чтению, записи, или по чтению и записи.

    X – прерывание по исполнению указанного адреса (в отличие от команды BPX не производится модификация кода).

    Отладочный регистр – указывает, какой регистр должен задействоваться при реализации команды (как правило, определяется автоматически).

    Например, команда BPMD MyGlobalVariable W IF MyGlobalVariable==5 устанавливает прерывание по записи значения “5” в переменную размером двойное слово с именем MyGlobalVariable.
    Команда BPINT

    BPINT номер-прерывания [IF выражение] [DO “команда1; команда2; …”]

    Например, BPINT 2E IF EAX==1E.
    Команда BPIO

    BPIO номер-порта [R|W|RW]

    [IF выражение] [DO “команда1; команда2; …”]

    R,W,RW – прерывание по чтению из порта (IN) записи в порт (OUT) или по любой из них.
    Команда BMSG

    BMSG дескриптор-окна [L] [1-сообщение-диапазона [последнее-сообщение-диапазона]] [IF выражение] [DO “команда1; команда2; …”]

    L означает, чтобы сообщение было просто отображено в окне команд без активизации SoftICE.

    Диапазоны сообщений показывают, какие сообщения необходимо фиксировать.

    Например, BMSG 1001E WM_NCPAINT
    Для удаления контрольных точек используется команда BC, например, BC MessageBoxA. Для удаления всех контрольных точек можно воспользоваться командой BC *.

    Для того чтобы выключить контрольную точку без удаления необходимо воспользоваться командой BD, например BD MessageBoxA. Для включения отключенной контрольной точки существует команда BE.
    Отображение информации в окне данных

    Каждая строка окна данных отображает 16 байт области памяти в текущем формате в виде байт, слов, двойных слов или коротких или длинных вещественных значений.

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

    Например,

    :D es:1000 – выводит содержимое памяти, начиная с адреса ES:1000h

    :D ESI – выводит содержимое памяти, начиная с адреса, указанного в регистре ESI.

    Команда D может использоваться одновременно и для указания формата отображения.

    DB – формат побайтового отображения, DW – формат отображения в виде слов, DD – в виде двойных слов.

    Например, DW es:1000
    Пошаговое исполнение кода

    Выполнять код в пошаговом режиме можно используя функциональную клавишу F8. По клавише F12 программа выполняется до тех пор, пока не встретится инструкция RET, ее можно эффективно использовать для выхода из подпрограмм.
    6.2. Дизассемблирование программ с помощью интерактивного дизассемблера IdaPro
    Интерактивный дизассемблер IDA PRO, как и всякий дизассемблер предназначен для дизассемблирования кода программы в мнемонические инструкции на языке ассемблера. Рабочее окно IDA представлено на рис. 6.2.

    Большим удобством Ida Pro является то, что он «сворачивает» стандартные библиотечные функции, что во многом упрощает навигацию по файлу, позволяя втиснуть больше информации в тесное пространство экрана. «Развернуть» функцию можно, подведя к ней курсор и нажав “+”, или для сворачивания “-”.

    Кроме этого, IDA способна находить перекрестные ссылки, вызываемые из кода. На основе сигнатурного анализа, IDA умеет распознавать различные библиотечные операторы., например, “ostream::operator<<”.

    Дизассемблер IDA изначально проектировался как интерактивная среда, предназначенная для совместной работы с человеком. Преимуществом интерактивных дизассемблеров является то, что дизассемблеры, пытающиеся выполнить весь процесс автоматически, легко сбить каким-либо хитрым приемом. Человека же сбить не так легко.


    Рис. 6.2. Рабочий интерфейс дизассемблера Ida Pro
    В IDA реализован удобный С-подобный внутренний язык написания скриптов, позволяющий реализовать многие полезные действия (например, осуществить дешифровку зашифрованного участка кода).

    Ida Pro поддерживает инструкции для различного вида процессоров. Среди них – все версии процессоров INTEL, Motorola, Z80.
    Пример использования дизассемблера IDA Pro приведен ниже.

    Пусть у нас имеется следующий COM файл размером 292 байт. Код данного файла представлен на рис. 6.3.
    Рис. 6.3. Код исследуемого файла

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

    Если приглядеться к первым двум командам, то можно увидеть, что инструкция JMP в строке 103h вызывает переход по адресу 106h. Для того, чтобы объяснить это IDA, необходимо добавить новую перекрестную ссылку. Это можно сделать так.

    В меню “View” выбрать пункт “Cross references” и нажать INSERT.

    В
    Рис. 6.4. Текст файла после первоначального дизассемблирования

    поле “From” указать адрес, с которого происходит прыжок (в нашем случае seg000:0103).

    В поле “To” указать адрес, куда происходит прыжок (в нашем случае seg000:0106).

    Этого же самого эффекта можно добиться более быстрым путем – подвести указатель к адресу 106h и нажать клавишу “C”. Тем самым мы укажем, что с данного адреса идет участок кода. Однако недостаток этого варианта состоит в том, что непонятно, с какого места этот участок кода будет получать управление.

    Комментарии в дизассемблированном коде имеют очень большое значение, особенно в больших проектах. Например, в нашем случае, в строке 103h можно поставить комментарий, говорящий о том, что при выполнении инструкции JMP SI, значение регистра SI=106h. Для осуществления этого, подведем курсор к строке 103h, нажмем клавишу “:” и введем текст комментария “SI=106h”.

    С адреса 106h идет следующий участок кода.

    loc_0_106:










    mov si, 114h

    Загрузка в si смещения 114h




    lodsw

    Загрузка в AX слова, на которое указывает регистр si




    xchg ax,cx

    Обмен значений регистров ax и cx




    push si

    Заносим si в стек

    loc_0_10C:










    xor byte ptr [si], 66h

    Расшифровываем байт, находящийся по адресу, на который указывает si




    inc si

    Увеличиваем si на 1




    loop loc_0_10C

    Замыкаем цикл




    jmp si

    Переходим на адрес, находящийся в регистре si

    Анализируя данный участок, видим, что данный участок осуществляет расшифровку некоторого фрагмента программы, находящегося с адреса 116h, при этом длина фрагмента хранится по адресу 114h и занимает 1 слово. Подведем курсор к адресу 114h и будем нажимать клавишу “D”, пока тип хранимых данных не изменится на «Слово» - «dw». Видим, что длина зашифрованного фрагмента равна 100h байт.

    Если проанализировать команду jmp si, находящуюся по адресу 112h и выполняемую после расшифровки, то можно увидеть, что управление передается на команду, находящуюся за зашифрованным фрагментом. Адрес этой команды равен 116h+100h=216h.

    Подведя курсор к адресу 216h и нажав клавишу “C”, мы получим следующий код, который выполняется после расшифровки.

    call $+3;

    Заносим в стек регистр IP

    pop cx;

    Извлекаем из стека регистр IP

    pop si;

    Извлекаем из стека начало расшифрованных данных

    sub cx, si;

    Вычисляем длину расшифрованного участка (+3 байта)

    mov di, 100h;




    push di;

    Заносим в стек адрес 100h, на который будем передавать управление

    repe movsb;

    Переносим расшифрованный участок кода на адрес 100h

    retn;

    Передаем управление на адрес 100h

    Общий смысл данной последовательности команд – перемещение расшифрованного фрагмента памяти по адресу 100h и передача на него управление.

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

    Следует отметить, что для доступа к произвольной ячейке памяти в IDA необходимо знать сегмент, в котором она расположена, и ее смещение. Seg000 в действительности не нулевой сегмент, а символическое имя. Для того, чтобы узнать базовый адрес, соответствующий данному сегменту, необходимо воспользоваться меню View/Segments. Вызвав его, видим, что ему соответствует адрес 1000h (рис. 6.5).


    1   ...   4   5   6   7   8   9   10   11   12


    написать администратору сайта