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

0000

public

start

seg000:

0000

start

proc near

seg000:

0000

push

seg000:

0001

push

seg000:

0002

push

seg000:

0003

bp, sp

seg000:

0005

word ptr [

seg000:

000A

seg000:

000B

bp, sp

seg000:

000D

cx, [bp+0]

seg000:

0010

seg000:

0011

sp, cx

seg000:

0013

push

seg000:

0014

sp, cx

seg000:

0016

retn

seg000:

0016

start

endp ;

sp = -4

Message("%d \n", GetSpDiff(0x10013)

Message("%d \n", GetSpDiff(0x10016)

Что бы узнать значение SP после завершения команды add sp, cx IDA, очевидно, должна знать чему равен регистр CX. Что бы его отследить пришлось бы включать в дизассемблер полноценный эмулятор 0x86 процессора. Пока это еще не реализовано и IDA предполагает, что значение CX равно нулю и, таким образом, уже неправильно определяет значение SP во всех нижележащих точках функции.

Исправить положение можно ручной коррекцией значения SP. Функция SetSpDiff задает изменение регистра SP после выполнения команды. Для этого необходимо передать линейный адрес конца, а не начала команды.

В нашем случае необходимо скорректировать величину изменения SP командами ADD SP, CX расположенными по адресам seg000:0011 и seg000:0014. Линейные адреса команд соответственно равны seg000:0013 и seg000:0016. Их и необходимо передать функции вместе с действительной величиной изменения SP.

SetSpDiff(0x10013,2); SetSpDiff(0x10016,2);

seg000:0000 000 seg000:0000 start seg000:0000 seg000:0001 002 seg000:0002 004

public start proc near push ax push ax push bp



seg000:0003

seg000:0005

word ptr [bp+2], 2

seg000:000A

seg000:000B

seg000:000D

[bp+0]

seg000:0010

seg000:0011

seg000:0013

push

seg000:0014

seg000:0016

retn

seg000:0016

start

endp

Операнд

Пояснения

Линейный адрес конца команды

delta

Величина изменения SP указанной командой

Return

Завершение

Пояснения

Успешно

Ошибка

success MakeLocal(long start,long end,char location,char name)

версия 3.74 и старше

С версии 3.74 IDA поддерживает локальные переменные, которые в большинстве же случаев распознает и создает автоматически. Но иногда она не способна правильно их распознать, и тогда эта миссия ложиться на плечи пользователя. Подробнее о локальных переменных можно прочитать в специальной главе «Локальные переменные» посвященной непосредственно им.

MakeLocal полный аналог («~Edit\Functions\Stack variables»). В прототипе функции MakeLocal указывается область видимости локальной переменной (start и end), однако существующие версии IDA (вплоть до IDA 4.0) не поддерживает такой возможности и область видимости локальной переменной распространяется целиком на всю функцию.

Функция принимает следующие операнды:

операнд Пояснения

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

start

Этот операнд в существующих версиях должен совпадать с началом функции, иначе MakeLocal возвратит ошибку (в последующих версиях start должен определять адрес начала видимости локальной переменной)

location

Смешение переменной в кадре стека, задаваемое в виде строкового выражения "[BP+XX]", где "xx" представлено в шестнадцатеричном исчислении.

Спецификатор x можно ставить, а можно не ставить - все равно

значение будет трактоваться как шестнадцатеричное.

Интересной недокументированной особенностью является



возможность задавать другие регистры, помимо BP, например AX, однако это не возымеет никакого значения, все равно будет трактоваться как BP

name

Это есть суть имя создаваемой переменной со всеми ограничениями, наложенными на имена и метки. Признаком хорошего тона является выбор такой нотации, что бы локальные переменные легко визуально отличались от остальных. IDA всем автоматически всем создаваемым локальным переменным присваивает имя var xx.

Return

==return

пояснения

Локальная переменная успешно создана

Ошибка

Hot Key

Menu

<Ctrl-K>

Edit\Functions\Stack variables

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

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

Пример:

MakeLocal(ScreenEA(),0,"[bp+0x4]","MyVar");

proc near = dword ptr 4 push [esp+MyVar]

.text:00401124 sub 0 401124 .text:00401124 .text:00401124 MyVar .text:00401124 .text:00401124

success SetReg (long ea,char reg,long value);

Функция устанавливает значение сегментных регистров. IDA автоматически отслеживает их значение (и изменение) и хранит его для каждой точки кода.

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

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

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

Например:

dseg:0000 start

dseg:0000 dseg:0003 dseg:0005 dseg:0005 dseg:0008

proc near

mov ax, seg dseg

mov ds, ax

assume ds:dseg

mov dx, offset aHelloSailor ;

call WriteLn



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