Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ida.final.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
6 Mб
Скачать

Архитектура структур в ida

Итак, что есть структура с точки зрения IDA? Это, прежде всего элемент bTree, точно как сегмент или функция.

Но в отличие от перечисленных выше, структура не связана ни с каким линейным адресом. Это самостоятельный объект, существующий вне адресного пространства дизассемблируемого файла.

В таком случае возникает вопрос, - а как же к ней может осуществляться доступ? Приходится выбирать другую уникальную характеристику, которая бы отличала одну структуру от другой.

Можно было бы использовать имя, или любую производную от него величину, но разработчик IDA выбрал другой путь. Он связал каждую структуру с 32-разрядным целым числом, то есть идентификатором (сокращенно ID), который возвращался при создании структуры.

Грубо говоря, можно считать идентификатор аналогом дескриптора файла, с которым приходится сталкиваться в современных операционных системах. Различия между ними и в самом деле несущественны, хотя все же существуют – так, например, после закрытия файла, его дескриптор освобождается и может быть повторно присвоен вновь открытому файлу, а идентификаторы уникальны и никогда не присваиваются дважды, – даже если связанный с ними объект был разрушен.

Однако, идентификаторы неудобны тем, что их приходится не только хранить, но и распределять между несколькими процессами. Ведь чаще всего один скрипт (IDA, пользователь) создает структуру, с которой приходится работать совсем другому скрипту.

Точно такая проблема стояла и перед разработчикам операционной системы Zerro Way (более известной широким кругам как Windows NT). И вот и в этом случае выход был один – использовать помимо идентификаторов, поименный доступ к объектам.

Символьные имена в самом деле гораздо удобнее малоосмысленных 32 битных числовых значений. Однако, поддерживать два набора функций, для имен и для идентификаторов по меньшей мере неразумно.

Поэтому в IDA была введена всего лишь одна функция, которая позволяла по имени структуры установить ее идентификатор (GetStrucIdByName). И обратная ей, GetStrucName, которая по идентификатору возвращала имя.

Это позволило писать понятый код наподобие следующего:

DelStruc(

GetStrucIdByName("struc_10")

);

Небольшое замедление выполнения с лихвой окупалось его удобочитаемостью, и поэтому он стал очень популярным (именно так построены все примеры скриптов, приведенные ниже)

Однако, одно лишь это не решало всех проблем. Все равно имя структуры требовалось как-то передавать скрипту, что было не всегда осуществимо.

Поэтому был необходим механизм, обеспечивающий доступ ко всем существующим структурам. Теоретически это можно осуществить с помощью идентификаторов. Так, если проскандировать все числа от нуля до 0xFFFFFFFE, то можно обнаружить все структуры, которые присутствуют в базе и получить к ним доступ.

Но как же это будет медленно! Однако, не стоит быстро отказываться от умный идей. Ведь можно загнать все структуры в один список, проиндексированный числами от нуля до номера последней созданной структуры, – тогда все операции с ним не потребуют никаких накладных расходов.

И в самом деле, IDA поддерживает именно такой список. Так, например, что бы узнать идентификаторы всех существующих структур достаточно выполнить следующий бесхитростный код:

auto a;

a=0;

while(1)

{

Message(“0x%X 0x%X \n”,

a,GetStrucId(a)

);

a=GetNextStrucIdx(a);

if (a==-1) break;

}

Ключевой его фигурой является функция GetStrucid, которая возвращает идентификатор по индексу структуры.

Однако, индексы не жестко связаны с идентификаторами и использовать их для доступа к структурам можно только сразу же после получения. А точнее только на протяжении того времени, в течении которого гарантировано ни одна структура не была добавлена или удалена.

Фактически индексы были введены, что бы было можно быстро получить список структур. И ни для чего большего их использовать не рекомендуется – разве что на свой страх и риск.

При этом будьте внимательны, иначе можно совершить ошибку наподобие следующей:

auto a;

for(a=0;a<GetStrucQty();a++) DelStruc(GetStrucId(a));

С первого взгляда в этих двух строчках нет никакой ошибки и скрипт будет работать как часы, но попробуйте его запустить и произойдет нечто невразумительное.

В чем же дело? Вся причина в том, что индексы обновляются при каждом удалении структуры. То есть, удалив структуру с индексом ноль, мы не может переходить к индексу один, так как индексы были реорганизованы, и теперь нулевому индексу соответствует другая структура, а список был сокращен на единицу.

Правильный код, как бы это ни парадоксально на первый взгляд должен выглядеть так:

auto a;

for(a=0;a<GetStrucQty();a++)

DelStruc(GetStrucId(0));

Поэтому, если вы не хотите искать подобных приключений, не используйте индексы ни для чего другого, кроме как просмотра существующих структур.

Теперь рассмотри, как осуществляется доступ к элементам структуры. Но для начала рассмотрим все характеристики члена структуры. Как известно руководств к языкам высокого уровня – это имя, тип и смещение относительно начала структуры.

Однако, в отличие от языков высокого уровня ассемблер MASM использует глобальное пространство имен, а это означает, что имя каждого члена структуры уникально и не может быть дважды повторено в системе.

Это огромный недостаток, который сводит на нет все преимущества структур. Так, например, если структура MCB (смотри выше) имеет члена с именем size, то невозможно дать тоже имя никакому члену другой структуры.

Впрочем, в TASM-е это ограничение устранено. Но, к сожалению, IDA не поддерживает такого режима работы. Поэтому имя члена могло бы служить идеальным средством доступа к нему, однако, в IDA использован другой подход, который при ближайшем рассмотрении оказывается не только более удобным, но и универсальным.

Доступ к элементам структуры осуществляется по их смещением, а точнее заданием любого, принадлежащего им смещения.

Это позволяет рассматривать структуру, как непрерывный «лоскут» адресного пространства, с «объектами» - членами. Именно так, например, организован доступ к локальным переменным функций.

С точки зрения IDA каждый член структуры характеризуется не только его типом (грубо говоря, размером ячейки), но и может иметь связанные объекты, такие как имя или комментарий.

Более того, член структуры может являться не только ячейкой памяти, но и вложенной структурой!

Методы

Функция

Описание

Long GetStrucQty(void)

Возвращает количество структур, созданных вызовом AddStrucEx

Long GetFirstStrucIdx(void);

Возвращает индекс первой структуры в списке

long GetLastStrucIdx(void);

Возвращает индекс последней структуры в списке

long GetNextStrucIdx(long index);

Возвращает следующий индекс в списке структур

long GetPrevStrucIdx(long index)

Возвращает предыдущий индекс в списке структур

long GetStrucId(long index)

Возвращает ID структуры по индексу.

long GetStrucIdByName(char name);

Возвращает идентификатор структуры по ее имени

char GetStrucName(long id)

Возвращает имя структуры по ее идентификатору

char GetStrucComment(long id,long repeatable);

Возвращает комментарии к структуре

long GetStrucSize(long id)

Возвращает размер структуры в байтах, который равен сумме размера всех ее членов

long GetMemberQty(long id);

Возвращает число членов структуры

long GetStrucNextOff(long id,long offset);

Возвращает смещение начала очередного элемента в структуре

long GetStrucPrevOff(long id,long offset)

Возвращает смещение начала предыдущего элемента структуры

long GetFirstMember(long id);

Возвращает смещение начала первого члена структуры

long GetLastMember(long id);

Возвращает смещение начала (не конца!) последнего члена структуры

char GetMemberName(long id,long member_offset);

Возвращает имя члена структуры

char GetMemberComment(long id,long member_offset,long repeatable);

Возвращает комментарий, связанный с членом структуры

long GetMemberSize(long id,long member_offset);

Возвращает размер члена структуры в байтах

long AddStrucEx(long index,char name,long is_union)

Создает новую структуру

long IsUnion(long id);

Возвращает единицу если тип структуры – объединение

success DelStruc(long id);

удаляет существующую структуру по ее идентификатору

long SetStrucIdx(long id,long index);

Изменяет индекс структуры

long SetStrucName(long id,char name)

Изменяет имя структуры

long SetStrucComment(long id,char comment,long repeatable)

Задает комментарий к структуре

long DelStrucMember(long id,long member_offset);

Удаляет члена структуры

long SetMemberName(long id,long member_offset,char name)

Изменяет имя члена структуры

long SetMemberType(long id,long member_offset,long flag,long typeid,long nitems

Изменяет тип члена структуры

long SetMemberComment(long id,long member_offset,char comment,long repeatable)

Задает комментарий члена структуры

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]