Анимация
JavaScript


Главная  Библионтека 

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

Кроме того, если в качестве нового конца указать адрес, уже принадлежащий какой-нибудь функции (разумеется, кроме текущей), то вызов провалиться.

seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000

2305 2305 2306 2309 230B 230B 230B 230D 230D 230D 230D 230D 230D 2310 2313 2316 2319 231B 231C 231D 231E 2321 2321 2321 2324 2324

sub 0 2305

sub 0 2305

sub 0 230D

proc

near

call

0 1CA

endp

S U

B R O

U T I

proc

near

2C51h

call

0 DD

2C4Dh

call

0 2E2

0 2321

2A2Dh

loc 0 2321: sub 0 230D

call

retn endp

sub 0 DD

Message("0x%X \n", SetFunctiinEnd(0x12305,0x12310)

Если функция возвращает отличное от нуля число, то это признак не успешности завершения операции. Следовательно, адрес конца не был изменен. (Повторный дамп для экономии не приводится)

Напротив, если за концом функции расположены данные (можно даже массив), то новый адрес конца будет успешно установлен.

sub 0 292F

seg000:292F seg000:292F seg000:2930 seg000:2932 seg000:2933

seg000:2933 sub 0 292F seg000:2933

seg000:2933 ; ----------

seg000:2 934*word 0 2 934 seg000:2934* seg000:2 936*byte 0 2 936

proc near

inc bx

loop loc 0 292F

retn

endp

dw 0 db 0



SetFuctionEnd(0x12930,0x12934);

seg000:292F sub 0 292F proc near

seg000:292F inc bx

seg000:2930 loop loc 0 292F

seg000:2932 nop

seg000:2933 retn seg000:2933

seg000:2933 ; ---------------------------------

seg000:2934*word 0 2934 dw 0 seg000:2934*

seg000:2934 sub 0 292F endp

seg000:2936*byte 0 2936 db 0

Можно даже указать на середину массива или ячейки. Функция завершиться успешно, адрес будет изменен, но он перестанет отображаться на экране, поскольку IDA забыла его округлить или проверить на корректность!

Это подтверждает следующий пример, проделанный над куском кода, приведенном

выше.

Message("0x%X \n", SetFuctionEnd(0x12930,0x12935)

seg000:292F sub 0 292F proc near

seg000:292F inc bx

seg000:2930 loop loc 0 292F

seg000:2932 nop

seg000:2933 retn

seg000:2933

seg000:2933 ; ----------------------------------

seg000:2934*word 0 2934 dw 0

seg000:2934*

seg000:2936*byte 0 2936 db 0

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

Message("0x%X \n", SetFuctionEnd(0x12936,0x12933)

Ага, вызов SetFunctionEnd возвратил ошибку, следовательно, адрес 0x12936 действительно не принадлежит функции. Попробуем теперь уменьшить его на единицу:

Message("0x%X \n", SetFuctionEnd(0x12935,0x12933)



); 0

seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000 seg000

sub 0 292F

292F 292F 2930 2932 2933 2933

2933 ; ----------

2934*word 0 2934 2934*sub 0 292F 2936*byte 0 2936

proc near inc bx

loop loc 0 292F

nop retn

dw 0

endp

db 0

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

Это не нарушает работоспособности дизассемблера, но сбивает с толку пользователя и вызывает в нем мнимое подозрение, что в базе IDA серьезные сбои или ошибки, и что лучше ее удалить и начать проект заново, чем работать с ошибками, которые еще не известно чем могут обернуться в будущем.

На самом деле никаких поводов для беспокойства нет. Необходимо поправить адрес конца функции и можно продолжить работать дальше.

Операнд

Пояснения

Любой линейный адрес, принадлежащий функции

Новый линейный адрес конца функции.

Return

Завершение

Пояснения

Вызов завершился не успешно. Функция не была создана

Вызов завершился Успешно

long NextFunction(long ea);

Вызов возвращает линейный адрес начала функции следующий за ea. Что бы получить адрес первой функции необходимо вызвать NextFunction(0).

Если больше ни одной функции возвратить невозможно, то функция возвращает ошибку BADADDR.

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

seg000:0000 sub 0 0 seg000:0000 seg000:0001

seg000:0027 seg000:0028 seg000:0029 seg000:0029 sub 0 0

proc

near

push

push

retn

endp



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