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

  • SetFuctionEnd(0x12936,0x12933)

  • SetFuctionEnd(0x12935,0x12933)

  • GetFunctionFlags(0x12305)

  • GetFunctionFlags(0x1048B)

  • GetFunctionFlags(0x4010FF)

  • GetFunctionName(0x10263) ); __cleanup void SetFunctionCmt(long ea, char cmt, long repeatable);

  • GetFunctionCmt(0x010271,1)

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


    Скачать 2.86 Mb.
    НазваниеОписание функций встроенного языка
    Анкорobraz_mihlenia_-_dizassembler_IDA
    Дата29.09.2022
    Размер2.86 Mb.
    Формат файлаpdf
    Имя файлаobraz_mihlenia_-_dizassembler_IDA.pdf
    ТипСправочник
    #704305
    страница17 из 39
    1   ...   13   14   15   16   17   18   19   20   ...   39

    SetFuctionEnd(0x12930,0x12935)
    );
    0 seg000:292F sub_0_292F proc near seg000:292F inc bx seg000:2930 loop loc_0_292F seg000:2932 nop seg000:2933 retn seg000:2933 seg000:2933 ; ---------------------------------- seg000:2934*word_0_2934 dw 0 seg000:2934* seg000:2936*byte_0_2936 db 0
    Однако, в действительности, то, что конец функции не отображается на экране, еще ничего не значит. Попробуем убедиться, что IDA действительно не выполнила округления, и адрес 0x12936 не принадлежит функции.
    Message(“0x%X \n”,
    SetFuctionEnd(0x12936,0x12933)
    );
    1
    Ага, вызов SetFunctionEnd возвратил ошибку, следовательно, адрес 0x12936 действительно не принадлежит функции. Попробуем теперь уменьшить его на единицу:
    Message(“0x%X \n”,
    SetFuctionEnd(0x12935,0x12933)

    164
    );
    0 seg000:292F sub_0_292F proc near seg000:292F inc bx seg000:2930 loop loc_0_292F seg000:2932 nop seg000:2933 retn seg000:2933 seg000:2933 ; ---------------------------------- seg000:2934*word_0_2934 dw 0 seg000:2934*
    sub_0_292F endp seg000:2936*byte_0_2936 db 0
    Выходит, что как это ни парадоксально, но линейный адрес конца функции лежал посередине ячейки word_02934, где он, разумеется, не мог быть отображен. Описание этой ошибки IDA (которая должна быть устранена в последующих версиях), вероятно, не стоил бы такого пристального внимания, если бы эти таинственные исчезновения конца функций не случались так часто.
    Это не нарушает работоспособности дизассемблера, но сбивает с толку пользователя и вызывает в нем мнимое подозрение, что в базе IDA серьезные сбои или ошибки, и что лучше ее удалить и начать проект заново, чем работать с ошибками, которые еще не известно чем могут обернуться в будущем.
    На самом деле никаких поводов для беспокойства нет. Необходимо поправить адрес конца функции и можно продолжить работать дальше.
    Операнд
    Пояснения ea
    Любой линейный адрес, принадлежащий функции end
    Новый линейный адрес конца функции.
    Завершение
    Пояснения
    0
    Вызов завершился не успешно. Функция не была создана
    Return
    1
    Вызов завершился Успешно
    long NextFunction(long ea);
    Вызов возвращает линейный адрес начала функции следующий за ‘ea’. Что бы получить адрес первой функции необходимо вызвать NextFunction(0).
    Если больше ни одной функции возвратить невозможно, то функция возвращает ошибку BADADDR.
    Пример использования: seg000:0000
    sub_0_0 proc near seg000:0000 push ax seg000:0001 push bx
    …………….. seg000:0027 pop bx seg000:0028 pop ax seg000:0029 retn seg000:0029 sub_0_0 endp

    165
    seg000:0029 seg000:002A seg000:002A ; ___________ S U B R O U T I N E
    ____________________ seg000:002A seg000:002A seg000:002A
    sub_0_2A proc near seg000:002A mov si, 211h seg000:002D call sub_0_DD seg000:0030 mov si, 2BAh seg000:0033 call sub_0_DD seg000:0036 retn seg000:0036 sub_0_2A endp seg000:0036 seg000:0037 seg000:0037 ; _______________ S U B R O U T I N E
    ________________ seg000:0037 seg000:0037 seg000:0037
    sub_0_37 proc near seg000:0037 seg000:0037 seg000:0037 push ax seg000:0038 push bx auto a; a=0; while ((a=NextFunction(a))!=-1)
    Message("%x \n",a);
    10000 1002a
    10037
    Операнд
    Пояснения ea
    Линейный адрес
    Завершение
    Пояснения
    !=BADADDR
    Линейный адрес начала следующей функции
    Return
    BADADDR
    Ошибка
    long PrevFunction(long ea)
    Вызов возвращает линейный адрес предыдущий функции. Что бы получить адрес последней функции необходимо вызвать PrevFunction(BADADDR). seg000:0000
    sub_0_0 proc near seg000:0000 push ax seg000:0001 push bx
    …………….. seg000:0027 pop bx seg000:0028 pop ax seg000:0029 retn seg000:0029 sub_0_0 endp

    166
    seg000:0029 seg000:002A seg000:002A ; ___________ S U B R O U T I N E
    ____________________ seg000:002A seg000:002A seg000:002A
    sub_0_2A proc near seg000:002A mov si, 211h seg000:002D call sub_0_DD seg000:0030 mov si, 2BAh seg000:0033 call sub_0_DD seg000:0036 retn seg000:0036 sub_0_2A endp seg000:0036 seg000:0037 seg000:0037 ; _______________ S U B R O U T I N E
    ________________ seg000:0037 seg000:0037 seg000:0037
    sub_0_37 proc near seg000:0037 seg000:0037 seg000:0037 push ax seg000:0038 push bx auto a; a=0x10038; while ((a=PrevFunction(a))!=-1)
    Message("%x \n",a);
    10037 1002a
    10000
    Операнд
    Пояснения
    Ea
    Линейный адрес
    Завершение
    Пояснения
    !=BADADDR
    Линейный адрес начала предыдущей функции
    Return
    BADADDR
    Ошибка
    long GetFunctionFlags(long ea);
    Вызов GetFunctionFlags позволяет узнать атрибуты функции. Назначение отдельных битов в возвращаемом значении показано в таблице ниже.
    Определение
    Значение
    Пояснения
    FUNC_NORET 0x00000001
    L
    Функция не возвращает управления
    FUNC_FAR 0x00000002
    L
    FAR (далекая) функция
    FUNC_LIB 0x00000004
    Библиотечная функция

    167
    L
    FUNC_STATIC 0x00000008
    L
    Статическая функция
    FUNC_FRAME 0x00000010L
    Функция использует для указателя кадра стека регистр BP
    FUNC_USERFAR 0x00000020
    L
    Функция определена пользователем как далекая
    (FAR)
    FUNC_HIDDEN 0x00000040
    L
    Скрытая функция
    Подробнее о каждом атрибуте будет рассказано ниже.
    FUNC_NORET
    Этот атрибут устанавливается тем функциям, что не возвращают управления командой ret. Однако в большинстве случаев IDA автоматически не присваивает его.
    Так, например, в следующей функции он не установлен. seg000:2305 sub_0_2305 proc near seg000:2305 sti seg000:2306 call sub_0_1CA seg000:2309 mov ah, 4Ch seg000:230B int 21h seg000:230B sub_0_2305 endp
    Message(“%b \n”,
    GetFunctionFlags(0x12305)
    );
    0
    Если в вашей ситуации это обстоятельство окажется критичным, то можно написать собственный скрипт, выполняющий такие проверки и устанавливающий атрибуты через вызов SetFunctionFlags.
    FUNC_FAR
    «Далекая» функция. IDA считает далекими все функции, оканчивающиеся командой далекого возврата – retf.
    Этот механизм достаточно несовершенен и может давать сбои. Так, например, в следующем фрагменте эмуляцию вызова CALL FAR \ RET IDA интерпретировала, как далекий возврат из функции.
    Это не упрек в сторону IDA, поскольку ради таких частных случаев бессмысленно вносить дополнительные усовершенствования в дизассемблер, но учитывать этот факт всегда стоит, вручную корректируя адрес конца и атрибуты функции. seg000:048B sub_0_48B proc far seg000:048B seg000:048B pushf seg000:048C push cs seg000:048D push offset locret_0_499 seg000:0490 push word ptr ds:74Dh seg000:0494 push word ptr ds:74Bh seg000:0498 retf

    168
    seg000:0498 sub_0_48B endp ; sp = -0Ah seg000:0498 seg000:0499 ; ------------------------------------------ seg000:0499 seg000:0499 locret_0_499: seg000:0499 retn
    Message(“%b \n”,
    GetFunctionFlags(0x1048B)
    );
    10
    FUNC_LIB
    Таким флагом отмечены стандартные «библиотечные» функции. То есть те, чьи сигнатуры известны FLIRT.
    .text:004010FF ;
    Attributes: library function
    .text:004010FF
    .text:004010FF __amsg_exit proc near
    .text:004010FF
    .text:004010FF
    .text:004010FF arg_0 = dword ptr 4
    .text:004010FF
    .text:004010FF cmp dword_0_408758, 2
    .text:00401106 jz short loc_0_40110D
    .text:00401108 call __FF_MSGBANNER
    .text:0040110D
    .text:0040110D loc_0_40110D:
    .text:0040110D push [esp+arg_0]
    .text:00401111 call __NMSG_WRITE
    .text:00401116 push 0FFh
    .text:0040111B call off_0_408050
    .text:00401121 pop ecx
    .text:00401122 pop ecx
    .text:00401123 retn
    .text:00401123 __amsg_exit endp
    Message(“%b \n”,
    GetFunctionFlags(0x4010FF)
    );
    100
    FUNC_FRAME
    Функция использует в качестве указателя на кадр стека регистр BP (EBP).
    IDA определяет это отслеживая последовательность
    PUSH BP
    MOV BP, SP

    169
    Большинство современных оптимизирующих компиляторов отказались от такого подхода, и адресуют локальные переменные и аргументы непосредственно по регистру ESP. IDA распознает такую ситуацию и отслеживает значение ESP по ходу исполнения процедуры, освобождая пользователя от львиной доли работы. seg000:20B8 ;
    Attributes: bp-based frame seg000:20B8 seg000:20B8 sub_0_20B8 proc near seg000:20B8 seg000:20B8 seg000:20B8 var_80 = byte ptr -80h seg000:20B8 var_6B = byte ptr -6Bh seg000:20B8 var_62 = byte ptr -62h seg000:20B8 seg000:20B8
    push bp
    seg000:20B9 mov ah, 2Fh seg000:20BB int 21h seg000:20BB seg000:20BD push bx seg000:20BE
    mov bp, sp
    seg000:20C0 sub sp, 80h seg000:20C4 mov ah, 1Ah seg000:20C6 lea dx, [bp+
    var_80
    ] seg000:20C9 int 21h
    Message(“%b \n”,
    GetFunctionFlags(0x4010FF)
    );
    10000
    Обратите внимание, что IDA распознала эту комбинацию, даже когда команды push bp и mov bp,sp оказались достаточно разнесены.
    FUNC_USERFAR
    Этот атрибут IDA устанавливает, когда пользователь вручную меняет тип функции с NEAR на FAR, вызывая диалог ‘Modify Function’ с помощью команды меню

    Edit \ Function \ Edit Function.

    170
    Обратите внимание, что это не относится к вызовам SetFunctionFlags!
    Последняя устанавливает именно тот набор атрибутов, который ей передается.
    FUNC_HIDDEN
    Этот атрибут устанавливается у «свернутых» функций. Свернуть любую функцию можно однократным нажатием Gray ‘-‘, переместив курсов в ее границы.
    Кроме этого, в зависимости от настоек, IDA может автоматически сворачивать все библиотечные функции для экономии места. dseg:027B ; [00000009 BYTES: COLLAPSED FUNCTION sub_0_27B. PRESS KEYPAD "+" TO EXPAND]
    Message(“%b \n”,
    GetFunctionFlags(0x4010FF)
    );
    100000
    Заметим, что в результате упущения этот тип не определен в IDC.IDC и что бы им пользоваться необходимо это сделать самостоятельно, внеся новую строчку:
    #define FUNC_HIDDEN 0x00000040L // a hidden function
    Все атрибуты функция IDA отображает в виде комментариев, расположенных в начале функции. dseg:0271 ;
    Attributes: library function dseg:0271 dseg:0271 __checknull proc near

    171
    dseg:0271 retn dseg:0271 __checknull endp dseg:0272 ;
    Attributes: library function bp-based frame dseg:0272 dseg:0272 __terminate proc
    Операнд
    Пояснения
    Ea Линейный адрес, принадлежащий функции
    Завершение
    Пояснения
    !=BADADDR
    Набор атрибутов функции (смотри таблицу выше)
    Return
    BADADDR
    Ошибка
    success SetFunctionFlags(long ea,long flags);
    Позволяет устанавливать атрибуты функции. Подробнее об этом было сказано в описании функции GetFunctionFlags.
    Операнд
    Пояснения
    Ea
    Линейный адрес, принадлежащий функции flag
    Атрибуты функции (смотри таблицу в описании GetFunctionFlags)
    Завершение
    Пояснения
    !=BADADDR
    Набор атрибутов функции (смотри таблицу выше)
    Return
    BADADDR
    Ошибка
    Как уже отмечалось в описании функции SetFunctionFlags, часто IDA автоматически не распознает функции, не возвращающие управления (нет команды ref в завершении функции).
    Если это критично, то нужный атрибут можно установить вручную. Покажем это на следующем примере: dseg:0272 ; Attributes: library function bp-based frame dseg:0272 dseg:0272 __terminate proc near ; COD dseg:0272 dseg:0272 arg_0 = byte ptr 2 dseg:0272 dseg:0272 mov bp, sp dseg:0274 mov ah, 4Ch ; 'L' dseg:0276 mov al, [bp+arg_0] dseg:0279 int 21h ; DOS dseg:0279 __terminate endp ; AL
    SetFunctionFilegs
    (
    0x10272,
    GetFunctionFlags(0x10272)
    +
    1
    )

    172
    dseg:0272 ; Attributes: library function noreturn bp-based frame dseg:0272 dseg:0272 __terminate proc near ; CODE XREF: sub_0_3C7+44p dseg:0272 dseg:0272 arg_0 = byte ptr 2 dseg:0272 dseg:0272 mov bp, sp dseg:0274 mov ah, 4Ch ; 'L' dseg:0276 mov al, [bp+arg_0] dseg:0279 int 21h ; DOS - 2+ - QUIT WITH EXIT dseg:0279 __terminate endp ; AL = exit code
    В большинстве случаев атрибуты никакого влияния на функции не оказывают. Так, например, если в приведенном примере сбросить флаг FUNC_FRAME, то это не повлечет за собой автоматического удаления всех локальных переменных, адресуемых через BP.
    SetFunctionFilegs
    (
    0x10272,
    GetFunctionFlags(0x10272)

    0x10;
    ) dseg:0272 ; Attributes: library function dseg:0272 dseg:0272 __terminate proc near ; CODE XREF: sub_0_3C7+44p dseg:0272 dseg:0272 arg_0 = byte ptr 2 dseg:0272 dseg:0272 mov bp, sp dseg:0274 mov ah, 4Ch ; 'L' dseg:0276 mov al, [bp+arg_0] dseg:0279 int 21h ; DOS - 2+ - QUIT WITH EXIT dseg:0279 __terminate endp ; AL = exit code
    Но вот установка флага FUNC_HIDDEN приведет к незамедлительному сворачиванию функции и сброс соответственно, наоборот.
    SetFunctionFilegs
    (
    0x10272,
    GetFunctionFlags(0x10272)
    +
    0x40;
    ) dseg:0272 ; [00000009 BYTES: COLLAPSED FUNCTION __terminate. PRESS KEYPAD "+" TO EXPAND]
    char GetFunctionName(long ea);
    Возвращает имя функции. Если указанный адрес не принадлежит ни одной из функций, то возвращается пустая строка.
    Поскольку функции без имени не бывает, то неоднозначной ситуации не возникает.
    Операнд
    Пояснения
    Ea Любой линейный адрес, принадлежащий функции
    Return
    Завершение
    Пояснения

    173
    !=””
    Имя функции
    “”
    Ошибка
    Пример использования: dseg:025E
    __cleanup proc near dseg:025E mov es, cs:DGROUP@ dseg:0263 push si dseg:0264 push di
    Message(“%s \n”,
    GetFunctionName(0x10263)
    );
    __cleanup
    void SetFunctionCmt(long ea, char cmt, long repeatable);
    Задает комментарий, который размещается впереди функции. IDA поддерживает символ переноса, поэтому комментарий может располагаться на нескольких строках.
    Существует возможность повторять тот же комментарий в точке вызова функции
    (так называемый repeatable comment). Для этого необходимо установить флаг ‘repeatable’ равным единице.
    Например:
    SetFunctionCmt(0x10271,”Hello IDA 4.0”,1);
    dseg:0271 ;
    Hello IDA 4.0
    dseg:0271 ; Attributes: static dseg:0271 dseg:0271 __checknull proc near ; CODE XREF: sub_0_3C7+2Cp dseg:0271 retn dseg:0271 __checknull endp
    Если перейти по перекрестной ссылке к месту вызова функции, то там будет можно обнаружить следующее: dseg:03F0 call __restorezero dseg:03F3 call __checknull ;
    Hello IDA
    4.0
    dseg:03F6 cmp [bp+arg_2], 0 dseg:03FA jnz loc_0_40F
    Если в строке комментария будет присутствовать символ переноса, то экран будет выглядеть так:
    SetFunctionCmt(0x10271,”Hello \nIDA 4.0”,1);

    174
    dseg:0271 ;
    Hello dseg:0271 ;
    IDA 4.0
    dseg:0271 ; Attributes: static dseg:03F3 call __checknull ;
    Hello dseg:03F3
    ;
    IDA 4.0
    dseg:03F6 cmp [bp+arg_2], 0
    Не рекомендуется перегружать листинг повторяемыми комментариями. Ведь всегда можно обратиться за разъяснениями к самой функции.
    Наиболее полезны они на начальной стадии дизассемблирования, когда назначение большинства функций плохо понятны и дать им осмысленное имя никак не удается. Тогда в повторяемом комментарии отражают все, что на данный момент известно о каждой из функций и по мере исследования текста, уточняют. На финальной же стадии дизассемблирования, повторяемые комментарии обычно убирают.
    Обратите внимание, каждая функция может обладать комментариями сразу двух типов, но в заголовке будет отображаться только один из них – ‘regular’.
    Например:
    SetFunctionCmt(0x10271,”Hello IDA 4.0”,1);
    SetFunctionCmt(0x10271,”Hello World”,0); dseg:0271 ;
    Hello World dseg:0271 ; Attributes: static dseg:03F3 call __checknull ;
    Hello IDA 4.0 dseg:03F6 cmp [bp+arg_2], 0
    Операнд
    Пояснения
    Ea Любой линейный адрес, принадлежащий функции
    Cmp Строка комментария, включая символ переноса
    Флаг
    Пояснения
    0 Неповторяемый комментарий
    Repeatable
    1 Повторяемый комментарий
    char GetFunctionCmt(long ea, long repeatable);
    Позволяет получить как повторяемый, так и постоянный комментарии. Для этого необходимо задать любой линейный адрес, принадлежащий функции.
    Подробнее о повторяемых комментариях можно прочитать в описании функции
    SetFunctionCmt
    Например: dseg:0271 ;
    Hello IDA 4.0
    dseg:0271 ; Attributes: static dseg:0271 dseg:0271 __checknull proc near dseg:0271 retn dseg:0271 __checknull endp
    Message(“%s \n”,
    GetFunctionCmt(0x010271,1)

    175
    );
    Hello, IDA 4.0
    Message(“%s \n”,
    GetFunctionCmt(0x010271,0)
    );
    Обратите внимание, что необходимо правильно указывать тип комментария
    (повторяемый или нет) иначе функция вернет совсем не то, что от нее ожидается.
    Операнд
    Пояснения
    Ea Любой линейный адрес, принадлежащий функции
    Флаг
    Пояснения
    0 Неповторяемый комментарий
    Repeatable
    1 Повторяемый комментарий
    Завершение
    Пояснения
    !=””
    Комментарий
    Return
    “”
    Ошибка
    long ChooseFunction(char title);
    Создает диалоговое окно содержащие список всех существующих функций с краткой сводной информацией о каждой из них.
    Возвращает линейный адрес начала выбранной функции или BADADDR, если ни одна функция не была выбрана.
    Пример использования:
    Message(“0x%X \n”,
    ChooseFunction(“List”)
    );

    176 0x401020
    Поле
    Function Name
    Имя функции
    Segment
    Сегмент, владеющий функцией
    Start
    Линейный адрес начала
    Length
    Длина функции в байтах
    Атрибут
    Определение
    Пояснение
    R
    !FUNC_NORET
    Функция, возвращающая управление
    F
    FUNC_FAR
    FAR (Далекая) функция
    L
    FUNC_LIB
    Библиотечная функция
    S
    FUNC_STATIC
    Static – функция
    B
    FUNC_FRAME
    BP используется как указатель на кадр стека
    * M
    FUNC_MEMBER member function
    * I
    FUNC_VIRTUAL
    Виртуальная функция
    * C
    FUNC_CTR
    Конструктор
    * D
    FUNC_DTR
    Деструктор
    RFLSBMICDV
    * V
    FUNC_VARARG
    Функция с переменным числом аргументов
    * Не поддерживается в текущих версиях. Зарезервировано для будущего использования.
    Подробнее узнать об атрибутах функции можно в описании SetFunctionFlags.
    Операнд
    Пояснения title Заголовок дианового окна

    177
    Завершение
    Пояснения
    !=BADADDR
    Линейный адрес начала выбранной функции
    Return
    BADADDR
    Ошибка
    По умолчанию подсвечивается функция, в границах которой находится курсор. В противном случае подсвечивается ближайшая функция, лежащая
    «выше» курсора (то есть в более младших адресах)
    Для поиска подстроки в именах функции предусмотрена специальная клавишная комбинация Регистр символов при этом будет игнорироваться.
    Для продолжения поиска необходимо нажать .
    В контекстной помощи сообщатся, что с помощью клавиш и можно соответственно добавлять или удалять функции. Но на самом деле в данном случае эти возможности недоступны.
    или двойной щелчок мышью выбирают функцию и возвращают управление, закрывая диалоговое окно.
    1   ...   13   14   15   16   17   18   19   20   ...   39


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