Анимация
JavaScript
|
Главная Библионтека 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 изменяется только после завершения команды - то есть с адреса начала следующей.
В точке выхода из функции значение SP (ESP) так же должно равняться нулю. В противном случае стек был бы несбалансированным, и команда возврата вытолкнула из стека не адрес возврата, а что-то совсем иное. В таком случае вероятнее всего, что IDA не смогла отследить все инструкции, модифицирующие значения стекового регистра (или сделала это неправильно). Рекомендуется обнаружить это место и скорректировать его вызовом SetSpDiff.
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)
Как и в случае с 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 |