Анимация
JavaScript
|
Главная Библионтека
По умолчанию подсвечивается функция, в границах которой находится курсор. В противном случае подсвечивается ближайшая функция, лежащая «выше» курсора (то есть в более младших адресах) Для поиска подстроки в именах функции предусмотрена специальная клавишная комбинация <Atl-T> Регистр символов при этом будет игнорироваться. Для продолжения поиска необходимо нажать <Ctrl-T>. В контекстной помощи сообщатся, что с помощью клавиш <ins> и <delete> можно соответственно добавлять или удалять функции. Но на самом деле в данном случае эти возможности недоступны. <Enter> или двойной щелчок мышью выбирают функцию и возвращают управление, закрывая диалоговое окно. char GetFuncOffset(long ea); Преобразует линейный адрес к строковому представлению в следующем формате: ИмяФункции+СмещениеОтносительноНачалаФункции. Смещение представлено в шестнадцатеричном виде без префиксов и постфиксов. Например: . text:004010FF amsg exit text:004010FF text:004010FF text:004010FF arg 0 text:004010FF text:004010FF text:00401106 text:00401108 text:0040110D text:0040110D loc 0 40110D text:0040110D text:00401111 text:00401116 text:0040111B text:00401121 text:00401121 amsg exit text:00401121 text:00401122 text:00401123 proc near = dword ptr 4 call push call push call pop endp retn dword 0 408758, 2 short loc 0 40110D FF MSGBANNER [esp+arg 0] nmsg wRite 0FFh off 0 408050 Message("%s \n", GetFuncOffset(0x401108) amsg exit+9
"" I Ошибка Если смещение относительно функции равно нулю, то вызов GetFuncOffset возвратит только одно имя. long FindFuncEnd(long ea); Описание этой функции, приведенное в контекстной помощи, немного запутанное и с первого взгляда назначение этой функции не ясно. Но на самом деле она очень находит широкое применение в автономных скриптах. Основное ее назначение - определение линейного адреса при создании функции. Это сопряжено со следующими трудностями - прежде всего необходимо, что бы адрес конца не превышал линейного адреса следующей за ней функции, поскольку функции перекрываться не могут. Например:
Функция start не завершается командой возврата ret. Вместо этого она перывает выполнение программы, процедурой Halt. Если пытаться создать функцию, определяя линейный адрес ее конца поиском ret, то полученный адрес будет принадлежать функции sub 0 22DDl Следовательно, адрес конца не может превышать линейный адрес следующей функции. Вторая проблема заключается в отождествлении инструкции возврата. Это может быть все что угодно. И RETN, и RETF Таким образом, определение конца функции «вручную» оказывается слишком утомительно. И тогда стоит прибегнуть к вызову FindFincEnd. Что она делает? Она возвращает линейный адрес на единицу больший линейного адреса конца функции, которая может быть успешно создана. Таким образом, задача создания определения адреса конца функции для ее создания упрощается, тем более, что FindFuncEnd ищет не первую встретившуюся ей инструкцию возврата, а последнюю в цепочке перекрестных ссылок на следующую команду (подробнее об этом рассказано в главе «Перекрестные ссылки»). Отсюда следует тот замечательный факт, что она поддерживает функций со множественными возвратами (а таким, как правило большинство). Например: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: 0100 start: 0100 0103 0106 0106 0106 0106 0108 010A 010B 010B 010B 010B 010E 010E ; ------ 010F aMyfile mov ax, 3D01h mov dx, 10Fh retn loc 0 10B loc 0 10B: mov ax, 0FFFFh retn db MyFile,0 Message("0x%X \n", FindFuncEnd(0x10103) 0x1010F Обратите внимание, что IDA эмулировала выполнение команды условного перехода и правильно определила точку выхода из функции. Однако, если быть уж совсем «буквоедом», то можно заметить, что строка aMyFIle вероятнее всего принадлежала функции, но IDA автоматически не смогла это распознать. Поэтому иногда результат работы функции все же приходится корректировать. Очень важный факт - линейный адрес должен указывать на начало команды, иначе вызов провалиться. Например: Message("0x%X \n", FindFuncEnd(0x10102) 0xFFFFFFFF То же самое произойдет если по указанному адресу будет расположены данные, так что функцию будет создать невозможно. Если же функция уже существует, то вызов FindFuncEnd так же возврат адрес ее конца:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [ 58 ] 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |