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

дизассемблер должен понимать его формат), реже предполагается по умолчанию - так для com файлов он всегда расположен по адресу 0x100, но для бинарных файлов (дампов RAM, например), точка входа не может и вовсе не иметь смысла. Поскольку управление может быть передано на множество мест, в зависимости от обстоятельств.

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

В общих чертах так оно и есть - набор функций, взаимодействующий с точками входа, очень ограничен и, откровенно говоря, не полон. Так, например, не предусмотрено функции удаления точек входа, в том числе и созданных пользователем.

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

Для этого предусмотрена функция long GetEntryPoint(long ordinal), чем потребности рядового пользователя с лихвой удовлетворяются.

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

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

Еще IDA предваряет их имена директивой public, делая их общедоступными. Но то же можно сделать вручную.

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

МЕТОДЫ

Функция

Описание

Long GetEntryPointQty(void);

Возвращает число точке входа

success AddEntryPoint(long ordinal,long ea,char name,long makecode)

Добавляет новую точку входа

long GetEntryOrdinal(long index);

Возвращает ординал точки входа по ее индексу

long GetEntryPoint(long ordinal)

Возвращает адрес точки входа по ординулу

success RenameEntryPoint(long ordinal,char name);

Переименовывает точку входа

long GetEntryPointQty(void);



Функция возвращает число точек входа (Entry Points). Обычно IDA создает только одну точку входа, адрес которой извлекается из заголовков исполняемого файла. Но иногда возникает потребность в создании более, чем в одной точке входа.

Например, PE файл, имеющий DOS-заглушку. Если мы захотим дизассемблировать последнюю, то необходимо добавить новую точку входа «вручную», поскольку IDA предпочитает в большинтстве случаев обходится всего лишь одним Entry Point



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

Message("0x%X \n", GetEntryPointQty());

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

Return

Число точек входа

success AddEntryPoint(long ordinal,long ea,char name,long makecode);

Добавляет новую точку входа. Будьте внимательны при вызове этой функции, ведь удалить созданную точку входа уже не удастся!

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

При генерации точки входа IDA вставляет директиву ассемблера PUBLIC.

seg000:0000 seg000:0000 start seg000:0000 seg000:0001

public start proc near push ax mov cx, 1



seg000:0004

seg000:0006

seg000:0008 seg000:0009 seg000:000B seg000:000B seg000:000B seg000:000B

start

push

retn

endp ;

sp =

ends

seg000

AddEnrtyPoint(1,0x10006,"NewEntryPoint",0);

start

seg000:0000 seg000:0000 seg000:0000 seg000:0001 seg000:0004 seg000:0006 seg000:0006 seg000:0006 seg000:0006 seg000:0008 seg000:0009 seg000:000B seg000:000B start seg000:000B seg000:000B seg000

public start proc near push ax mov cx, 1

shl cx, 1

public NewEntryPoint

NewEntryPoint:

push

retn endp

ends

; sp = -4

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

AddEnrtyPoint(2,0x10009,"NewEntryPoint",0);

seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000: seg000:

0000 0000 0000 0001 0004 0006 0006 0006 0006 0008 0009 0009 0009 0009 000B 000B 000B 000B

start

public start proc near push ax mov cx, 1

shl cx, 1

public NewEntryPoint

NewEntryPoint:

push

NewEntryPoint 0:

public NewEntryPoint 0

start

seg000

retn endp

ends

sp, cx

; sp = -4

Если попытаться создать точку входа с уже существующим ординалом, то она не будет создана, а функция вернет ошибку.

Message("0x%X \n",

AddEnrtyPoint(2,0x10009,"MyEntryPoint",0)



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