Анимация
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

long GetSpd(long ea);

Возвращает значение регистра SP (ESP) в произвольной точке функции относительно его оригинального значения.

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

Для специфичных случаев предусмотрена ручная коррекция (смотри описание функции SetSpDiff) но в большинстве случаев IDA и сама справляется с этой задачей.

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

text text text text text text text text text text text text text text text text text text text

004010FF 004010FF 004010FF 004010FF 004010FF 004010FF 00401106 00401108

0040110D 0040110D 0040110D

00401111 00401116 0040111B 00401121 00401122

00401123 00401123 00401123

amsg exit

arg 0

loc 0 40110D:

proc near

= dword ptr 4

amsg exit

call

push

call

push

call

retn endp

dword 0 4 08758, 2

short loc 0 40110D

FF MSGBANNER

[esp+arg 0] NMSG WRITE

0FFh

off 0 408050

ecx ecx

Message("%d \n", GetSpd(0x4010FF)

Message("%d \n", GetSpd(0x401111)

Message("%d \n", GetSpd(0x401116)

Message("%d \n", GetSpd(0x401122)

Message("%d \n",



GetSpd(0x401123)

В точке входа в функцию значение SP (ESP) всегда равно нулю. Затем, в нашем примере, оно изменяется командой push, заносящей в стек двойное слово.

Обратите внимание, что значение ESP изменяется только после завершения команды - то есть с адреса начала следующей.

Относительное значение ESP

Адрес

Инструкция

.text:0040110D

push [esp+arg 0]

.text:00401111

call NMSG WRITE

В точке выхода из функции значение SP (ESP) так же должно равняться нулю. В противном случае стек был бы несбалансированным, и команда возврата вытолкнула из стека не адрес возврата, а что-то совсем иное.

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

Операнд

Пояснения

Линейный адрес в теле функции

Return

Относительное значение стекового регистра SP (ESP)

long GetSpDiff(long ea);

Возвращает относительное изменение стекового регистра SP (ESP) командой, расположенной по линейному адресу ea. Например:

.text:004010FF amsg exit

.text:004010FF .text:004010FF .text:004010FF arg 0 .text:004010FF .text:004010FF .text:00401106 .text:00401108 .text:0040110D .text:0040110D loc 0 40110D .text:0040110D .text:00401111 .text:00401116 .text:0040111B .text:00401121 .text:00401122 .text:00401123 .text:00401123 amsg exit

Message("%d \n",

proc near

= dword ptr 4

call

push

call

push

call

retn endp

dword 0 408758, 2 short loc 0 40110D FF MSGBANNER

[esp+arg 0]

NMSG WRITE

0FFh

off 0 408050

ecx ecx



GetSpd(0x4010FF)

Message("%d \n", GetSpd(0x401111)

Message("%d \n", GetSpd(0x401116)

Message("%d \n", GetSpd(0x401122)

Message("%d \n", GetSpd(0x401123)

Относительное значение ESP

Адрес

Инструкция

.text:0040110D

push [esp+arg 0]

.text:00401111

call NMSG WRITE

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

Операнд

Пояснения

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

Return

Относительное изменение стекового регистра SP (ESP)

success SetSpDiff(long ea,long delta);

Задает изменение стекового регистра SP (ESP) командой, лежащей по указанному линейному адресу. Дело в том, что IDA использует достаточно простой алгоритм, отслеживания SP (ESP), который не учитывает ряда особенностей некоторых экзотических команд.

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

Возьмем следующий, достаточно надуманный пример:



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