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

  • Рисунок 11 0x017 IDAC: Область вывода результатов работы скрипта «консоль» Рисунок 12 0x018 IDAG: Область вывода результатов работы скрипта «консоль»

  • define • undef • include • error • ifdef\ifndef\else\endif Внимание

  • Таблица 1 структура файла *.id1 Если открыть файл “tutor.id1” в любом шестнадцатеричном редакторе (внимание

  • Архитектура страничной памяти

  • Описание функций встроенного языка


    Скачать 2.86 Mb.
    НазваниеОписание функций встроенного языка
    Анкорobraz_mihlenia_-_dizassembler_IDA
    Дата29.09.2022
    Размер2.86 Mb.
    Формат файлаpdf
    Имя файлаobraz_mihlenia_-_dizassembler_IDA.pdf
    ТипСправочник
    #704305
    страница4 из 39
    1   2   3   4   5   6   7   8   9   ...   39
    Язык скриптов IDA Си
    IDA поддерживает Си-подобный скрип-язык, в целом напоминающий Си Керигана и
    Ричи, но значительно упрощенный, не поддерживающий типов, массивов, указателей и в том числе не обладающий возможностью отладки приложений. Язык скриптов изначально задумывался как средство выполнения простейших операций, укладывающихся в десяток- другой строк кода, а для «серьезных» задач предусмотрен механизм плагинов – внешних модулей, написанных на Borland C++ или Microsoft Visual C++ и подключаемых к IDA по мере необходимости. Впрочем, в подавляющем большинстве случаев нет никакой нужды прибегать к плагинам и вполне можно обойтись встроенным скрипт-языком.
    Ниже приводится краткое описание языка скриптов IDA Си, рассчитанное на читателя знакомого и владеющего «классическим» Си.
    Консоль
    Простейшие скрипты могут быть набраны «не отходя от кассы» в диалоге, вызываемом нажатием , в дальнейшем именуемым консолью. Достоинство этого

    24
    метода – оперативность, а недостатки - жесткое ограничение максимально допустимого размера вводимого текста (порядка одного килобайта) и невозможность работать более чем с одним скрипом одновременно.
    Более сложные скрипты как правило создаются в отдельном файле, загружаемый нажатием или заданием ключа “-Sfilename” в командной строке, причем между “-S” и именем файла не должно присутствовать символа пробела.
    Результаты работы скрипта (и служебные сообщения самой IDA) выводятся в специальную область экрана, напоминающую собой бесконечную телетайпную ленту, условно именуемую «консолью». Поскольку одна консоль связана с вводом (исходного текста скрипта), а другая с выводом (результатов работы), никакого противоречия не возникает и по контексту легко понять о какой именно консоли идет речь.
    Рисунок 11 0x017 IDAC: Область вывода результатов работы скрипта «консоль»
    Рисунок 12 0x018 IDAG: Область вывода результатов работы скрипта «консоль»
    Функции, объявление функций, аргументы функции, возвращаемое значение
    IDA поддерживает функции двух типов – встроенные (build-in) функции и функции, определяемые пользователем. Объявление пользовательских функций происходит следующим образом – перед именем функции указывается ключевое слово “static”, а за именем в круглых скобках через запятую перечисляются аргументы (если они есть) без указания их типа, например, так: static
    MyFunc() static
    MyOtherFunc(x,y,s0)
    { {
    // тело функции; // тело функции;
    } }
    Ограничения: максимально допустимая длина имени функции равна 16 символам; возможность организовывать вложенные функции отсутствует.
    Консоль не поддерживает объявления функций, сообщая при этом о синтаксической ошибке, функции могут быть объявлены только в idc-файлах.
    Все функции, объявленные как “static” (т.е. все функции вообще, поскольку, локальные функции IDA не поддерживает) будучи однажды загруженными, резидентно остаются в памяти на протяжении всего сеанса работа с дизассемблером и в любой момент доступны для вызова из консоли или других программ.
    Например, если создать idc-файл следующего содержания: «
    static Demo(s0)
    {Warning(s0);}
    », загрузить его нажатием <F2>, нажать <Shift-F2> для вызова консоли и набрать нечто наподобие “
    Demo(“Hello, IDA!”);
    появится диалоговое окно, выводящее указанную строку на экран. static-функции не могут быть выгружены из памяти, но могут перекрываться повторным объявлением. Встроенные в IDA функции перекрыть нельзя.
    Если в тексте скрипта объявлена функция main(), она автоматически выполняется при его загрузке.
    Возврат значения функции осуществляется посредством “return” с последующим указанием имени переменной или константы, например, так: static MyFunc(x,y) staic MyOtherFunc()
    {
    { return x-y; return “Hello, IDA Pro\\n”;
    }
    }
    Пустой “return”, равно как и его отсутствие, возвращает нулевое значение (пустую строку).

    25
    Объявление переменных, типы переменных, преобразования переменных
    Для объявления переменных используется ключевое слово auto за которым последовательно перечисляются декларируемые переменные, отделенные друг от друга запятой. Инициализация при объявлении не поддерживается.
    Например: auto x; auto x,y,z; a) верно auto x=1; b) неверно
    Все переменные, объявленные таким образом, локальные; поддержка глобальных переменных, доступных всем функциям отсутствует. Вместо этого IDA поддерживает
    виртуальные массивы, доступные всем функциям всех загруженных скриптов одновременно (см. главу ??? «Виртуальные массивы»).
    Имя переменной не должно совпадать ни с одним зарезервированным ключевым словом. Зарезервированные ключевые слова в IDA те же самые, что и в Си.
    IDA поддерживает два типа переменных – переменные типа строка и переменные типа число.
    Строковые переменные ограничены максимальной длиной в 255 символов и заканчиваются нулем. Над ними доступны три операции – присвоение, контекция
    (слияние) и сравнение.
    Переменные типа число в свою очередь делятся на два подтипа: long – 32- разрядное знаковое целое и float – число с плавающей запятой до 25 разрядов. Над ними обоими доступны операции – присвоение, сравнение, сложение, вычитание,
    умножение, деление. Над целочисленными переменными доступны битовые операции -
    циклический сдвиг вправо и влево, битовое И, битовое НЕ, битовое ИЛИ, битовое НЕТ и битовое ИЛИ-ИСКЛЮЧАЮЩЕЕ-И.
    Преобразования типов переменных осуществляются автоматически и просиходят в следующих случаях:
    • если левая переменная – строка, то и правая переменная преобразуется в строку;
    • если левая переменная – длинное целое, а правая – строка, правая переменная преобразуется в длинное целое;
    • если одна из переменных имеет тип float, все остальные переменные преобразуются в тип float;
    • если над переменной выполняются одна из битовых операций, она преобразуется в длинное целое
    Преобразование «строка Æ длинное целое» осуществляется по следующей схеме: если левая часть строки представляет собой число, записанное в десятичной нотации, результат преобразования равен этому числу, в противном случае – нулю.
    Примеры: auto s0,s1,s2,s3; s0=”1234”; s1=”1234mystring”,”0x1234”,”MyString”;
    Message(“>%d,%d,%d,%d\n”,s0,s1,s2,s3);
    >1234,1234,0,0

    26
    Преобразование «длинное целое Æ строка» осуществляется путем дописывания завершающего нуля к преобразуемому значению.
    Примеры: auto a,b; a=0x21;b=0x22232425;
    Message(“>%s,%s\n”,a,b);
    > !,%$#"
    Преобразование «строка Æ float» осуществляется аналогично преобразованию
    «строка Æ длинное целое», включая дробную часть; если же преобразование невозможно, результат равен нулю.
    Например: auto s0,s1; s0=”1.1”; s1=”MyString”;
    Message(“>%f,%f\n”,s0,s1);
    > 1.1, 0.
    Преобразование «float Æ строка» в отличие от преобразования «длинное целое Æ строка» осуществляет действительно корректное преобразование, сравните: auto f; auto a; f=”1.2”; a=0x21;
    Message(“>%s\n”,f);
    Message(“>%s\n”,a);
    > 1.2
    >!
    При сложении двух строковых переменных происходит их контакция (слияние); при вычитании одной строки из другой левый операнд игнорируется, а над каждым символом правого выполняется операция NEG (дополнение до нуля); при делении и умножении сток друг на друга они преобразуются к длинному целому. Операции вычитания, деления и умножения строк недокументированны и по-разному могут вести себя в зависимости от версии IDA. Рекомендуется воздержаться от использования их в собственных программах.
    Смешивание операндов различных типов заставляет внимательно относиться к порядку расстановки их выражении – результат может зависеть от перемены мест слагаемых, например: auto x,s0;x=1;s0=”3h”; auto x,s0;x=1;s0=”3h”;
    Message(“>%x\n”,x+s0);
    Message(“>%x\n”,s0+x);
    >4
    >3
    Пояснение:
    в первом случае левая переменная – длинное целое, поэтому, строка “3h”
    преобразуется к длинному целому, в результате чего получается: 1+3=4; во втором случае левая
    переменная – строка, поэтому, длинное целое #1 преобразуется к строке, в результате чего
    получается: “3h”+’\x1’ = “3h\x1”, но затем “3h\x1” вновь преобразуется к длинному целому, ибо того
    требует спецификатор “%x”, а “3h\x1” = #3. Так что от перемены мест слагаемых сумма меняется!
    Смещение типов – частый источник трудноуловимых ошибок, и лучше использовать явное преобразование вызовом следующих функций:
    long ( переменная ) // Преобразует переменную в длинное целое
    char ( переменная ) // Преобразует переменную в строку

    27
    float( переменная ) // Преобразует переменную в тип float
    Например: auto x,s0;x=1;s0=”3h”; auto x,s0;x=1;s0=”3h”;
    Message(">%d\n",long(s0)+x);
    Message(">%d\n",x+long(s0));
    >4
    >4
    На этот раз от перемены мест слагаемых сумма не изменяется!
    Директивы
    IDA поддерживает следующие стандартные директивы препроцессора:
    #define
    #undef
    #include
    #error
    #ifdef\#ifndef\#else\#endif
    Внимание: консоль не поддерживает никаких директив препроцессора – их
    можно использовать только в IDC-файлах.
    Замечание: для использования определений, констант, приводимых в этой книге
    по ходу описания функций, в исходный код скрипта необходимо включить
    директиву “#inclide ”.
    Вызов функций возможен и без включения файла в исходный
    листинг – это необходимо только для использования определений, например,
    таких, как BADADDR.
    До вызова консоли IDA самостоятельно подключает к ней этот файл,
    делая доступными все определения.
    Предписания
    IDA поддерживает следующие стандартные конструкции, изменяющие нормальный ход выполнения программы:
    if, else;
    for;
    while, do, break, continue;
    return
    Замечание: цикл “for (expr1; expr2; expr3 ) statement” в отличие от стандартного
    языка Си не поддерживает более одного счетчика.
    Математические и битовые операторы
    Поддерживаются следующие математические операторы – сложение: “+”,
    вычитание: “-“, умножение: “*”, деление “/”, приращение на единицу “++”. Операторы
    “+=” и “-=” не поддерживаются.

    28
    Поддерживаются следующие битовые операторы – битовое И: “&”, битовое ИЛИ:”|”, битовое НЕТ: “!”, битовое ИЛИ-ИСКЛЮЧАЮЩЕЕ-И:”^”.
    Массивы
    Встроенной языковой поддержки массивов, наподобие той, что присутствует в Си, у
    IDA нет.
    ВИРТУАЛЬНАЯ ПАМЯТЬ
    Архитектура виртуальной памяти
    В отличии от многих других дизассемблеров, IDA работает не с исследуемым файлом, а с его образом, загруженным в виртуальную память. IDA эмулирует загрузчик операционной системы, благодаря чему образ загруженного в дизассемблер файла идентичен образу того же файла, загруженного операционной системой.
    IDA использует плоскую 32-разрядную модель виртуальной памяти, предоставляя в распоряжение пользователя немногим менее четырех гигабайт адресного пространства.
    Наибольший возможный адрес равен 0xFF000000 и для удобства определен в файле
    <idc.idc> через константу MAXADDR. Попытка задания больших адресов приведет к ошибке.
    Адресное пространство виртуальной памяти может быть разбито на один или более сегментов (см. главу «Сегменты и селекторы»), однако, подавляющее большинство встроенных функций IDA ожидают не сегментных, а линейных адресов.
    Адресное пространство виртуальной памяти не непрерывно – в нем могут присутствовать «выключенные» адреса, попытка обращения к которым приведет к ошибке.
    IDA не предоставляет функций, позволяющих манипулировать «включением» -
    «выключением» адресов. Эта операция может быть выполнена только косвенно – адреса
    «включаются» при загрузке бинарного файла и создании нового сегмента, а выключаются при его удалении (см. описание функции SegCreate).
    С каждым «включенным» адресом виртуальной памяти связана специальная структура данных, включающая в себя 8-разрядную ячейку виртуальной памяти и 24- разрядное поле атрибутов этой ячейки.
    Атрибуты, в частности, указывают следует ли отображать ячейку как инструкцию или как данные, в каком виде следует представлять операнды и т.д. Назначение каждого бита атрибутов подробно описано в главах «Элементы», «Типы элементов», «Операнды» и
    «Объекты». Поле атрибутов доступно не только для косвенного (посредством вызова встроенных в IDA Функций), но и непосредственного чтения и изменения. Однако, разработчики IDA настоятельно рекомендуют избегать непосредственной модификации, поскольку, назначение тех или иных битов атрибутов в последующих версиях дизассемблера может измениться!
    Ячейка может иметь как инициализированное, так и неинициализированное значение. Попытка чтения неинициализированной ячейки возвращает ошибку. Определить инициализирована ячейка или нет можно по состоянию младшего бита поля атрибутов – если ячейка инициализирована он равен одному, а если неинициализированная – нулю.
    32-разрядное целое, содержащее ячейку и связанные с ней атрибуты, называется
    флагом виртуальной памяти (см. рис. 13).
    32 16 8
    0
    атрибуты ячейка
    Рисунок 13 Строение флага виртуальной памяти

    29
    Флаги виртуальной памяти хранятся в виртуальном массиве, подробнее об организации которого рассказано в главе «Виртуальные массивы».
    Сами же виртуальные массивы хранятся в страничной физической памяти.
    Совокупность страниц физической страничной памяти в документации и контекстовой помощи IDA называется виртуальной памятью. Такая терминологическая путаница требует постоянного уточнения о чем собственно идет речь – образе загруженного файла или виртуальном массиве, поэтому, во избежание двусмысленного понимания, здесь и далее память, хранящая виртуальные массивы, будет называется страничной, а память, хранящая образ загруженного файла – виртуальной.
    Технические детали:
    Виртуальное адресное пространство представляет собой совокупность индексов всех существующих элементов виртуального массива, а «выключенные» адреса являются отсутствующими индексами виртуального массива.
    Виртуальный массив располагается в файле *.id1, формат заголовка которого приведен в таблице 1. смещение длина значение
    0x0 0x4 сигнатура “Va4” – “Virtual Array version 4”
    0x4 0x2
    (Word) количество непрерывных регионов памяти
    0x6 0x2
    (Word) количество страниц всего (одна страница равна 4 кб)
    0x8 0x4
    (long) индекс (он же линейный адрес) первого кванта региона
    0xC 0x4
    (long) индекс (он же линейный адрес) последнего кванта региона
    0x10 0x4
    (long) смещение индекса первого кванта региона в файле *.id1
    +0x4 0x4
    (long) индекс (он же линейный адрес) первого кванта следующего региона
    +0x4 0x4
    (long) индекс (он же линейный адрес) последнего кванта региона
    +0x4 0x4
    (long) смещение индекса первого кванта следующего региона в файле *.id1
    ... ... …
    Таблица 1 структура файла *.id1
    Если открыть файл “tutor.id1” в любом шестнадцатеричном редакторе (внимание,
    это необходимо сделать до выхода из IDA, т.к. при выходе он будет автоматически
    удален), его начало должно выглядеть так:
    00000000: 56 61 34 00 02 00 03 00 │ 66 06 01 00 78 06 01 00 Va4 ☻ ♥ f♠☺ x♠☺
    00000010: 98 39 00 00 77 07 01 00 │ 89 07 01 00 DC 5D 00 00 Ш9 w•☺ Й•☺ ▄]
    ??? #Художнику – используя файл 0x019_o выделить указанные ниже элементы графически (кружочком) со стрелочкой, указывающей на его отношение к нижеследующему описанию, причем левую часть (т.е. указание самого значения поля, отделенную двоеточием) затем удалить.
    “Va4”: сигнатура, позволяющая распознать тип файла
    00 02: два непрерывных адресных пространства 0x10666 – 0x10677 и
    0x10777 и 0x10788 00 03: три страницы виртуальной памяти израсходовано (размер страницы
    4 кб).
    66 06 01 00: начальный адрес первого непрерывного регион виртуальной памяти
    78 06 01 00: конечный адрес первого непрерывного региона виртуальной памяти
    98 39 00 00: смещение, по которому хранится первый регион виртуальной памяти в этом файле

    30 77 07 01 00: начальный адрес второго непрерывного регион виртуальной памяти
    89 07 01 00: конечный адрес второго непрерывного региона виртуальной памяти
    DC 5D 00 00: смещение, по которому хранится второй регион виртуальной памяти в этом файле
    По смещению 0x003998 (помним об обратном порядке байтов) в файле “tutor.id1” находится следующее содержимое:
    00003998: 68 21 00 00│45 01 00 00│4C 01 00 00│4C 01 00 00 H! ell
    000039A8: 4F 01 00 00│0C 01 00 00│00 01 00 00│69 01 00 00 o,☺ ☺ I
    000039B8: 64 01 00 00│61 01 00 00│00 01 00 00│70 01 00 00 DA☺ ☺ P
    000039C8: 52 01 00 00│4F 01 00 00│21 01 00 00│20 01 00 00 ro!☺ ☺
    000039D8: 0D 01 00 00│FF 01 00 00│00 00 00 00│00 00 00 00 ♪☺ ☺
    Это и есть флаги виртуальной памяти, содержащие, ячейки и атрибуты виртуальной памяти, читая которые через каждый четвертый байт, можно разобрать “Hello,
    IDA Pro!”
    Архитектура страничной памяти
    Размещение виртуальной памяти в дисковом файле требует некоторого количества оперативной памяти компьютера под кэш-буфера, поскольку побайтовый обмен с диском крайне непроизводителен.
    Кэш IDA имеет страничную организацию. Вся виртуальная память разбита на множество блоков одинакового размера, называемых страницами. Если происходит обращение к одной ячейке виртуальной памяти, страница, в которой эта ячейка расположена, загружается в оперативную память целиком. Соответственно, модификация одной ячейки виртуальной памяти влечет перезапись всей страницы.
    Разбивка на страницы осуществляет маскированием n младших битов целевых адресов, по этой причине размер страницы всегда представляет собой степень двойки.
    Если размер региона, выделенный под кэш буфер (так же называемый
    1   2   3   4   5   6   7   8   9   ...   39


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