Неплохо для начала? Мы уже дизассемблировали часть файла и при этом нам не потребовалось знание ни одного кода операции, за исключением, быть может, 0CDh, соответствующего команде 'INT.
Вряд ли мы скажем, о чем говорит код 087h. (Впрочем, обращая внимание на его близость к операцииNOP , являющейся псевдонимом ' XCHGAX,AX ', можно догадаться, что 087h — это код операцииXCHG ). Обратим внимание на связанный с ним байт 0F2h:
Как не трудно догадаться, эта команда заносит в SI смещение пароля, содержащиеся в DX. Этот вывод мы делаем, только исходя из смыслового значения регистров, полностью игнорируя код команды. К сожалению, этого нельзя сказать о следующем байте — 0ACh. Это код операцииLODSB , и его придется просто запомнить.
0x02 — это кодADD , а следующий за ним байт — этоAH,AL (не буду больше повторять, как это было получено).
0xE2 — это код операцииLOOP , а следующий за ним байт — это знаковое относительное смещение перехода.
Чтобы превратить его в знаковое целое, необходимо дополнить его до нуля, (операцияNEG , которую большинство калькуляторов не поддерживают). Тот же самый результат мы получим, если отнимем от 0100h указанное значение (в том случае, если разговор идет о байте). В нашем примере это равно пяти. Отсчитаем пять байт влево от началаследующей команды . Если все сделать правильно, то вычисленный переход должен указывать на байт 0ACh (командаLODSB ), впрочем, последнее было ясно и без вычислений, ибо других вариантов, по-видимому, не существует.
Почему? Да просто данная процедура подсчета контрольной суммы (или точнее хеш-суммы) очень типична. Впрочем, не стоит всегда полагаться на свою интуицию и «угадывать» код, хотя это все же сильно ускоряет анализ.
С другой стороны, хакер без интуиции — это не хакер. Давайте применим нашу интуицию, чтобы «вычислить», что представляет собой код следующей команды. Вспомним, что 0B4h (10110100b) — этоMOVAH,imm8 .
0BEh очень близко к этому значению, следовательно, это операция MOV. Осталось определить регистр-приемник. Рассмотрим обе команды в двоичном виде:
Как уже говорилось выше, младшие три бита — это код регистра. Однако, его невозможно однозначно определить без утончения размера операнда. Обратим внимание на третий (считая от нуля) бит. Он равен нулю для AH и единице в нашем случае. Рискнем предположить, что это и есть бит размера операнда, хотя этого явно и не уточняет Intel, но вытекает из самой архитектуры команд и устройства декодера микропроцессора.
Обратим внимание, что это, строго говоря, частный случай, и все могло оказаться иначе. Так, например, четвертый справа бит по аналогии должен быть флагом направления или знакового расширения, но увы — таковым в данном случае не является. Четыре левые бита это код операции ' movreg,imm '. Запомнить его легко — это «13» в восьмеричном представлении.
Итак, 0BEh 03Bh 001h — этоMOVSI,013Bh . Скорее всего, 013bh — это смещение, и за этой командой последует расшифровщик очередного фрагмента кода. А может быть и нет — это действительно смелое предположение. Однако, байты 030h 024h это подтверждают. Хакеры обычно так часто сталкиваются с функцийxor , что чисто механически запоминают значение ее кода.
Не трудно будет установить, что эта последовательность дизассемблируется какXOR[SI],AH . Следующий байт 046h уже нетрудно «угадать» —INCSI . Кстати, посмотрим, что же интересного в этом коде:
Третий бит равен нулю! Выходит команда должна выглядеть какINCAH ! (Что кстати, выглядит непротиворечиво смысле дешифровщика). Однако, все же этоINCSI . Почему мы решили, что третий бит — флаг размера? Ведь Intel этого никак не гарантировала! А команда ' INCbyte ' вообще выражается через дополнительный код, что на байт длиннее.
Выходит, что как ни полезно знать архитектуру инструкций, все же таблицу кодов команд хотя бы местами надо просто выучить.