Анимация
JavaScript
|
Главная Библионтека смотря на то, что в idc.idc утверждается, что этот тип ссылок доступен Rnext (смотри описание ниже) на самом же деле, Rnext проходя список приемников перекрестных ссылок, игнорирует этот тип. Если указан неверный источник, (то есть линейный адрес, не содержащий перекрестных ссылок) или источник перекрестной ссылки данных, то функция возвратит ошибку BADADDR Примеры использования: seg000:28C6 seg000:28C7 Message("0x%X \n", Rfirst(0x128C6) pop di ; источник pop si ; приемник 0x28C7 seg000:28CB seg000:28CB Message("0x%X \n Rfirst(0x128CB) sub 0 2847 retn endp 0xFFFFFFFF seg000:2870 источник seg000:2870 ; seg000:2872 seg000:2873 seg000:2892 loc 0 2892: XREF: seg000:2870j seg000:2892 приемник seg000:2892 loc 0 2 8 92 ; db 90h ; Р db 90h ; Р ; CODE byte ptr [si], 22h ; Message("0x%X \n", Rfirst(0x12870) 0x12892 Операнд Пояснения Линейный адрес источника перекрестной ссылки From Пояснения Линеный адрес приемника первой перекрестной ссылки Return long Rnext (long From,long current); Эта функция возвращает линейный адрес приемника очередной перекрестной I II I ссылки в списке. При этом тип перекрестных ссылок, указывающих на следующую инструкцию (ordinary flows) игнорируется и никогда не может быть возращен. Для понимания того, как работает данная функция, рекомендуется прочесть описания функций AddCodeXref, DelCodeXref, Rfirst. IDA хранит список перекрестных ссылок для каждого источника, отсортированный по адресам приемника. Первыми в нем идут те ссылки, чей линейный адрес приемника наименьший, за ними следующие. Напоминаем, что функция игнорирует указатель на следующую инструкцию. Если же она завершилась успешно, то возвратит линейный адрес приемника перекрестной ссылки, следующей на current. То есть current должен быть не обязательно точно равен адресу приемника текущей перекрестной ссылки в списке. Он может быть меньше его, но, разумеется, обязательно превосходить адрес приемника предыдущей ссылки. Поясним это на примере: seg000:0000 seg000:2864p seg000:0000 push ; CODE XREF: приемник seg000:2864 call bx ; источник seg000:2869 loc 0 286 seg000:2864p seg000:2869 seg000:2892 loc 0 2892: seg000:2864p seg000:2892 seg000:2892 ; CODE XREF: inc si ; приемник ; CODE XREF: ; приемник 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 если список исчерпан или отсутствует источник long RfirstB (long To); Функция возвращает линейный адрес первого источника для указанного списка приемников. Для понимания этого, рекомендуется прочесть описания функций AddCodeXref, DelCodeXref, Rfirst, Rnext. Очевидно, что по одному и тому же линейному адресу может существовать более одного приемника перекрестных ссылок. Например:
Источник по адресу seg000:0x14D помечен не случайно. Он, разумеется, не имеет никакого отношения к операнду loc 0 143, а представляет собой перекрестную ссылку на следующую команду. Реализация этой функции повторяет особенность реализации Rfirst. Действительно, рассмотрим список источников перекрестных ссылок, который IDA сформировала по адресу seg000:0x14F - {0x1013B, 0x10146, 0x1014A, 0x1014C}. Вполне естественно ожидать, что вызов RfirstB должен был бы вернуть первый - самый наименьший из них. Однако же, вместо него возвращается источник ссылка на следующую инструкцию, то есть 0x1014A. Покажем это ниже: 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 |