Описание функций встроенного языка
Скачать 2.86 Mb.
|
??? #Верстальщику – change table аргумент пояснения ea линейный адрес, принадлежащий сегменту startea 32-разрядный линейный адрес нового начала сегмента endea величина на единицу большая последнего принадлежащего сегменту адреса disable уничтожать освободившиеся адреса =return пояснения ==1 успешное завершение операции return ==0 ошибка Родственные функции: SegCreate Интерактивный аналог: Функция принимает любой линейный адрес, принадлежащий сегменту, и возвращает линейный адрес начала данного сегмента. Если переданный адрес не принадлежит ни одному сегменту, функция возвратит BADADDR, сигнализируя об ошибке. Пример использования: SegCreate(0x10000,0x20000,0x1000,0,0,0); a) создаем сегмент с адресом начала 0x10000 и адресом конца 0x20000 0. Creating a new segment (00010000-00020000) ... ... OK b) сегмент успешно создан Message(">%X\n",SegStart(0x10100)); c) вызываем функцию SegStart, передавая ей один из адресов, принадлежащих сегменту 64 >10000 d) результат – функция вернула адрес начала сегмента ??? #верстальщику – change table аргумент пояснения ea линейный адрес принадлежащий сегменту =return пояснение !=BADADDR линейный адрес начала сегмента return ==BADADDR ошибка Родственные функции: SegEnd Интерактивный аналог: “View\Segments” адрес начала сегмента –––––––––––––––––––––––––––––––––––––––––––––––––––––––––--┐ │ ╔═[■]═════════════════════════════════ Program Segmentation ═════════════════════│═════════3═[↑]═╗ ║ Name Start End Align Base Type Cls 32es ss ds fs gs ▼ ▲ ║ seg000 00000000 00010000 at 1000 pri N FFFF FFFF FFFF FFFF FFFF 00010000 00020000 ▓ ║ ▓ ║ ▼ ╚1/1 ══════════════════◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒►─┘ long SegEnd(long ea) Функция принимает любой линейный адрес, принадлежащий сегменту, и возвращает линейный адрес конца данного сегмента. Если указанный адрес не принадлежит ни одному сегменту, функция возвратит значение BADADDR, сигнализируя об ошибке. Линейный адрес конца сегмента на единицу больше наибольшего адреса, принадлежащего сегменту. Подробнее об этом рассказывается в описании функции SegCreate. Пример использования: SegCreate(0x1000,0x2000,0x100,0,0,0); SegCreate(0x2000,0x3000,0x200,0,0,0); a) создаем два смежный сегмента с адресами начала и конца 0x1000; 0x2000 и 0x2000; 0x3000 соответственно 0. Creating a new segment (00001000-00002000) ... ... OK 1. Creating a new segment (00002000-00003000) ... ... OK b) сегменты успешно созданы Message(">%X\n",SegEnd(0x1100)); c) вызываем функцию SegEnd, передавая ей один из адресов, принадлежащих первому сегменту >2000 d) результат – адрес конца первого сегмента Message(">%X\n",SegStart(0x2000)); e) вызываем функцию SegStart, передавая ей адрес конца первого сегмента >2000 f) результат – адрес начала второго сегмента. Таким образом, наглядно 65 продемонстрировано – адрес конца сегмента не принадлежит самому сегменту. ??? #верстальщику – change table аргумент пояснения ea любой 32-разрядный линейный адрес, принадлежащий сегменту =return пояснения !=BADADDR линейный адрес конца сегмента return ==BADADDR ошибка Родственные функции: SegStart Интерактивный аналог: “View\Segments” адрес конца сегмента –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––--┐ │ ╔═[■]═════════════════════════════════ Program Segmentation ═════════════════════════==═====═══│═3═[↑]═╗ ║ Name Start End Align Base Type Cls 32es ss ds fs gs ▼ ▲ ║ seg000 00000000 00010000 at 1000 pri N FFFF FFFF FFFF FFFF FFFF 00010000 00020000 ▓ ║ ▓ ║ ▼ ╚1/1 ══════════════════◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒►─┘ long SegByName(char segname) Функция по имени сегмента (с учетом регистра) определяет его базовый адрес. Если базовый адрес представляет собой селектор, то функция автоматически возвратит его значение. Если сегмента с указанным именем не существует, функция возвратит значение BADADDR, сигнализируя об ошибке. Детали: а) вызов SegByName – единственный способ определения базового адреса сегмента. Чтобы определить базовый адрес сегмента, по некому линейному адресу, принадлежащему сегменту, необходимо воспользоваться конструкцией BASE = SegByName(SegName(ea)). b) Поскольку, IDA допускает совместное существование двух и более одноименных сегментов, определение базового адреса сегмента по ему имени позволяет определишь базовый адрес лишь одного из них. Но никакого другого (во всяком случае документированного) способа определения базового адреса не существует и выходом из такой ситуации становится отказ от использования одноименных сегментов. Пример использования: SegCreate(0x1000,0x2000,0x100,0,0,0); SegRename(0x1000,"MySeg"); a) создаем новый сегмент с базовым адресом 0x1000 и тут же переименовываем его в “MySeg” Message(">%X\n",SegByName("MySeg")); b) вызываем функцию SegByName передавая ей имя только что созданного сегмента 66 >1000 c) результат – базовый адрес сегмента MySeg SegCreate(0x2000,0x3000,0x200,0,0,0); SegRename(0x2000,"MySeg"); d) создаем второй сегмент с именем “MySeg”, но на этом раз базовым адресом, равным 0x2000 ╔═[■]════════════════════════════════ Program Segmentation ═══════════════════════════════4═[↑]═╗ ║ Name Start End Align Base Type Cls 32es ss ds fs gs ▲ ║ MySeg 00000000 00001000 at 0100 pri N FFFF FFFF FFFF FFFF FFFF 00001000 00002000 ▒ ║ MySeg 00000000 00001000 at 0200 pri N FFFF FFFF FFFF FFFF FFFF 00002000 00003000 ■ ║ ▼ ╚2/2 ═════════════════◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒►─┘ e) это получилось! Теперь существуют два одноименных сегмента Message(">%X\n",SegByName("MySeg")); f) вызываем функцию SegByName передавая ей имя “MySeg” >1000 g) результат – базовый адрес первого сегмента ??? #верстальщику – change table аргумент пояснения segname имя сегмента (регистр учитывается) =return пояснения !=BADADDR базовый адрес сегмента или значение селектора return ==BADADDR ошибка Родственные функции: SegRename, SegName Интерактивный аналог: “View\Segments” базовый конца сегмента –––––––––--┐ ┌–- имя сегмента │ ╔═[■]═══▼══=====═════════════════=═════▼══ Program Segmentation ═════════════════════==═=====════3═[↑]═╗ ║ Name Start End Align Base Type Cls 32es ss ds fs gs ▲ ║ seg000 00000000 00010000 at 1000 pri N FFFF FFFF FFFF FFFF FFFF 00010000 00020000 ▓ ║ ▓ ║ ▼ ╚1/1 ══════════════════◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒►─┘ long SegByBase(long base) Функция по базовому адресу (селектору) сегмента определяет линейный адрес его начала. Если передать базовый адрес, не принадлежащий ни одному сегменту, или существующий, но не использующийся ни одним сегментом селектор, функция возвратит значение BADADDR, сигнализируя об ошибке. Поскольку, IDA допускает совместное существование двух и более сегментов с одинаковыми базовыми адресами, определение адреса начала сегмента по его базовому адресу позволяет определишь адрес начала лишь одного из них. Пример использования: SegCreate(0x1100,0x2000,0x100,0,0,0); a) создаем сегмент с базовым адресом 0x100 и линейным адресом начала 0x1100 Message(">%X\n",SegByBase(0x100)); 67 b) вызываем функцию SegByBase для получения линейного адреса начала сегмента по его базе >1100 c) результат – линейный адрес начала сегмента ??? #верстальщику – change table аргумент пояснения base базовый адрес сегмента или значение селектора =return пояснения !=BADADDR линейный адрес начала сегмента return ==BADADDR ошибка Родственные функции: SegByName Интерактивный аналог: “View\Segments” базовый конца сегмента –––––––-–––––-┐ │ линейный адрес начала сегмента -┐ ╔═[■]═══========═════════════════=═════▼══ Program Segmentation ═════════════════════== │====════3═[↑]═╗ ║ Name Start End Align Base Type Cls 32es ss ds fs gs ▼ ▲ ║ seg000 00000000 00010000 at 100 pri N FFFF FFFF FFFF FFFF FFFF 0001100 0002000 ▓ ║ ▓ ║ ▼ ╚1/1 ══════════════════◄■▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒►─┘ success SegRename(long ea,char name) Функция переименовывает сегмент, возвращая при удачном завершении операции ненулевое значение и ноль в противном случае. Аргумент ea представляет собой любой линейный адрес, принадлежащий сегменту. Если передать адрес не принадлежащий никакому сегменту, функция возвратит ошибку. Аргумент name задает новое имя сегмента с учетом регистра. Если имя начинается с цифры, функция автоматически дополнит его знаком прочерка. Если в имени содержится недопустимые символы, они будут автоматически заменены знаком прочерка. Допустимые символы перечисляются в полях NameChars конфигурационного файла Попытка присвоить сегменту пустое имя (аргумент name равен “”) приводит к ошибке. IDA допускает существование двух и более сегментов с одинаковыми именами, однако, использование этой возможности влечет невозможность определения базового адреса сегмента. Подробнее – см. описание функции SegByName. ??? #Верстальщику Create New Table платформа перечень символов, допустимых в именах "$?@" 5 “_0123456789" PC "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; Java "$_@?!" 6 5 Служебные символы ассемблера 6 Символы, определенные только для специальных режимов Java-ассемблера 68 "0123456789<>" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" 7 "абвгдежзийклмнопрстуфхцчшщъыьэюя"; "$_0123456789" TMS320C6 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "_0123456789." PowerPC "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz” Таблица 4 Пример использования: SegCreate(0x1000,0x2000,0x100,0,0,0); Message(">%s\n",SegName(0x1000)); a) создаем сегмент и тут же определяем его имя >seg000 b) имя сегмента – “seg000” SegRename(0x1000,"666"); Message(">%s\n",SegName(0x1000)); c) вызываем функцию SegRename для переименования сегмента в “666” и тут же получаем имя сегмента при помощи SegName >_666 d) результат – новое имя сегмента “_666”, - функция автоматически добавила спереди знак прочерка, поскольку имя начиналась с цифры SegRename(0x1000,”Русский квас”); Message(">%s\n",SegName(0x1000)); e) вызываем функции SegRename для переименования сегмента в «Русский квас» и тут же получаем имя сегмента при помощи SegName >____________ f) результат – все запрещенные символы были заменены знаками прочерка ??? #верстальщику – change table аргумент пояснения ea линейный адрес, принадлежащий сегменту name новое имя сегмента =return пояснения ==1 успешное завершение операции return ==0 ошибка Родственные функции: SegName, SegByName Интерактивный аналог: “View\Segments”, 7 Национальные (российские символы) 69 success SegAddrng(long ea,long use32) Функция изменяет разрядность сегмента, определяя каким образом будет дизассемблироваться машинные инструкции. На платформе Intel 386+ префикс 0x66 перед инструкцией в 16-разрядном сегменте указывает на использование 32-битных операндов и, соответственно, в 32-разрядном сегменте наоборот. Изменение адресации так же затрагивает интерпретацию префикса предопределения адреса - 0x67, видов адресации и т.д. Неверный выбор разрядности сегмента приводит к некорректному дизассемблированию – появлению бессмысленного «мусора», бессвязных инструкций. IDA определяет разрядность сегмента на основе информации, содержащейся в заголовках файлов. При загрузке бинарных файлов, равно как и MS-DOS exe файлов разрядность созданных сегментов по умолчанию равна нулю. Если IDA неправильно определила разрядность одного или нескольких сегментов, ее следует исправить вручную. Внимание: изменение разрядности сегмента уничтожает все результаты дизассемблирования – метки, функции, переменные и т.д. Аргумент ea задает любой линейный адрес, принадлежащий сегменту. Если передать адрес не принадлежащий никакому сегменту, функция возвратит ошибку. Нулевое значение аргумента use32 указывает на 16-битовую разрядность сегмента и приводит к помещению в ассемблерный листинг атрибута размера сегмента use16; в противном случае сегмент считается 32-разрядным, а атрибут размера сегмента – use32. Независимо от разрядности сегмента, IDA всегда выражает смещения 32-битовыми значениями и допустимо создания 16-разрядного сегмента размером более 64 килобайт, однако, следует помнить, что в дальнейшем такой «большой» сегмент не сможет быть ассемблирован. Функция не учитывает выбранный тип процессора и допускает использование 32- разрядного режима даже с 8086 (!) процессором. Пример использования: SegCreate(0x1000,0x2000,0x100,0,0,0); a) Создание 16-разрядного сегмента seg000:0000 seg000 segment at 100h private '' use16 b) Сегмент успешно создан. Атрибут размера сегмента выделен жирным шрифтом. SegAddrng(0x1000,1); c) Вызов функции SegAddrng для изменения разрядности сегмента seg000:00000000 seg000 segment at 100h private '' use32 e) Разрядность сегмента успешно изменена ??? #верстальщику – change table аргумент пояснения ea линейный адрес, принадлежащий сегменту =use32 пояснения ==0 16-разрядный сегмент use32 ==1 32-разрядный сегмент =return пояснения ==1 успешное завершение операции return ==0 ошибка 70 Родственные функции: SegCreate Интерактивный аналог: “View\Segments”, Функция управляет выравниванием сегмента, помещая в ассемблерный текст соответствующий атрибут вырывания (byte, word, dword, para, page, mempage). Подробнее о каждом из этих атрибутов можно прочитать в документации, прилагаемой к используемому линкеру. Никакого влияния на дизассемблируемый образ файла функция не оказывает и не выравнивает сегмент в виртуальной памяти. Это подтверждает следующий эксперимент: SegCreate(0x1003,0x2000,0x100,0,0,0); a) создание нового сегмента с адресом начала равным 0x1003 seg000:0003 seg000 segment at 100h private '' use16 b) сегмент создан; смещение первого байта в сегменте равно трем Message(">1%x\n",SegAlign(0x1003,saRelWord)); c) вызов функции SegAlign для выравнивания сегмента по границе слова seg000:0003 seg000 segment word private '' use16 >1 d) результат – функция поместила в ассемблерный текст атрибут выравнивания ‘word’ (он выделена жирным шрифтом) и сигнализировала об успешном завершении. Но линейный адрес начала сегмента не был изменен (он выделен жирным шрифтом)! Атрибут выравнивания возымеет действие только на стадии компоновки объективного файла, расположив сегмент по адресу, кратным двум. Это приведет к несоответствию смещений в дизассемблируемом и целевом файле, что, скорее всего, вызовет невозможность корректного выполнения откомпилированной программы. Для выравнивания сегмента в виртуальной памяти следует воспользоваться функцией SegBounds для перемещения его начала по заданному адресу. Аргумент ea задает любой линейный адрес, принадлежащий сегменту. Если передать адрес не принадлежащий никакому сегменту, функция возвратит ошибку. Аргумент alignment представляет собой атрибут выравнивания сегмента и может принимать одно из значений, перечисленных в таблице ??? определение # пояснения saAbs 0 Безусловное выравнивание saRelByte 1 Выравнивание по границе байта (8 бит) saRelWord 2 Выравнивание по границе слова (16 бит) saRelPara 3 Выравнивание по границе параграфа (16 байт) saRelPage 4 Выравнивание по границе страницы (256-байт для чипов Intel) saRelDble 5 Выравнивание по границе двойного слова (4 байта) saRel4K 6 Выравнивание по границе страницы (4 килобайта для PharLap OMF) 8 saGroup 7 Segment group saRel32Bytes 8 Выравнивание по границе 32 байта saRel64Bytes 9 Выравнивание по границе 64 байта saRelQword 10 Выравнивание по границе 8 байт 8 Не поддерживается стандартным линкером LINK. 71 Таблица 5 ??? #верстальщику – change table аргумент пояснения ea линейный адрес, принадлежащий сегменту alignment кратность выравнивания (смотри определения в таблице выше) =return пояснения ==1 успешное завершение операции return ==0 ошибка Родственные функции: SegCreate Интерактивный аналог: “View\Segments”, Функция управляет объединением сегментов, помещая в ассемблерный листинг атрибут комбинирования (private, public, common, at, stack). Атрибут комбинирования указывает компоновщику как следует комбинировать сегменты различных модулей, имеющие одно и то же имя. Подробную информацию о каждом из атрибутом можно найти в документации, прилагаемой к используемому линкеру. Аргумент segea задает любой линейный адрес, принадлежащий сегменту. Если передать адрес не принадлежащий никакому сегменту, функция возвратит ошибку. Аргумент comb представляет собой атрибут выравнивания, и может принимать одно из значений, приведенных в Таблице ??? Пример использования: SegCreate(0x1000,0x2000,0x100,0,0,scPub); a) создаем новый сегмент с атрибутом комбинирования public seg000:0000 seg000 segment at 100h public '' b) сегмент успешно создан, атрибут комбинирования выделен жирным шрифтом SegComb(0x10000,scStack); c) вызываем функцию SegComb для изменения атрибута комбинирования сегмента seg000:0000 seg000 segment at 100h stack '' d) атрибут комбинирования изменен определение # пояснения scPriv 0 Атрибут private. Не может быть соединен ни с одним другим сегментом scPub 2 Атрибут public. Может быть объединен с другими сегментами с учетом требуемого выравнивания scPub2 4 Атрибут, определенный Microsoft, то же самое, что и scPub . scStack 5 Атрибут stack. Может быть объединен с public сегментами, но с выравниваем в один байт. scCommon 6 Атрибут common. scPub3 7 Атрибут, определенный Microsoft, то же самое, что и scPub . |