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

ОГЛАВЛЕНИЕ

 

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

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

	pop	cx			;03e56 
ret ;03e57
;-----------------------------------------------------
add BYTE PTR [bx+si],al ;03e58
add BYTE PTR [bx+si],al ;03e5a
m03e5c: mov BYTE PTR ds:d05830,01 ;03e5c

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

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

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

	pop	cx			;03e56 
ret ;03e57
;-----------------------------------------------------
d03e58 dw 0 ;03e58
d03e5a db 0 ;03e5a
d03e5b db 0
m03e5c: mov BYTE PTR ds:d05830,01 ;03e5c

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

 	mov	si,WORD PTR ds:d03e58	;03dd0
mov bl,BYTE PTR ds:d03e5a ;03dd4,

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

b03f53:	cmp	al,05			;03f53 
jnz b03f6b ;03f55 ;Jump not equal(ZF=0)
.....................................................
ret ;03f69
;-----------------------------------------------------
add BYTE PTR [si],bh ;03f6a
push es ;03f6c
jnz b03f79 ;03f6d ;Jump not equal(ZF=0)

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

b03f53:	cmp	al,05			;03f53 
jnz b03f6b ;03f55 ;Jump not equal(ZF=0)
......................................................
ret ;03f69
;-----------------------------------------------------
d03f6a db 0 ;03f6a
b03f6b: cmp al,06h ;03f6b
jnz b03f79 ;03f6d ;Jump not equal(ZF=0)

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