Описание функций встроенного языка
Скачать 2.86 Mb.
|
МЕТОДЫ Функция Назначение long CreateArray(char name) Создает новый массив long GetArrayId(char name) Возвращает идентификатор массива по его имени success RenameArray(long id,char newname) Переименовывает массив void DeleteArray(long id) Удаляет массив success SetArrayLong(long id,long idx,long value) Присваивает значение индексу массива типа «длинное целое» success SetArrayString(long id,long idx,char str) Присваивает значение индексу массива типа «строка» char or long GetArrayElement(long Возвращает значения обоих типов 358 tag,long id,long idx элементов success DelArrayElement(long tag,long id,long idx) Удаляет один элемент массива long GetFirstIndex(long tag,long id); Возвращает индекс первого элемента long GetLastIndex(long tag,long id); Возвращает индекс последнего элемента long GetNextIndex(long tag,long id,long idx) Возвращает следующий индекс элемента массива long GetPrevIndex(long tag,long id,long idx) Возвращает предыдущий индекс элемента массива success SetHashLong(long id,char idx,long value Присваивает значение элементу массива типа «длинное целое» success SetHashString(long id,char idx,char value); Присваивает значение элементу массива типа «строка» long GetHashLong(long id,char idx) Возвращает значение элемента типа «длинное целое» char GetHashString(long id,char idx) Возвращает значение элемента типа «строка» success DelHashElement(long id,char idx) Удаляет элемент ассоциативного массива char GetFirstHashKey(long id) Возвращает индекс первого элемента массива char GetLastHashKey(long id) Возвращает индекс последнего элемента массива char GetNextHashKey(long id,char idx) Возвращает индекс следующего элемента массива char GetPrevHashKey(long id,char idx); Возвращает индекс предыдущего элемента массива long CreateArray(char name); Функция создает новый разряженный массив, в котором можно будет хранить данные обоих типов – как строковые, так и длинные целые. Массив сохраняется в базе IDA как элемент Btree до тех пор, пока не будет принудительно удален из нее. Никаких ограничений на размер массива не налагается. Каждый массив должен иметь свое уникальное имя (два массива с одинаковыми именами существовать не могут). Массивы имеют собственное пространство имен (то есть 359 можно создать метку или сегмент совпадающую с именем уже существующего массива и наоборот) На имена наложены следующие ограничения – длина до 120 символов, может начинаться с цифры, но не должен содержать пробелов. При успешном завершении функция возвращает идентификатор массива, в противном случае (массив с таким именем уже существует?) BADADDR. Пример: Message("0x%X \n", CreateArray("MyArray") ); 0xFF000041 Операнд Пояснения name Имя массива ==return Пояснения !=BADADDR Идентификатор массива Return ==0 Ошибка long GetArrayId(char name); Функция возвращает идентификатор массива по его имени. Это позволяет не сохранять идентификаторы массивов, полученные при их создании, а обращаться к массивам по имени. Например: Message("0x%X \n", CreateArray("MyArray") ); Message(“0x%X \n” GetArrayId(“MyArray”) ); DeleteArray( GetArrayId(“MyArray”) ); Message(“0x%X \n” GetArrayId(“MyArray”) ); 0xFF000041 0xFF000041 0xFFFFFFFF Операнд Пояснения name Имя массива ==return Пояснения !=BADADDR Идентификатор массива Return ==0 Ошибка 360 success RenameArray(long id,char newname); Функция позволяет изменить имя массива, заданного идентификатором. Обычно используется редко. Например: Message("0x%X \n", CreateArray("MyArray") ); 0xFF000041 RemaneArray( GetArrayId(“MyArray”), “MyNewname” ); Message(“0x%X \n” GetArrayId(“MyNewName”) ); 0xFF000041 Операнд Пояснения id Идентификатор массива Newname Новое имя массива ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка void DeleteArray(long id); Функция удаляет массив, заданный идентификатором. Необходимо помнить, что массивы, как элемент Btree хранятся в базе IDA то того момента, пока не будут удалены. Это можно сделать, например, следующим образом: DeleteArray( GetArrayId(“MyArray”) ); Операнд Пояснения id Идентификатор массива success SetArrayLong(long id,long idx,long value); Функция присваивает значение типа «длинное целое» элементу массива, заданного идентификатором. Индекс массива выражается 32-битным целым числом. Разряженные массивы позволяют эффективно хранить данные, не резервируя памяти под несуществующие элементы. 361 Поэтому индексы не обязательно должны следовать один за другим. Так, например, массив может состоять всего из двух индексов, – скажем 0х0 и 0х10000, – при этом будет потрачено всего две ячейки памяти. Необходимо помнить, что один и тот же индекс, одного и того же массива может хранить одновременно данные двух тиров – как строковые, так и длинные целые и никакого «затирания при этом не происходит». Пример использования: SetArrayLong( GetArrayId(“MyArray”), 0x100, 0x666); Операнд Пояснения id Идентификатор массива idx Индекс массива value Присваиваемое значение типа «длинное целое» ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка success SetArrayString(long id,long idx,char str); Функция присваивает значение типа «строка» элементу массива, заданного идентификатором. Индекс массива выражается 32-битным целым числом. Разряженные массивы позволяют эффективно хранить данные, не резервируя памяти под несуществующие элементы. Поэтому индексы не обязательно должны следовать один за другим. Так, например, массив может состоять всего из двух индексов, – скажем 0х0 и 0х10000, – при этом будет потрачено всего две ячейки памяти. Необходимо помнить, что один и тот же индекс, одного и того же массива может хранить одновременно данные двух тиров – как строковые, так и длинные целые и никакого «затирания при этом не происходит». Пример использования: SetArrayString( GetArrayId(“MyArray”), 0x100, “MyString”); Операнд Пояснения id Идентификатор массива idx Индекс массива str Присваиваемое значение типа «строка» ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка 362 char or long GetArrayElement(long tag,long id,long idx); Функция служит для чтения обоих типов элементов разряженных массивов. Выбор интересующего типа осуществляется тегом tag. Он может принимать следующие значения: Определение Значение AR_LONG 'A' Элемент типа «длинное целое» AR_STR 'S' Элемент типа «строка» Запрашиваемый индекс должен быть инициализирован ранее, иначе функция вернет ошибку. Пример использования: SetArrayLong( GetArrayId(“MyArray”), 0x100, 0x666); SetArrayString( GetArrayId(“MyArray”), 0x100, “MyString”); Message(“%s \n0x%X\n”, GetArrayElement(AR_STR, GetArrayId(“MyArray”), 0x100), GetArrayElement(AR_LONG, GetArrayId(“MyArray”), 0x100), ); MYString 0x666 Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива idx Индекс массива ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка success DelArrayElement(long tag,long id,long idx); Функция удаляет указанный тип элемента разряженного массива. Тип задается тегом tag, который может принимать следующие значения, перечисленные ниже в таблце: 363 Определение Значение AR_LONG 'A' Элемент типа «длинное целое» AR_STR 'S' Элемент типа «строка» Пример использования: DelArrayElement(AR_LONG, GetArrayId(“MyArray”), 0x100); Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива idx Индекс массива ==return Пояснения ==1 Успешное завершение Return ==0 Ошибка long GetFirstIndex(long tag,long id); Функция возвращает индекс первого элемента разряженного массива. В отличие от «обычных» массивов, известных нам по языками С и Pascal, разряженные массивы могут начинаться с любого индекса, а не обязательно с нулевого. «Первым» индексом разряженного массива будет индекс инициализированного элемента с наименьшим числовым значением. Например: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetArrayLong(a,0x100,0x666); SetArrayLong(a,0x77,0x67); SetArrayLong(a,0x210,0x777); Message("0x%X \n", GetFirstIndex(AR_LONG,a) ); DeleteArray(a); 0x77 Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива ==return Пояснения !=BADADDR Индекс первого элемента разряженного массива Return ==BADADDR Ошибка 364 long GetLastIndex(long tag,long id); Функция возвращает индекс последнего элемента разряженного массива. Обратите внимание, что число элементов разряженного массива обычно много меньше, чем индекс последнего из них. Так, например, массив может состоять всего из трех элементов с индексами, скажем, (0x5, 0x777, 0x666777) – тогда функция GetLastIndex возвратит 0x666777, тогда как размер массива равен всего лишь трем. К сожалению не предоставлено никаких функций, позволяющих узнать размер массива. Все что можно сделать это пройтись по цепочке элементов функциями GetNextIndex (GetPrevIndex). Поэтому, вызов GetLastIndex используется очень редко, так как в нем особой нужды обычно и не бывает. Пример использования: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetArrayLong(a,0x100,0x666); SetArrayLong(a,0x77,0x67); SetArrayLong(a,0x210,0x777); Message("0x%X \n", GetLastIndex(AR_LONG,a) ); DeleteArray(a); 0x210 Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива ==return Пояснения !=BADADDR Индекс последнего элемента разряженного массива Return ==BADADDR Ошибка long GetNextIndex(long tag,long id,long idx); Функция возвращает следующий индекс разраженного массива. Как уже было сказано выше, в разряженных массивах индексы не обязательно следуют друг за другом, а могут быть разделены «дырами» произвольного размера. Поэтому, для «путешествия» по цепочке инициализированных элементов массива и была введена функция GetNextIndex. Передаваемый текущий индекс (idx) не обязательно должен существовать в природе, - функция возвращает первый же инициализированный за ним элемент. Это дает возможность отказаться от использования функции GetFirstIndex, поскольку GetNextIndex(,,0) ему полностью эквивалентен, что и показано на примере, приведенном ниже: auto a,b; b=0; DeleteArray(GetArrayId("MyArray")); 365 a=CreateArray("MyArray"); SetArrayLong(a,0x100,0x666); SetArrayLong(a,0x77,0x67); SetArrayLong(a,0x210,0x777); while(1) { b=GetNextIndex(AR_LONG,a,b); if (b==-1) break; Message("0x%X \n",b); } DeleteArray(a); 0x77 0x100 0x210 Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива idx Индекс массива ==return Пояснения !=BADADDR Следующий индекс Return ==BADADDR Ошибка long GetPrevIndex(long tag,long id,long idx) Функция возвращает предыдущий индекс разраженного массива. Как уже было сказано выше, в разряженных массивах индексы не обязательно следуют друг за другом, а могут быть разделены «дырами» произвольного размера. Поэтому, для «путешествия» по цепочке инициализированных элементов массива и была введена функция GetPrevIndex. Передаваемый текущий индекс (idx) не обязательно должен существовать в природе, - функция возвращает первый же предшествующий ему инициализированный элемент. Это дает возможность отказаться от использования функции GetPrevIndex, поскольку GetPrevIndex(,,-1) ему полностью эквивалентен, что и показано на примере, приведенном ниже: auto a,b; b=0; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetArrayLong(a,0x100,0x666); SetArrayLong(a,0x77,0x67); SetArrayLong(a,0x210,0x777); while(1) { b=GetPrevIndex(AR_LONG,a,b); if (b==-1) break; Message("0x%X \n",b); } DeleteArray(a); 366 0x210 0x100 0x77 Операнд Пояснения ==tag Значение AR_STR Элемент типа «строка» tag AR_LONG Элемент типа «длинное целое» id Идентификатор массива idx Индекс массива ==return Пояснения !=BADADDR Предыдущий индекс Return ==BADADDR Ошибка АССОЦИАТИВНЫЕ МАССИВЫ ОБ АССОЦИАТИВНЫХ МАССИВАХ Ассоциативные массивы это маленькое чудо IDA. Большинству программистам возможно ранее никогда не приходилось сталкиваться ни с чем подобным. К сожалению, о них очень мало (ну совсем ничего) не сказано в контекстной помощи, поэтому будет не лишим остановиться на них и рассмотреть подробнее. Один из распространенных языков, поддерживающим такие конструкции можно назвать Perl, который ввиду свой кросс - платформенности стал очень популярен среди разработчиков Internet – приложений. Но многие тысячи поклонников Си и Pascal могли и вовсе не слышать о нем, а уж тем более изыскивать время для досконального изучения. Когда-то авторитет программиста зависел от числа освоенных им языков. Сегодня же ситуация переменилась – разработчики предпочитают сосредоточиваться не только на одном языке, но даже компиляторы, зачастую совершенно не интересуясь, что происходит у «соседей». К сожалению, ставшие популярными языки многие конструкции реализуют далеко не лучшим образом, если вообще реализуют это. Так случилось и с ассоциативными массивами. Чем они отличаются от своих собратьев? И какие возможности предоставляют при этом? Уникальность ассоциативных массивов в том, что они индексируются строковыми значениями. Причем строковыми в буквальном смысле этого слова, - никакого хеширования или иного преобразования в численный вид не проводится. Это позволят значительно упрощать многие алгоритмы, раньше выглядевшие громоздкими, - например, пусть нам требуется составить таблицу, перечисляющую имена сотрудников и получаемую ими зарплату. Традиционно потребовалось бы создавать три массива, а потом обвязывать все это кодом, гарантирующим согласованность и непротиворечивость данных. Насколько же проще решается задача с использованием ассоциативных массивов Кроме этого можно придумать массу других примеров. АРХИТЕКТУРА АССОЦИАТИВНЫХ МАССИВОВ Ассоциативные массивы представляют собой всего лишь подкласс обычных разряженных массивов, которые уже были подробно рассмотрены выше. 367 Ассоциативные массивы создаются вызовом функции CraeteArray, точно так же как и обычные разряженные. Кроме того, любой массив по сути одновременно является и разряженным и ассоциативным. Точнее, масивов на самом деле все же несколько, но идентификатор (ID) у всех может быть один. Поэтому к ассоциативным массивам применимы описанные выше функции RenameArray и DeleteArray. Новым является набор менее чем из десятка функций работающий со строковыми индексами. Вообще же в терминологии ассоциативных массивов индексы называются ключами. Каждый ключ предстваляет собой строковое значение без явных ограничений (во всяком случае в контекстой помощи IDA на этот счет ничего не сказано) и может содержать один элемент типа «строка» или «длинное целое» Обратите внимание, тогда как каждый индекс разряженного массива может одновременно содержать элементы двух типов, то каждый ключ ассоциативного массива ссылается лишь на одно значение того или иного типа. В остальном же операции с элементами ассоциативных массивов ничем не отличаются от уже описанных выше. Собственно всеми манипуляциями заведут всего три функции. Элемент можно присвоить, прочитать, и, наконец, удалить. На этом предоставляемые IDA возможности заканчиваются. Более интересны операции, выполняемые над ключами. Поскольку теперь они представляют собой строковые значения, то может быть не совсем понятно с первого взгляда, как можно выполнить даже такую тривиальную операцию, как перечислить все элементы массива. На самом деле для этого существуют традиционные функции GetNext и GetPrev. Очевидно, что они перечисляют ключи (то есть индексы) массива один за другим, но вот в каком порядке? Вообще-то это не документировано, и поэтому стоит проектировать код скрипта так, чтобы его работоспособность не зависела от подобного рода деталей. Но как нетрудно убедиться, все текущие версии IDA упорядочивают список индексов в алфавитном порядке, не зависимо от очередности создания элементов. Необходимо заметить, что некоторые языки упорядочивают индексы ассоциативных массивов именно в порядке их создания, и никем не гарантируется, что так не будет и в следующих версиях IDA (хотя, это конечно, очень маловероятно). Однако, ваш скрипт не должен завистеть от этих деталей. success SetHashLong(long id,char idx,long value); Функция присваивает значение элементу ассоциативного массива. Ассоциативные массивы выгодно отличаются от остальных тем, что могут индексироваться строковыми значениями! В остальном же с ними могут использоваться те же подходы, что и для разряженных массивов. Однако, в отличие от разреженных массивов один и тот же индекс не может содержать числовое и строковое значение одновременно. Пример использования: auto a; DeleteArray(GetArrayId("MyArray")); a=CreateArray("MyArray"); SetHashLong(a," |