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

  • FIXUP ALMA MATER

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


    Скачать 2.86 Mb.
    НазваниеОписание функций встроенного языка
    Анкорobraz_mihlenia_-_dizassembler_IDA
    Дата29.09.2022
    Размер2.86 Mb.
    Формат файлаpdf
    Имя файлаobraz_mihlenia_-_dizassembler_IDA.pdf
    ТипСправочник
    #704305
    страница28 из 39
    1   ...   24   25   26   27   28   29   30   31   ...   39

    long GetEnumFlag(long enum_id);
    Функция возвращает флаги, определяющие представление членов перечисления, заданного идентификатором.
    Возможные значения перечислены ниже в таблице:
    FF_0NUMH
    0x00100000 шестнадцатеричное представление первого операнда
    FF_0NUMD
    0x00200000 десятичное представление первого операнда
    FF_0CHAR
    0x00300000 символьное представление первого операнда
    FF_0SEG
    0x00400000 первый операнд – сегмент
    FF_0OFF
    0x00500000 первый операнд – смещение
    FF_0NUMB
    0x00600000
    Представление первого операнда в бинарном виде
    FF_0NUMO
    0x00700000
    Представление первого операнда в восьмеричном виде
    FF_0ENUM
    0x00800000
    Представление первого операнда в виде перечисления
    FF_0FOP
    0x00900000
    Принудительный первый операнд
    FF_0STRO
    0x00A00000
    Представление первого операнда как смещения в структуре
    FF_0STK
    0x00B00000 первый операнд стековая переменная
    FF_1VOID
    0x00000000 тип второго операнда Void
    FF_1NUMH
    0x00100000
    Шестнадцатеричное представление второго операнда
    FF_1NUMD
    0x00200000 десятичное представление второго операнда
    FF_1CHAR
    0x00300000 символьное представление второго операнда
    FF_1SEG
    0x00400000 второй операнд – сегмент
    FF_1OFF
    0x00500000 второй операнд – смещение
    FF_1NUMB
    0x00600000
    Представление второго операнда в бинарном виде
    FF_1NUMO
    0x00700000
    Представление второго операнда в восьмеричном виде
    FF_1ENUM
    0x00800000
    Представление второго операнда в виде перечисления
    FF_1FOP
    0x00900000
    Принудительный второй операнд
    FF_1STRO
    0x00A00000
    Представление второго операнда как смещения в структуре
    FF_1STK
    0x00B00000 второй операнд стековая переменная
    Пример:
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    Message("0x%X \n",
    GetEnumFlag(
    GetEnum("enum_1")
    );
    0x1100000
    Операнд Пояснения
    Enum_id Идентификатор перечисления
    ==return Пояснения
    !=0
    Флаг отображения членов перечисления
    Return
    ==0
    Ошибка

    290
    long GetConstByName(char name);
    Функция возвращает идентификатор константы по ее имени. Все перечисления разделяют общее пространство имен, другими словами одно и то же имя не может быть повторено дважды, поэтому является уникальным.
    Например:
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; ---------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_2
    FFFFFFFF MyEnum = 16h
    Message("0x%X \n",
    GetConstByName("MyEnum")
    );
    0xFF000136
    Идентификатор обеспечивает доступ к константе. Что бы, например, получить ее значение необходимо воспользоваться функцией long GetConstValue(long const_id), которая описана ниже.
    Операнд Пояснения name Имя константы
    ==return Пояснения
    !=0
    Идентификатор константы
    Return
    ==0
    Ошибка
    long GetConstValue(long const_id);
    Функция возвращает значение константы по ее идентификатору или ноль в результате ошибки. Поэтому часто возникает неопределенность, – то ли действительно имела место ошибка (например, был указан несуществующий идентификатор) или же просто константа имеет такое значение.
    Пример использования:
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; ---------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_2
    FFFFFFFF MyEnum = 16h
    Message("0x%X \n",
    GetConstValue(
    GetConstByName("MyEnum")
    )
    );
    0x16

    291
    Операнд Пояснения
    Const_id Идентификатор константы
    ==return Пояснения
    !=0
    Значение константы
    Ошибка
    Return
    ==0
    Значение константы
    char GetConstName(long const_id);
    Функция возвращает имя константы, заданной идентификатором. Если идентификатор указан неправильно, то возвращается пустая строка
    Например:
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; -----------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_2
    FFFFFFFF MyEnum = 16h
    FFFFFFFF
    Message("%s \n",
    GetConstName(
    GetConstByName("MyEnum")
    )
    );
    MyEnum
    Операнд Пояснения
    Const_id ID константы
    ==return Пояснения
    !=””
    Имя константы
    Return
    ==””
    Ошибка
    char GetConstCmt(long const_id,long repeatable);
    Возвращает комментарий константы, заданной идентификатором. Комментарии бывают двух типов – постоянные и повторяемые. Постоянные отображаются только справа от константы, а повторяемые при каждом обращении к ней.
    FFFFFFFF ;
    FFFFFFFF ; FFFFFFFF enum_1_0 = 1 ;
    My regulag commnet
    FFFFFFFF enum_1_2 = 2 seg000:0046 rol bx, enum_1_0
    Message(“%s \n”,
    GetConstCmt(

    292
    GetConstByName("enum_1_0"),
    0);
    My regulag commnet
    FFFFFFFF
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1 ; My Enum repeatable commnet
    FFFFFFFF enum_1_2 = 2 seg000:0046 rol bx, enum_1_0 ;
    My
    Repeatable commnet
    Message(“%s \n”,
    GetConstCmt(
    GetConstByName("enum_1_0"),
    1);
    My Repeatable commnet
    Операнд
    Пояснения id Идентификатор (ID) константы
    Флаг
    Пояснения
    0
    Неповторяемый комментарий
    Repeatable
    1
    Повторяемый комментарий
    Завершение
    Пояснения
    !=””
    Комментарий
    Return
    “”
    Ошибка
    long AddEnum(long idx,char name,long flag);
    Функция добавляет новое перечисление. . Для этого необходимо указать его имя
    (которое впоследствии может быть изменено) и тип представления констант в перечислении.
    Индекс задает положение перечисления в списке. Если он равен BADADDR, то новое перечисление будет добавлено в конец списка, иначе же старое перечисление будет затерто! Подробнее об этом рассказано в описании функции AddStrucEx
    Флаг определяет представление констант в перечислении. Может принимать значения, перечисленные ниже в таблице:
    FF_0NUMH
    0x00100000 шестнадцатеричное представление первого операнда
    FF_0NUMD
    0x00200000 десятичное представление первого операнда
    FF_0CHAR
    0x00300000 символьное представление первого операнда
    FF_0SEG
    0x00400000 первый операнд – сегмент
    FF_0OFF
    0x00500000 первый операнд – смещение
    FF_0NUMB
    0x00600000
    Представление первого операнда в бинарном виде
    FF_0NUMO
    0x00700000
    Представление первого операнда в восьмеричном виде
    FF_0ENUM
    0x00800000
    Представление первого операнда в виде перечисления

    293
    FF_0FOP
    0x00900000
    Принудительный первый операнд
    FF_0STRO
    0x00A00000
    Представление первого операнда как смещения в структуре
    FF_0STK
    0x00B00000 первый операнд стековая переменная
    FF_1VOID
    0x00000000 тип второго операнда Void
    FF_1NUMH
    0x00100000
    Шестнадцатеричное представление второго операнда
    FF_1NUMD
    0x00200000 десятичное представление второго операнда
    FF_1CHAR
    0x00300000 символьное представление второго операнда
    FF_1SEG
    0x00400000 второй операнд – сегмент
    FF_1OFF
    0x00500000 второй операнд – смещение
    FF_1NUMB
    0x00600000
    Представление второго операнда в бинарном виде
    FF_1NUMO
    0x00700000
    Представление второго операнда в восьмеричном виде
    FF_1ENUM
    0x00800000
    Представление второго операнда в виде перечисления
    FF_1FOP
    0x00900000
    Принудительный второй операнд
    FF_1STRO
    0x00A00000
    Представление второго операнда как смещения в структуре
    FF_1STK
    0x00B00000 второй операнд стековая переменная
    Пример использования:
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    AddEnum(-1,”MyNewEnum”,0);
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; --------------------------
    FFFFFFFF
    FFFFFFFF ; enum MyNewEnum
    Операнд
    Пояснения
    ==index
    Действие
    [0,MaxIdx]
    Индекс перечисления (старое перечисление при этом будет затерто)
    MaxIdx+1
    Индекс нового перечисления index
    BADADDR
    Индекс нового перечисления name
    Имя перечисления
    Завершение
    Пояснения
    !=BADADDR
    Идентификатор перечисления
    Return
    ==BADADDR
    Ошибка
    Интерактивно структуру добавить можно, вызвав список командой меню

    View \
    Structures и нажав клавишу

    294
    void DelEnum(long enum_id);
    Функция удаляет перечисление, заданное идентификатором вместе со всеми его членами.
    Пример:
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; ----------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_2
    FFFFFFFF MyEnum = 16h
    FFFFFFFF
    DelEnum(
    GetEnum("enum_2")
    );
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1

    295
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    Операнд Пояснения
    Enum_id Идентификатор перечисления
    Интерактивно перечисление можно удалить, установив курсор на любой его элемент и нажав клавишу
    success SetEnumIdx(long enum_id,long idx);
    Функция позволяет изменять индекс перечисления в списке. При этом перечисления меняются местами, и затирания не происходит.
    Например:
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; ---------------------------
    FFFFFFFF
    FFFFFFFF ; enum MyNewEnum
    FFFFFFFF MyNewEnum_0 = 0
    FFFFFFFF
    FFFFFFFF ; ---------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_9
    FFFFFFFF enum_9_0 = 0
    SetEnumIdx(
    GetEnum("enum_1"),1
    );
    FFFFFFFF ; enum MyNewEnum
    FFFFFFFF MyNewEnum_0 = 0
    FFFFFFFF
    FFFFFFFF ; ---------------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_1
    FFFFFFFF enum_1_0 = 1
    FFFFFFFF enum_1_2 = 2
    FFFFFFFF
    FFFFFFFF ; ---------------------------------
    FFFFFFFF
    FFFFFFFF ; enum enum_9
    FFFFFFFF enum_9_0 = 0
    FFFFFFFF
    Операнд Пояснения id Идентификатор (ID) перечисления
    Return
    ==return Пояснения

    296
    ==1
    Успешное завершение
    ==0
    Ошибка
    FIXUP
    ALMA MATER
    Более привычным синонимом fixup вероятно, окажется термин «перемещаемые элементы».
    Что это такое? Как можно судить из названия, это относительные адреса, обеспечивающие портабельность кода, то есть независимость от базового адреса загрузки.
    Поскольку IDA эмулирует загрузку файла в собственное адресное пространство и даже трассирует его выполнение, то она должна поддерживать и перемещаемые элементы.
    Покажем это на небольшом примере, MS-DOS exe файла.
    Просмотр с помощью HIEW
    00000200: B80100 mov ax
    ,
    00001
    00000203: 8ED8 mov ds,ax
    00000205: B409 mov ah,009 ;"
    00000207: BA0000 mov dx,00000 0000020A: CD21 int 021
    Просмотр с помощью IDA seg000:0000 start proc near seg000:0000 mov ax,
    1001h
    seg000:0003 mov ds, ax seg000:0005 assume ds:dseg seg000:0005 mov ah, 9 seg000:0007 mov dx, 0 seg000:000A int 21h
    Что грузиться в регистр AX? С виду непосредственное значение. Однако, это не так. Если приглядеться, то можно увидеть, что дальше оно помещается в регистр DS и, следовательно, скорее всего указывает на сегмент данных программы.
    То есть 0x1 это адрес сегмента данных выраженный в параграфах. Знакомым с архитектурой IBM PC может показаться, с чего бы это вдруг он казался расположенным глубоко в таблице векторов прерываний. Но ничего странного нет. И сегмент данных расположен вовсе не там, где можно было бы подумать.
    Ведь это относительный адрес. Резанный вопрос относительный чего? В exe файлах от отсчитывается от адреса загрузки первого байта, расположенного за заголовком файла.
    По умолчанию IDA загружает exe файлы по адресу 0x10000. Следовательно, считая в параграфах, 0x1000+0x1 == 0x1001, как видим, результат совпадает с тем, что отобразила IDA.
    Вот это и понимается под поддержкой перемещаемых элементов. Остается только ответить на вопрос, откуда IDA узнала, как следует трактовать этот непосредственный операнд? Эвристическим анализатором? Нет, конечно. Она поступила точно так же, как и операционная система на ее месте, - просто прочитала заголовок файла.
    00000000: 4D 5A 2C 00-02 00
    02 00
    -20 00 00 00-FF FF 00 00 MZ, __

    297 00000010: 00 00 00 00-00 00 00 00-3E 00 00 00-01 00 FB 71 > _q
    00000020: 6A 72 00 00-00 00 00 00-00 00 00 00-00 00 00 00 jr
    00000030: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 01 00 00000040:
    00 00 0D 00-00 00 00 00-00 00 00 00-00 00 00 00
    Файлы типа OLD EXE имеют очень простую структуру, реализующую поддержку перемещаемых элементов. В таблице, состоящей из двойных слов, перечисляются линейные адреса, указывающие на перемещаемые элементы, - то есть относительные адреса, каждый из которых представляет собой слово, ссылающееся на сегмент (адрес в параграфах).
    Таким образом, IDA остается только выполнить простое арифметическое сложение. Впрочем, существуют и более запутанные форматы. Так, например, все win32 файлы, поддерживающие динамическое связывание, или говоря проще, возможность вызова функций чужих DLL вынуждены иметь похожие структуры, – ведь адреса вызываемых функций не известны на этапе линковки программы и могут быть вычислены только после загрузки файла в память.
    Если же обратиться к другим платформам, а не замыкаться на серии Intel 80x86, то мы столкнемся с феейверком самых разных технических решений от которого может быстро зарябить в глазах.
    Каким же образом IDA может поддерживать все это одним махом? Ведь перемещаемыми элементами управляют меньше десяти функций.
    Действительно, если абстрагироваться от вариаций технических реализаций и сосредоточиться на природе перемещаемых элементов, то можно с удивлением обнаружить, что в ее основы могут быть сформулированы всего одной фразой.
    Вот этот операнд ссылается туда. И все! Этого достаточно, что бы обеспечить нормальную функциональность и работоспособность!
    Какой конкретно элемент и куда ссылается, вычисляют специальные модули, отвечающие за загрузку файла определенного формата. Ядро IDA такие проблемы не волнуют.
    Поэтому фактически, поддержка перемещаемых элементов обеспечивается не IDA, а внешними модулями, к которым у пользователя программного доступа из языка скриптов
    нет.
    Другими словами, перемещаемыми элементами пользователь не управляет. Да, конечно, он может посмотреть все существующие перемещаемые элементы и даже их скорректировать, но нужно ли это?
    Большинство, использующих IDA, этой возможности ни когда в своей жизни не использовали (ну, может быть, разве что из любопытства). И это правильно.
    Правильно, потому что IDA и сама неплохо справляется с поставленной задачей.
    Поддержка перемещаемых элементов это не та область, что требует внимания со стороны пользователя.
    Впрочем, из этого правила все же есть исключения. Если некоторая ну очень хитрая программа имеет свой загрузчик (или чаще – интерпретируемый код), который работает не стандартно и стало быть IDA его не поддерживает.
    Немного поразмыслив, сюда же можно отнести и некоторые случаи самомодифицирующегося кода. Ведь поддержка перемещаемых элементов лежит на самом низком уровне иерархии IDA – другими словами «исправляется» виртуальная память, поэтому это работает не только с операндами, но и с кодом, то есть влияет на дизассемблирование инструкций.
    Основная трудность описания перемещаемых элементов в объяснении их типов. А они то же разными бывают. Причем большая часть существует только на других платформах и совершенно чужда пользователям PC с Windows и Pentium. А поэтому описывать их подробно в этой книге совершенно бессмысленно.
    Для этого планируется выпустить специально приложение, рассказывающие об особенностях использования IDA на других платформах.
    Поэтому ниже на типе перемещаемых элементах внимание акцентироваться не будет.

    298
    МЕТОДЫ
    Функция
    Назначение long GetNextFixupEA(long ea)
    Возвращает линейный адрес следующего перемещаемого элемента long GetPrevFixupEA(long ea)
    Возвращает линейный адрес предыдущего перемещаемого элемента long GetFixupTgtType(long ea)
    Тип перемещаемого элемента long GetFixupTgtSel(long ea)
    Возвращает селектор перемещаемого элемента long GetFixupTgtOff(long ea)
    Возвращает смещение перемещаемого элемента void SetFixup(long ea,long type,long targetsel,long targetoff,long displ)
    Добавляет новый перемещаемый элемент void DelFixup(long ea)
    Функция удаляет перемещаемый элемент
    long GetNextFixupEA(long ea);
    Возвращает линейный адрес следующего перемещаемого элемента. Обратите внимание, что эта функция действительно возвращает адрес перемещаемого элемента, а не адрес начала содержащей его инструкции.
    Например: dseg:0000 public start dseg:0000 start proc near dseg:0000 B8 00 10
    mov ax, seg dseg dseg:0003 8E D8 mov ds, ax
    Message(“0x%X \n”,
    GetNextFixupEA(0)
    );
    0x1001
    Эмулятор загрузки инициализировал перемещаемый элемент необходимым значением, указывающим на адрес сегмента в виртуальной памяти. В нашем случае он равен 0x10.
    Операнд
    Пояснения ea
    Линейный адрес
    Завершение
    Пояснения
    !=BADADDR
    Успешно
    Return
    ==BADADDR
    Ошибка

    299
    long GetPrevFixupEA(long ea);
    Возвращает предыдущий адрес следующего перемещаемого элемента. Обратите внимание, что эта функция действительно возвращает адрес перемещаемого элемента, а не адрес начала содержащей его инструкции.
    Например: dseg:0000 public start dseg:0000 start proc near dseg:0000 B8 00 10
    mov ax, seg dseg dseg:0003 8E D8 mov ds, ax
    Message(“0x%X \n”,
    GetNextFixupEA(-1)
    );
    0x1001
    Эмулятор загрузки инициализировал перемещаемый элемент необходимым значением, указывающим на адрес сегмента в виртуальной памяти. В нашем случае он равен 0x10.
    Операнд
    Пояснения ea
    Линейный адрес
    Завершение
    Пояснения
    !=BADADDR
    Успешно
    Return
    ==BADADDR
    Ошибка
    long GetFixupTgtType(long ea);
    Функция возвращает тип перемещаемого элемента по его линейному адресу.
    Возможные значения перечислены в таблице ниже. Поскольку большинство из них на платформе Intel не имеет места, то подробное описание их назначения приведено в факультативном приложении к книге «Использование IDA на не-Intel платформах»
    FIXUP_MASK
    0xF
    FIXUP_BYTE
    FIXUP_OFF8
    FIXUP_OFF8 0
    Восьми битное смещение
    FIXUP_OFF16 1
    16-битное смещение
    FIXUP_SEG16 2
    16-битный сегмент (селектор)
    FIXUP_PTR32 3
    32-битный длинный указатель (16-бит база; 16-бит селектор)
    FIXUP_OFF32 4
    32-битное смещение
    FIXUP_PTR48 5
    48-битный указатель (16-бит база; 32-бит смещение).
    FIXUP_HI8 6
    Старшие 8 бит 16-битного смещения
    FIXUP_HI16 7
    Старшие 16 бит 32-битного смещения
    FIXUP_LOW8 8
    Младшие 8 бит 16-битного смещения
    FIXUP_LOW16 9
    Младшие 16бит 32-битного смещения
    FIXUP_REL
    0x10 fixup is relative to the linear address specified in the 3d parameter to set_fixup()

    300
    FIXUP_SELFRE
    L
    0x0 elf-relative? - disallows the kernel to convert operands in the first pass- this fixup is used during output This type of fixups is not used anymore. Anyway you can use it for commenting purpose in the loader modules
    FIXUP_EXTDEF
    0x20 target is a location (otherwise - segment)
    FIXUP_UNUSED
    0x40 fixup is ignored by IDA disallows the kernel to convert operands- this fixup is not used during output
    FIXUP_CREATE
    D
    0x80 fixup was not present in the input file
    Пример: seg000:032D cmp word ptr [bp+8], seg seg000
    seg000:0332 jnz loc_0_33A
    Message("0x%X \n",
    GetFixupTgtType(
    GetNextFixupEA(0)
    )
    );
    0x2
    Операнд
    Пояснения ea
    Линейный адрес
    Завершение
    Пояснения
    !=BADADDR
    Тип перемещаемого элемента
    Return
    ==BADADDR
    Ошибка
    1   ...   24   25   26   27   28   29   30   31   ...   39


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