Анимация
JavaScript
|
Главная Библионтека ea = BASE * 0x10 + offset Формула 2 Перевод сегментного адреса в линейный Подавляющее большинство функций IDA работают не с сегментными, а с линейными адресами. Пользователь же, напротив, видит на экране дизассемблера в основном сегментные адреса, а линейные от его взора скрыты. Для облегчения преобразования сегментных адресов в линейные предусмотрен специальный макрос MK FP(long BASE, long offset), возвращающий значение BASE*0x10+offset, а так же оператор «квадратные скобки» - "[BASE, offset]" аналогичного назначения. Линейные адреса начала и конца сегмента представляют собой 32-битовые значения, ограничивающие максимальный размер сегмента четырьмя гигабайтами. Базовый адрес представляет собой 16-битовое значение, ограничивающее адресуемую память одним мегабайтом, которого в ряде случаев оказывается недостаточно. Замечание: размер сегмента ограничен разрядностью линейных адресов его начала и конца и составляет 4 гигабайта, но выбор адреса начала сегмента, первый байт которого имеет нулевое смещение, ограничен разрядностью базового адреса, и равен BASEmax* 0x10 = OxFFFF * 0x10 = OxFFFFO, т.е. немногим менее одного мегабайта. Выход состоит в использовании селекторов, ссылающихся на 32-разрядные адреса, что позволяет адресовать с их помощью до 4 гигабайт. К селектору можно обратится по его индексу в таблице селекторов. Индексы представляют собой 16-разрядные целые значения, увеличивающиеся с каждым очередным элементом на единицу. Элементы таблицы - 32-разрядные базовые адреса сегмента, измеряемые в параграфах. Таблица селекторов представляет собой разряженный массив, допуская создание элементов с несмежными индексами. Например, 0x5,0x07,0x16,0x88 Если при создании сегмента в качестве базового адреса указать индекс созданного ранее селектора, его значение будет автоматически использовано для базирования данного сегмента. Аналогично, если создать селектор, совпадающий с базовым адресом некоторого сегмента, для его базирования станет использоваться значение селектора, а не базовый адрес. С каждым сегментом связан ряд атрибутов - имя сегмента, кратность выравнивания, разрядность и объединение. Никакой из атрибутов, включая имя, уникальной характеристикой сегмента не является и вполне допустимо существование двух и более сегментов с одинаковыми именами (однако, ассемблеры не смогут откомпилировать исходный тест, содержащий несколько одноименных сегментов). Замечание: создание двух сегментов с одинаковыми базовыми адресами допускается, но пользоваться этой возможностью категорически не рекомендуется. Над каждым сегментом можно выполнять следующие операции - создание и удаление сегментов, получение и изменение основных характеристик сегментов (линейного адреса начала, линейного адреса конца, базового адреса), получение и изменение атрибутов сегмента (имя, кратность выравнивания, разрядность и т.д.). Подробнее об этом рассказано в главе «Функции, работающие с сегментами и селекторами». Навигатор по функциям Для изучения организации сегментов и селекторов рекомендуется загрузить полученный в главе «Виртуальная память» файл "tutor.idb" в дизассемблер, при этом экран IDA должен выглядеть так:
Для создания нового сегмента можно воспользоваться вызовом функции SegCreate(long startea,long endea,long base,long use32,long align,long comb), последовательно передав ей адрес начала сегмента, адрес конца сегмента, базовый адрес сегмента, разрядность сегмента, кратность выравнивания и атрибуты (о трех последних аргументах подробно рассказано в описании функции SegCreate, сейчас их можно принять равными нулю), например, так: «SegCreate(0x10000, 0x10012, 0x1000, 0, 0, 0);» seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: 0000 0000 0000 0000 0000 0001 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010 0011 0011 ; Segment type: Relar seg000 segment at 1000h private use16 assume cs:seg000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing seg000 db db db db db db db db db db db db db db db db db db ends 48h 65h 6Ch 6Ch 6Fh 2Ch 20h 49h 44h 41h 20h 50h 6Fh 21h 20h 0Dh Создав новый сегмент, IDA автоматически присвоила ему имя "seg000", где "000" порядковый номер (считая от нуля) созданного сегмента. Последующие сегменты будут названы "seg001", "seg002" и т.д. Функция "long SegByName(char segname)" позволяет узнать линейный адрес базового адреса сегмента4 по его имени. Ее вызов может выглядеть, например, так: Message(">%X\n > 10000 SegByName("seg000")); Переименовать сегмент можно с помощью функции "success SegRename(long ea, char name)" принимающей в качестве первого аргумента любой линейный адрес, принадлежащий указанному сегменту, а вторым - его новое имя. Например: SegRename(SegByName("seg000"),"MySeg"); MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg MySeg 0000 ; Segment type: Relar
Для удаления сегментов предусмотрена функция "success SegDelete (long ea, long disable)" Если флаг "disable" равен нулю, будет удален лишь сам сегмент, а содержимое принадлежащих ему ячеек сохранится, в противном случае вместе с сегментом будет удалены и все принадлежащие ему адреса виртуальной памяти. Сравните: SegDelete(0x10000, 0); SegDelete(0x10000, 0);
п[И] IDA view-A Густой экран дизассемблера Т.е. функция возвращает базовый адрес, тут же умножая его на 0x10 для перевода в линейный. 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 |