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

Long Rfirst (long From);

Функция возвращает линейный адрес приемника первой перекрестной ссылки указанного источника.

Подробнее о перекрестных ссылках было рассказано в описании функция AddCodeXref и DelCodeXref.

Хотя это не очевидно, источник может иметь несколько перекрестных ссылок. Например, когда используется инструкция, наподобие JMP BX.

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

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

Если указан неверный источник, (то есть линейный адрес, не содержащий перекрестных ссылок) или источник перекрестной ссылки данных, то функция возвратит ошибку BADADDR

Примеры использования:

seg000:28C6 pop di ;  источник

seg000:28C7 pop si ;  приемник

Message(“0x%X \n”,

Rfirst(0x128C6)

);

0x28C7

seg000:28CB retn

seg000:28CB sub_0_2847 endp

Message(“0x%X \n”,

Rfirst(0x128CB)

);

0xFFFFFFFF

seg000:2870 jmp loc_0_2892 ;  источник

seg000:2870 ; ---------------------------------------

seg000:2872 db 90h ; Р

seg000:2873 db 90h ; Р

seg000:2892 loc_0_2892: ; CODE XREF: seg000:2870j

seg000:2892 ;  приемник

seg000:2892 cmp byte ptr [si], 22h ; '"'

Message(“0x%X \n”,

Rfirst(0x12870)

);

0x12892

Операнд

Пояснения

From

Линейный адрес источника перекрестной ссылки

Return

Пояснения

Линеный адрес приемника первой перекрестной ссылки

Long Rnext (long From,long current);

Эта функция возвращает линейный адрес приемника очередной перекрестной ссылки в списке. При этом тип перекрестных ссылок, указывающих на следующую инструкцию (ordinary flows) игнорируется и никогда не может быть возращен.

Для понимания того, как работает данная функция, рекомендуется прочесть описания функций AddCodeXref, DelCodeXref, Rfirst.

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

Напоминаем, что функция игнорирует указатель на следующую инструкцию. Если же она завершилась успешно, то возвратит линейный адрес приемника перекрестной ссылки, следующей на current.

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

Поясним это на примере:

seg000:0000 push ax ; CODE XREF: seg000:2864p

seg000:0000 ;  приемник

seg000:2864 call bx ;  источник

seg000:2869 loc_0_286 ; CODE XREF: seg000:2864p

seg000:2869 inc si ;  приемник

seg000:2892 loc_0_2892: ; CODE XREF: seg000:2864p

seg000:2892 ;  приемник

seg000:2892 cmp byte ptr [si], 22h ; '"'

Пусть при изучении программы было определено, что BX может принимать следующие значения – 0x0, 0x2869, 0x2892. В этом случае по линейному адресу seg000:2864 будет расположено три перекрестные ссылки на соответствующие приемники.

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

IDA сформирует по линейному адресу 0x12864 следующий список приемников: {0x10000, 0x12869, 0x12892} Вот эти адреса и будут возвращаться при прохождении списка функцией Rnext.

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

Вообще не понятно, зачем понадобилось вводить Rfirst. Ведь первую перекрестную ссылку можно найти с помощью Rnext – и это будет следующая ссылка за нулем. Очевидно, что Rnext(0x12864,0) вернет 0x10000 – первую перекрестную ссылку в списке. Следовательно, Rnext(X, 0) идентична Rfirst.

На самом деле тут нас поджидает небольшой сюрприз. Функция Rnext, проходя список, не обнаруживает в нем ссылок на следующую команду. Это не является ошибкой, а документированной особенностью IDA.

Например:

auto a;

a=0;

for (;;)

{

a=Rnext(ScreenEA(),a);

if (a==-1) break;

Message("0x%X \n",a);

}

Операнд

Пояснения

Form

Линейный адрес источника списка перекрестных ссылок

Current

Текущий адрес

Return

Пояснения

Следующий адрес в списке

-1 если список исчерпан или отсутствует источник

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