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

Alma mater

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

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

С первого взгляда возможно будет даже не понятно, о чем идет речь. Если перекрестная ссылка уже создана, то какие могут быть проблемы? На самом деле все не так просто. Перекрестная ссылка может быть создана (и при том не в единственном числе), а может быть, и нет. Как узнать это наверняка? И как получить адрес, на который перекрестная ссылка ссылается?

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

Итак, любая перекрестная ссылка состоит из источника и приемника. В контекстной помощи IDA источник обозначается как ‘from’, а приемник – как ‘to’.

Источником называется операнд, ссылающийся на примем ник, но не наоборот! Разберем в свете этого приведенный выше пример:

  1. .MODEL TINY

  2. .CODE

  3. ORG 100h

  4. Start:

  5. MOV AH,9 ;

  6. LEA DX,s0 ; 

  7. INT 21h ;

  8. RET ;

  9. s0 DB "Hello, Sailor!",0Dh,0Ah,'$' ; 

  10. END Start

Так в строке 8 должна быть создан источник перекрестной ссылки, а в строке 11 – приемник.

Часто вызывает путаницу, что IDA создает комментарий к перекрестной ссылке только возле приемника. Это, разумеется, правильно, потому что источник в комментариях не нуждается – в большинстве случаев очевидно на что ссылается операнд (хотя в случае инструкций подобных CALL BX этого сказать нельзя), а вот по виду приемника источник установить невозможно.

Вот IDA и отображает его в виде комментария:

seg000:0100 public start

seg000:0100 start proc near

seg000:0100 mov ah, 9

seg000:0102 mov dx, offset aHelloSailor

seg000:0105 int 21h

seg000:0105

seg000:0107 retn

seg000:0107 start endp

seg000:0107

seg000:0107 ; ------------------------------------------------------seg000:0108 aHelloSailor db 'Hello, Sailor!',0Dh,0Ah,'$' ; DATA XREF: start+2o

seg000:0108 seg000 ends

Обратите внимание, что IDA ничем не выделила строку 0x102 – создается иллюзия, что здесь ничего нет. Но на самом деле именно с этим адресом и связана перекрестная ссылка, а точнее, ее источник.

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

Начнем в первого, как более простого для понимания.

seg000:0100 org 100h

seg000:0100 assume es:nothing, ss:nothing, ds:seg000, fs:nothing, gs:nothing

seg000:0100

seg000:0100 public start

seg000:0100 start: ; "Hello, World!\r\n$"

seg000:0100 push offset aHelloWorld

seg000:0103 call Print

seg000:0106 push offset aHelloSailor ; "Hello, Sailor!\r\n$"

seg000:0109 call Print

seg000:010C retn

seg000:010D

seg000:010D; _____________ S U B R O U T I N E _______________________________________

seg000:010D

seg000:010D

seg000:010D Print proc near ; CODE XREF: seg000:0103p

seg000:010D ; seg000:0109p

seg000:010D pop ax

seg000:010E pop dx

seg000:010F push ax

seg000:0110 mov ah, 9

seg000:0112 int 21h ; DOS - PRINT STRING

seg000:0112 ; DS:DX -> string terminated by "$"

seg000:0114 retn

seg000:0114 Print endp ; sp = 2

seg000:0114

seg000:0114 ; ------------------------------------------------------------------------

seg000:0115 aHelloWorld db 'Hello, World!',0Dh,0Ah,'$' ; DATA XREF: seg000:0100o

seg000:0125 aHelloSailor db 'Hello, Sailor!',0Dh,0Ah,'$' ; DATA XREF: seg000:0106o

seg000:0125 seg000 ends

-0001010D: sub_0_10D

В этом примере процедура Print вызывалась из двух точек кода, о чем свидетельствуют две перекрестные ссылки, проставленные IDA как комментарии. Следовательно, один приемник может иметь и более одного источника.

Что бы изучить вызывающий эту процедуру код достаточно только подвести курсор в границы адреса, указанного в перекрестной ссылке и нажать Enter и при желании возвратиться назад по <Esc>.

Так же можно переместить курсор в любое место строки 0x10D и выбрать пункт меню ~ View \ Cross references. Появится окно следующего вида:

Поскольку довольно часто встречается, что на один приемник ссылаются десятки (а то и больше!) различных источников, то IDA считает не рациональным отображать их в виде комментариев и показывает по умолчанию лишь две первые из них (перекрестные ссылки отсортированы по линейным адресам источников – от младших адресов, к старшим), то просматривать остальные приходится именно в таком окне.

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

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

seg000:0002 mov ds, ax

seg000:0004 assume ds:seg000

seg000:0004 mov ah, 6

seg000:0006 mov di, offset off_0_25

seg000:0009 jmp short Print

seg000:0009 ; ---------------------------------------------------

seg000:000C

seg000:000C Def_1: ; CODE XREF: start+1Bu

seg000:000C ; DATA XREF: seg000:0025o

seg000:000C mov dl, 31h ; '1'

seg000:000E retn

seg000:000F ; ----------------------------------------------------

seg000:000F

seg000:000F Def_2: ; CODE XREF: start+1Bu

seg000:000F ; DATA XREF: seg000:0027o

seg000:000F mov dl, 32h ; '2'

seg000:0011 retn

seg000:0012 ; -----------------------------------------------------

seg000:0012

seg000:0012 Print: ; CODE XREF: start+9j

seg000:0012 ; start+1Fj

seg000:0012 mov bx, [di]

seg000:0014 add di, 2

seg000:0017 or bx, bx

seg000:0019 jz loc_0_21

seg000:001B call bx

seg000:001D int 21h

seg000:001F jmp short Print

seg000:0021 ; ------------------------------------------------------

seg000:0021

seg000:0021 loc_0_21: ; CODE XREF: start+19j

seg000:0021 mov ah, 4Ch

seg000:0023 int 21h

seg000:0023 start endp ; AL = exit code

seg000:0023

seg000:0023 ; ----------------------------------------------------

seg000:0025 off_0_25 dw offset Def_1 ; DATA XREF: start+6o

seg000:0027 dw offset Def_2

seg000:0029 dw offset def_3

seg000:002B dw offset def_4

seg000:002D dw 0

seg000:002F ; -----------------------------------------------------

seg000:002F

seg000:002F def_3: ; CODE XREF: start+1Bu

seg000:002F ; DATA XREF: seg000:0029o

seg000:002F mov dl, '3'

seg000:0031 retn

seg000:0032 def_4:

seg000:0032

seg000:0032 mov dl, '4'

seg000:0034 retn

Подобные примеры не редкость и встречаться с ними приходится довольно таки часто. Обратим внимание на следующую строку:

seg000:001B call bx

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

К сожалению пока IDA не умеет автоматически вычислять значение регистра BX и, следовательно, не может ни создать перекрестных ссылок, ни даже дизассемблировать вызываемые этой строкой функции. Скорее всего они будут помечены как ‘unexplored’.

Поэтому эта часть работы ложится на плечи пользователя. Часто при этом дизассемблируют код, но забывают создать перекрестные ссылки. Что при этом получается? А то, что вернувшись к дизассемблируемому файлу спустя некоторое время, вы уже не будете помнить какой код вызывает эти функции и анализ придется начинать сначала.

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

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