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

  • Rfirst0(0x128C6) ); 0xFFFFFFFF seg000:28CB retn seg000:28CB sub_0_2847 endp Message(“0x%X \n”, Rfirst0(0x128CB)

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


    Скачать 2.86 Mb.
    НазваниеОписание функций встроенного языка
    Анкорobraz_mihlenia_-_dizassembler_IDA
    Дата29.09.2022
    Размер2.86 Mb.
    Формат файлаpdf
    Имя файлаobraz_mihlenia_-_dizassembler_IDA.pdf
    ТипСправочник
    #704305
    страница22 из 39
    1   ...   18   19   20   21   22   23   24   25   ...   39
    long RfirstB (long To);
    Функция возвращает линейный адрес первого источника для указанного списка приемников.
    Для понимания этого, рекомендуется прочесть описания функций AddCodeXref,
    DelCodeXref, Rfirst, Rnext.
    Очевидно, что по одному и тому же линейному адресу может существовать более одного приемника перекрестных ссылок.
    Например: seg000:013B jz loc_0_14F ;
    Æ источник seg000:013D mov ds, ax seg000:013F mov ax, cs seg000:0141 mov es, ax seg000:0143 lodsb seg000:0144 cmp al, 21h ; '!' seg000:0146 jb loc_0_14F ;
    Æ источник seg000:0148 cmp al, 7Ah ; 'z' seg000:014A ja loc_0_14F ;
    Æ источник seg000:014C stosb seg000:014D loop loc_0_143 ;
    Æ источник seg000:014F seg000:014F loc_0_14F: ; CODE XREF: seg000:013Bj seg000:014F ; seg000:0146j ... seg000:014F ;
    Å приемник seg000:014F pop es
    Источник по адресу seg000:0x14D помечен не случайно. Он, разумеется, не имеет никакого отношения к операнду loc_0_143, а представляет собой перекрестную ссылку на следующую команду.
    Реализация этой функции повторяет особенность реализации Rfirst.
    Действительно, рассмотрим список источников перекрестных ссылок, который IDA сформировала по адресу seg000:0x14F – {0x1013B, 0x10146,
    0x1014A
    , 0x1014C}.
    Вполне естественно ожидать, что вызов RfirstB должен был бы вернуть первый – самый наименьший из них.
    Однако же, вместо него возвращается источник ссылка на следующую инструкцию, то есть
    0x1014A. Покажем это ниже:

    216
    Message(“0x%X \n”,
    RfirstB(0x1014F)
    );
    0x1014A
    Как получить действительно первый элемент источника списка можно прочитать в описании функции RnextB
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Пояснения
    Источник ссылки на следующую инструкцию или если ее нет, то первый адрес в списке.
    Return
    -1 если список исчерпан или отсутствует источник
    long RnextB (long To,long current);
    Функция возвращает адрес следующего источника в списке перекрестных ссылок, расположенного по указанному приемнику.
    Для более глубокого понимания принципов работы рекомендуется ознакомиться с описанием функций AddCodeXref, DelCodeXref, Rnext, RfirstB.
    Очевидно, что по одному и тому же линейному адресу может существовать более одного приемника перекрестных ссылок.
    Например: seg000:013B jz loc_0_14F ;
    Æ источник seg000:013D mov ds, ax seg000:013F mov ax, cs seg000:0141 mov es, ax seg000:0143 lodsb seg000:0144 cmp al, 21h ; '!' seg000:0146 jb loc_0_14F ;
    Æ источник seg000:0148 cmp al, 7Ah ; 'z' seg000:014A ja loc_0_14F ;
    Æ источник seg000:014C stosb seg000:014D loop loc_0_143 ;
    Æ источник seg000:014F seg000:014F loc_0_14F: ; CODE XREF: seg000:013Bj seg000:014F ; seg000:0146j ... seg000:014F ;
    Å приемник seg000:014F pop es
    Реализация этой функции повторяет особенность реализации Rnext. Не смотря на то, что в idc.idc утверждается будто бы эта функция «видит» тип перекрестных ссылок, указывающих на следующую команду, в действительности этого не происходит. И выделенный красным цветом адрес источника функция не вернет никогда. {0x1013B,
    0x10146,
    0x1014A
    , 0x1014C}.

    217
    Поскольку RnextB хранит текущий адрес не во внутренней переменной, а в передаваемом параметре, то существует возможность, модифицируя его, управлять работой функции.
    Так, например, RnextB(ScreenEA(), 0) гарантированно вернет следующий за ним адрес, то есть 0x1013B, а пройти весь список (за исключением ссылок на следующую инструкцию) можно с помощью следующего кода: auto a; a=0; for (;;)
    { a=RnextB(ScreenEA(),a); if (a==-1) break;
    Message("0x%X \n",a);
    }
    0x1013B
    0x10146 0x1014C
    Немного модернизировав код можно добиться того, что бы на экран выдавался действительно весь список источников, включая и ссылки на следующую команду. auto a; a=0; for (;;)
    { a=RnextB(ScreenEA(),a); if (a==-1) break; if (a>RfirstB(ScreenEA())
    Message(“0x%X \n”,
    RfirstB(ScreenEA()
    );
    Message("0x%X \n",a);
    }
    0x1013B
    0x10146 0x1014A
    0x1014C
    Функция возвращает ошибку BADADDR, если список исчерпан, (то есть текущий адрес наибольший в списке) или не существует.
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Current
    Текущий адрес
    Пояснения
    Следующий адрес в списке
    Return
    -1 если список исчерпан или отсутствует источник

    218
    long Rfirst0 (long From);
    Функция возвращает линейный адрес приемника перекрестной ссылки для заданного источника.
    Практически идентична Rfirst, за тем исключением, что не имеет доступа к ссылкам на следующую инструкцию, поэтому возвращает действительно первый элемент списка линейный адресов приемников.
    Поэтому ее рекомендуется использовать в паре с функцией Rnext, впрочем,
    Rnext(xxx, 0) возвращает идентичный результат и хотя работает ничуть не быстрее, но немного экономит на компактности кода.
    Для понимания этого рекомендуется ознакомиться с описанием функций
    AddCodeXref, DelCodeXref, Rfrst, Rnext
    Если указан неверный источник, (то есть линейный адрес, не содержащий перекрестных ссылок) или источник перекрестной ссылки данных, то функция возвратит ошибку BADADDR
    Примеры использования: seg000:28C6 pop di ;
    Æ источник seg000:28C7 pop si ;
    Å приемник
    Message(“0x%X \n”,
    Rfirst0(0x128C6)
    );
    0xFFFFFFFF seg000:28CB retn seg000:28CB sub_0_2847 endp
    Message(“0x%X \n”,
    Rfirst0(0x128CB)
    );
    0xFFFFFFFF seg000:2870
    jmp loc_0_2892 ; Æ источник seg000:2870 nop seg000:2892 loc_0_2892: ; CODE
    XREF: seg000:2870j seg000:2892 ;
    Å приемник seg000:2892 cmp byte ptr [si], 22h ;
    '"'
    Message(“0x%X \n”,
    Rfirst0(0x12870)
    );
    0x12892
    Операнд
    Пояснения
    From
    Линейный адрес источника перекрестной ссылки

    219
    Пояснения
    Return
    Линеный адрес приемника первой перекрестной ссылки
    long Rnext0 (long From,long current);
    Эта функция по идее (а точнее следуя из сказанного в файле idc.idc) должна отличатся от Rnext только отсутствием доступа к перекрестным ссылкам на следующую инструкцию.
    Однако из-за особенностей реализации функции Rnext она «не видит» такой тип ссылок и это делает обе функции полностью идентичными.
    Поэтому никакого описания здесь не приводится, поскольку пришлось бы полностью повторить все сказанное об Rnext.
    Чаще всего ссылка на следующую команду не требуется. В этих случаях и следует применять вызов Rnext0.
    В противном случае придется воспользоваться листингом, приведенным ниже. auto a; a=0; for (;;)
    { a=RnextB(ScreenEA(),a); if (a==-1) break; if (a>RfirstB(ScreenEA())
    Message(“0x%X \n”,
    RfirstB(ScreenEA()
    );
    Message("0x%X \n",a);
    }
    Операнд
    Пояснения
    Form
    Линейный адрес источника списка перекрестных ссылок
    Current
    Текущий адрес
    Пояснения
    Следующий адрес в списке
    Return
    -1 если список исчерпан или отсутствует источник
    long RfirstB0(long To);
    Функция возвращает линейный адрес источника перекрестной ссылки для заданного приемника.
    Практически идентична RfirstB, за тем исключением, что не имеет доступа к ссылкам на следующую инструкцию, поэтому возвращает действительно первый элемент списка линейный адресов источников.
    Поэтому ее рекомендуется использовать в паре с функцией RnextB, впрочем,
    RnextB(xxx, 0) возвращает идентичный результат и хотя работает ничуть не быстрее, но немного экономит на компактности кода.
    Для понимания этого рекомендуется ознакомиться с описанием функций
    AddCodeXref, DelCodeXref, RfrstB, RnextB

    220
    Если указан неверный источник, (то есть линейный адрес, не содержащий перекрестных ссылок) или источник перекрестной ссылки данных, то функция возвратит ошибку BADADDR
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Пояснения
    Источник ссылки на следующую инструкцию или если ее нет, то первый адрес в списке.
    Return
    -1 если список исчерпан или отсутствует источник
    long RnextB0 (long To,long current);
    Эта функция по идее (а точнее следуя из сказанного в файле idc.idc) должна отличатся от
    RnextB только отсутствием доступа к перекрестным ссылкам на следующую инструкцию.
    Однако из-за особенностей реализации функции Rnext она «не видит» такой тип ссылок и это делает обе функции полностью идентичными.
    Поэтому никакого описания здесь не приводится, поскольку пришлось бы полностью повторить все сказанное об Rnext.
    Чаще всего ссылка на следующую команду не требуется. В этих случаях и следует применять вызов Rnext0. В противном случае придется воспользоваться листингом, приведенным выше.
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Current
    Текущий адрес
    Пояснения
    Следующий адрес в списке
    Return
    -1 если список исчерпан или отсутствует источник
    void add_dref(long From,long To,long drefType);
    Подробнее об архитектуре перекрестных ссылках было сказано в описании функции AddCodeXref.
    Для удобства IDA поддерживает две группы перекрестных ссылок – на данные и на код. Каждая группа со своим набором функций и возможностей.
    Типы, поддерживаемых перекрестных ссылок на данные следующие:
    Определение
    Пояснения
    Легенда dr_O
    1 Смещение (Offset) o dr_W
    2 Запись (Write) w dr_R
    3 Чтение (Read) r dr_T
    4 Пользовательский тип t
    С первого взгляда кажется, что можно создать перекрестную ссылку на данные с помощью вызова AddCodeXref, только лишь указав соответствующий тип ссылки.
    Например:
    AddCodeXref(0x10148,0x1014C,2);

    221
    seg000:014C loc_0_14C: ; CODE XREF: seg000:0148
    w
    На самом же деле постфикс (в данном случае ‘w’) играет только информационную роль и ничуть не влияет на тип ссылки, которая так и осталась кодовой, что видно по предваряющему ее ключевому слову.
    Сравните это со следующим примером: аdd_dref(0x10148,0x1014C,2); seg000:014A ja loc_0_14F seg000:014C ;
    DATA
    XREF: seg000:0148w seg000:014C stosb
    Обратите внимание, что IDA никак не контролирует корректность ссылки, полностью перекладывая эту работу на код, вызывающий эту функцию.
    Тип ссылки играет чисто информационную роль и служит для ускорения анализа дизассемблируемой программы. Никаких других влияний на работу IDA он не оказывает.
    Однако стоит все же придерживаться единой схемы наименования перекрестных ссылок, что бы ни приводить пользователя в замешательство. dr_O - Смещение (Offset)
    Под смещением понимается любое (прямое или косвенное) обращение к адресу ячейки данных.
    Например:
    Seg000:0301 push offset loc_0_30A ;
    Æ источник seg000:030A loc_0_30A: ; DATA XREF: seg000:0301
    o seg000:030A ;
    Å приемник seg000:3000 DW offset byte_0_293A ;
    Æ источник
    Seg000:293A byte_0_293A DB ? ; DATA XREF: seg000:3000
    o
    Seg000:293A ;
    Å приемник
    Но и в том числе и такие инструкции, где смещение не указано явно, а только подразумевается.
    Например, LEA.
    Dr_W Запись (Write)
    Любая инструкция, производящая прямую запись в ячейку. seg000:2928 mov cs:
    byte_0_2939
    ,1 ;
    Æ источник seg000:2939* DB ? ; DATA XREF seg000:2928
    w seg000:2939 ;
    Å приемник seg000:0E5F dec word_0_F72
    ;
    Æ источник

    222
    seg000:0F72* DW ? ; DATA XREF seg000:0E5F
    w seg000:0F72 ;
    Å приемник
    Однако, для таких инструкций, как, например, MOVS IDA автоматически не создает перекрестных ссылок. Но это могут делать продвинутые пользовательские скрипты.
    Dr_R Чтение (Read)
    Любая инструкция, производящая прямое чтение ячейки. Например: seg000:0D08 mov ax,
    word_0_F72
    ;
    Æ источник seg000:0F72*word_0_F72 dw 0 ; DATA XREF: seg000:0D08
    r seg000:0F72 ;
    Å приемник
    При этом инструкции, выполняющие цикл операций чтение – вычисление – запись,
    IDA всегда относит к типу dr_w, а не dr_r
    Обратите внимание, что функция add_dref не возвращает результата успешности операции, поэтому для того, что бы определить действительно ли была создана перекрестная ссылка, или нет – приходится прибегать к полному прохождения списка в попытках найти в нем «свой» адрес.
    Операнд
    Пояснения
    From
    Адрес источника перекрестной ссылки
    To
    Адрес приемника перекрестной ссылки
    Dreftype
    Тип перекрестной ссылки (смотри таблицу, приведенную выше)
    void del_dref(long From,long To);
    Функция позволяет удалять перекрестную ссылку на данные. Для этого необходимо знать линейные адреса ее источника и приемника.
    Например: seg000:2331 mov word_0_2934, ax ;
    Æ источник seg000:2934*word_0_2934 dw 0 ; DATA XREF: seg000:2331w seg000:2934 ;
    Å приемник
    Del_dref(0x2331,9x2934); seg000:2331 mov word_0_2934, ax ; seg000:2934*word_0_2934 dw 0 ; seg000:2934 ;
    К сожалению, нет никакой возможности узнать о результате успешности операции, поскольку функция возвращает тип void.

    223
    Часто путают источник и приемник местами, что приводит к ошибкам. Необходимо запомнить, что IDA всегда создает комментарий к перекрестной ссылке возле ее приемника, а не источника.
    Поэтому, что бы удалить указанную перекрестную ссылку необходимо воспользоваться следующим кодом:
    Del_dref(0x2331,9x2934);
    Разумеется, что эта функция не пригодна для удаления перекрестных ссылок на код.
    Операнд
    Пояснения
    From
    Адрес источника перекрестной ссылки
    To
    Адрес приемника перекрестной ссылки
    long Dfirst (long From);
    Функция возвращает линейный адрес приемника первой перекрестной ссылки указанного источника.
    Подробнее о перекрестных ссылках было рассказано в описании функция
    AddCodeXref, add_dref.
    Хотя это не очевидно, источник может иметь несколько перекрестных ссылок.
    Например, когда используется инструкция, наподобие mov ax,[BX].
    Если указан неверный источник, (то есть линейный адрес, не содержащий перекрестных ссылок) или источник перекрестной ссылки данных, то функция возвратит ошибку BADADDR
    Пример использования: seg000:2331 mov word_0_2934, ax ;
    Æ источник seg000:2934*word_0_2934 dw 0 ; DATA XREF: seg000:2331w seg000:2934 ;
    Å приемник
    Message(“0x%X \n”,
    Dfirst(0x12331)
    );
    0x12934
    Операнд
    Пояснения
    From
    Линейный адрес источника перекрестной ссылки
    Пояснения
    Return
    Линеный адрес приемника первой перекрестной ссылки
    long Dnext (long From,long current);
    Эта функция возвращает линейный адрес приемника очередной перекрестной ссылки в списке.
    Для понимания того, как работает данная функция, рекомендуется прочесть описания функций AddCodeXref, add_dref, Dfirst.

    224
    IDA хранит список перекрестных ссылок для каждого источника, отсортированный по адресам приемника. Первыми в нем идут те ссылки, чей линейный адрес приемника наименьший, за ними следующие.
    Если функция завершится успешно, то возвратит линейный адрес приемника перекрестной ссылки, следующей на current.
    То есть current должен быть не обязательно точно равен адресу приемника текущей перекрестной ссылки в списке. Он может быть меньше его, но, разумеется, обязательно превосходить адрес приемника предыдущей ссылки.
    Поясним это на примере: seg000:2331 mov word_0_2934, ax ;
    Æ источник seg000:26C1 cmp ax, word_0_2934 ;
    Æ источник seg000:277B cmp dx, word_0_2934 ;
    Æ источник seg000:2934* word_0_2934 dw 0 ; DATA XREF: seg000:2331w seg000:2934* ; seg000:26C1r seg000:2934* ; seg000:277Br seg000:2934 ;
    Å приемник
    IDA сформирует по линейному адресу 0x12934 следующий список приемников:
    {0x12331, 0x126С1, 0x1277B} Вот эти адреса и будут возвращаться при прохождении списка функцией Dnext.
    Не обязательно начинать первый вызов с Dfirst (смотри описание выше). Как уже упоминалось, Dnext хранит указатель на текущую ссылку не во внутренней скрытой переменной, а принимает его как параметр.
    Таким образом, это дает нам возможность легко манипулировать ее значением, управляя поведением функции.
    Вообще не понятно, зачем понадобилось вводить Dfirst. Ведь первую перекрестную ссылку можно найти с помощью Dnext – и это будет следующая ссылка за нулем.
    Очевидно, что Dnext(0x12934,0) вернет 0x12331 – первую перекрестную ссылку в списке. Следовательно, Dnext(X, 0) идентична Dfirst.
    Вывести на экран адреса всех источников перекрестных ссылок поможет следующий код: auto a; a=0; for (;;)
    { a=Dnext(ScreenEA(),a); if (a==-1) break;
    Message("0x%X \n",a);
    }
    Операнд
    Пояснения
    Form
    Линейный адрес источника списка перекрестных ссылок
    Current
    Текущий адрес
    Пояснения
    Return
    Следующий адрес в списке

    225
    -1 если список исчерпан или отсутствует источник
    long DfirstB (long To);
    Функция возвращает линейный адрес первого источника для указанного списка приемников.
    Для понимания этого, рекомендуется прочесть описания функций AddCodeXref, add_dref, Dfirst.
    Очевидно, что по одному и тому же линейному адресу может существовать более одного приемника перекрестных ссылок.
    Например: seg000:2331 mov word_0_2934, ax ;
    Æ источник seg000:26C1 cmp ax, word_0_2934 ;
    Æ источник seg000:277B cmp dx, word_0_2934 ;
    Æ источник seg000:2934* word_0_2934 dw 0 ; DATA XREF: seg000:2331w seg000:2934* ; seg000:26C1r seg000:2934* ; seg000:277Br
    Рассмотрим список источников перекрестных ссылок, который IDA сформировала по адресу seg000:0x2934 – {0x12331, 0x126С1, 0x1277B}.
    Вызов DfirstB возвратит первый из них – с наименьшим линейным адресом.
    Message(“0x%X \n”,
    ВfirstB(0x12934)
    );
    0x12331
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Пояснения
    Источник ссылки на следующую инструкцию или если ее нет, то первый адрес в списке.
    Return
    -1 если список исчерпан или отсутствует источник
    long DnextB (long To,long current);

    226
    Функция возвращает адрес следующего источника в списке перекрестных ссылок, расположенного по указанному приемнику.
    Для более глубокого понимания принципов работы рекомендуется ознакомиться с описанием функций AddCodeXref, add_dref, Dnext
    Очевидно, что по одному и тому же линейному адресу может существовать более одного приемника перекрестных ссылок.
    Например: seg000:2331 mov word_0_2934, ax ;
    Æ источник seg000:26C1 cmp ax, word_0_2934 ;
    Æ источник seg000:277B cmp dx, word_0_2934 ;
    Æ источник seg000:2934* word_0_2934 dw 0 ; DATA XREF: seg000:2331w seg000:2934* ; seg000:26C1r seg000:2934* ; seg000:277Br
    Поскольку DnextB хранит текущий адрес не во внутренней переменной, а в передаваемом параметре, то существует возможность, модифицируя его, управлять работой функции.
    Так, например, DnextB(ScreenEA(), 0) гарантированно вернет следующий за ним адрес, а пройти весь список (за исключением ссылок на следующую инструкцию) можно с помощью следующего кода: auto a; a=0; for (;;)
    { a=DnextB(ScreenEA(),a); if (a==-1) break;
    Message("0x%X \n",a);
    }
    0x12331 0x126C1 0x1277B
    Функция возвращает ошибку BADADDR, если список исчерпан, (то есть текущий адрес наибольший в списке) или не существует.
    Операнд
    Пояснения
    To
    Линейный адрес приемника списка перекрестных ссылок
    Current
    Текущий адрес
    Пояснения
    Следующий адрес в списке
    Return
    -1 если список исчерпан или отсутствует источник

    227
    1   ...   18   19   20   21   22   23   24   25   ...   39


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