Опыт дизассемблирования большой .com программы
Страница 3. Как отличить данные от команд?


 

2. Как отличить данные от команд?

Любой дизассемблер путает данные и команды. Особенно это относится к .COM программам, где все перемешано. Рассмотрим простой пример:

popcx;03e56 
ret;03e57
;-----------------------------------------------------
addBYTE PTR [bx+si],al;03e58
addBYTE PTR [bx+si],al;03e5a
m03e5c:movBYTE PTR ds:d05830,01;03e5c

В этом фрагменте встретились две вычурных, повисших инструкции:

addBYTE PTR [bx+si],al;03e58
addBYTE PTR [bx+si],al;03e5a

Сверху они ограничены инструкцией возврата из подпрограммы ret, а снизу - меткой m03e5c. Ясно, что эти инструкции могут быть только данными. После переделки приведенный фрагмент должен выглядеть так:

popcx;03e56 
ret;03e57
;-----------------------------------------------------
d03e58dw 0 ;03e58
d03e5a db 0 ;03e5a
d03e5b db 0
m03e5c:movBYTE PTR ds:d05830,01;03e5c

Тут возникает еще один вопрос: почему в одном случае стоит dw, а в другом - db? Ответ содержится в тексте, который выдал дизассемблер. Там можно найти такие инструкции:

 movsi,WORD PTR ds:d03e58;03dd0
movbl,BYTE PTR ds:d03e5a;03dd4,

Откуда следует, что d03e58 рассматривается как слово, а d03e5a - как байт. Рассмотрим чуть более сложный, но, тем не менее, очень характерный пример.

b03f53:cmpal,05;03f53 
jnzb03f6b ;03f55;Jump not equal(ZF=0)
.....................................................
ret;03f69
;-----------------------------------------------------
addBYTE PTR [si],bh;03f6a
pushes;03f6c
jnzb03f79 ;03f6d;Jump not equal(ZF=0)

В приведенном фрагменте текста метка b03f6b отсутствует. Между тем эта метка должна "разрубить" пополам инструкцию add BYTE PTR [si],bh , которая начинается в оригинальной программе, подвергаемой дизассемблированию, со смещения 03f6a. Выход здесь может быть только один - смещению 03f6a соответствует байт данных, а инструкция начинается со смещения 03f6b. Исправленный фрагмент должен выглядеть так:

b03f53:cmpal,05;03f53 
jnzb03f6b ;03f55;Jump not equal(ZF=0)
......................................................
ret;03f69
;-----------------------------------------------------
d03f6adb 0 ;03f6a
b03f6b:cmp al,06h;03f6b
jnzb03f79 ;03f6d;Jump not equal(ZF=0)

Путаница между данными и инструкциями возникает довольно часто. SOURSER способен выдавать целые метры бессмысленных инструкций. DisDoc 2.3 в этом отношении ведет себя лучше.

 
« Предыдущая статья   Следующая статья »