Анимация
JavaScript


Главная  Библионтека 

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

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 должен выглядеть так:

0:00010000

0:00010001

0:00010002

0:00010003

0:00010004

0:00010005

0:00010006

0:00010007

0:00010008

0:00010009

0:0001000A

0:0001000B

0:0001000C

0:0001000D

0:0001000E

0:0001000F

0:00010010

Для создания нового сегмента можно воспользоваться вызовом функции 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

0000 MySeg

segment at 1000h private

0000

sume cs

:MySeg

0000

assume es:nothing, ss:no

0000

48h ;

0001

65h ;

0002

6Ch ;

0003

6Ch ;

0004

0005

2Ch ;

0006

20h ;

0007

49h ;

0008

0009

41h ;

000A

20h ;

000B

50h ;

000C

72h ;

000D

000E

21h ;

000F

20h ;

0010

0Dh ;

0011

0Ah ;

0011 MySeg

ends

Для удаления сегментов предусмотрена функция "success SegDelete (long ea, long disable)" Если флаг "disable" равен нулю, будет удален лишь сам сегмент, а содержимое принадлежащих ему ячеек сохранится, в противном случае вместе с сегментом будет удалены и все принадлежащие ему адреса виртуальной памяти.

Сравните:

SegDelete(0x10000, 0);

SegDelete(0x10000, 0);

0:00010000

48h ;

0:00010001

65h ;

0:00010002

6Ch ;

0:00010003

6Ch ;

0:00010004

0:00010005

2Ch ;

0:00010006

20h ;

0:00010007

49h ;

0:00010008

0:00010009

41h ;

0:0001000A

20h ;

0:0001000B

50h ;

0:0001000C

72h ;

0:0001000D

п[И] 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