Анимация
JavaScript
|
Главная Библионтека Поскольку в стековый фрейм входит и адрес возврата, то независимо от того, имеет ли функция локальные переменные или нет, он не может быть равен нулю. Примеры использования: seg000:0000 seg000:0000 seg000:0003 seg000:0006 seg000:0009 seg000:0009 start start proc near call call call retn endp sub 0 A sub 0 10 sub 0 16 Message("0x%X \n", GetFrameSize(0x10000) seg000:0010 seg000:0010 seg000:0011 seg000:0012 seg000:0014 seg000:0015 seg000:0015 sub 0 10 sub 0 10 proc near push push mov retn endp ax bp, ; sp = -2 Message("0x%X \n", GetFrameSize(0x10010) Message("0x%X \n", GetFrameRegsSize(0x10010) Как видно, в последнем случае стековый фрейм состоял из адреса возврата и сохраненных в стеке регистров. Однако, если команды расположить по другому, то результат изменится: seg000:000A seg000:000A seg000:000B seg000:000D seg000:000E seg000:000F seg000:000F sub 0 A sub 0 A proc near push bp mov bp, sp push ax pop bp retn endp ; sp = -2 Message("0x%X \n", GetFrameSize(0x1000A) Message("0x%X \n", GetFrameRegsSize(0x1000A) Все команды, лежащие «ниже» (то есть в более старших адресах) относительно команды mov bp, sp (которая и определят стековый фрейм) в него не попадают и можно безболезненно заносить (выталкивать) команды из стека, не боясь разрушить стековый фрейм.
long MakeFrame(long ea,long lvsize,long frregs,long argsize); Создает фрейм стека функции или модифицирует уже существующий. Для этого достаточно указать любой адрес, принадлежащий функции и размеры области для локальных переменных, сохраненных регистров и аргументов. Они расположены во фрейме в следующей последовательности. Стековый фрейм Локальные переменные Сохраненные регистры Аргументы, переданные функции Адрес возврата из функции При успешном завершении функция возвращает ID структуры, обеспечивающий доступ ко всем вышеперечисленным элементам. В противном случае функция вернет ошибку BADADDR.
Модифицирование уже существующего фрейма стека может повлечь за собой удаление локальных переменных. Например: .text:00401487 setargv proc near .text:00401487 .text:00401487 var 8 .text:00401487 var 4 .text:00401487 .text:00401487 .text:00401488 .text:0040148A .text:0040148B = dword ptr -8 = dword ptr -4 push mov push push ebp, esp ecx ecx MakeFrame(0x401487,0,0,0); .text:00401487 setargv .text:00401487 .text:00401488 .text:0040148A .text:0040148B .text:0040148C proc near push ebp mov ebp, esp push ecx push ecx push ebx Аргументы же функции никогда не удаляются из стекового фрейма, даже при уменьшении размера выделенного для них региона до нуля. Однако, это нарушает целостность всего фрейма и локальных переменных, лежащих «выше» text:00401520 text:00401520 text:00401520 .text:00401520 arg 0 text:00401520 arg 4 text:00401520 arg 8 text:00401520 arg C text:00401520 arg 10 text:00401520 text:00401520 text:00401521 text:00401523 text:00401526 text:00401529 sub 0 401520 proc near dword ptr dword ptr dword ptr dword ptr dword ptr push push ecx, eax, 0Ch 10h 14h 18h ebp, esp [ebp+arg 10] [ebp+arg C] MakeFrame(0x401520,0,0,0); text:00401520 text:00401520 text:00401520 text:00401520 arg 0 text:00401520 arg 4 text:00401520 arg 8 text:00401520 arg C text:00401520 arg 10 text:00401520 text:00401520 text:00401521 text:00401523 text:00401526 text:00401529 sub 0 401520 proc near dword ptr dword ptr dword ptr dword ptr dword ptr push push ecx, eax, 0Ch 10h 14h 18h ebp, esp [ebp+arg 10] [ebp+arg C] 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 |