0

次のようなコードからコンパイルされた古い.com実行可能ファイルを逆アセンブルする場合:

.model tiny             ; com program
.code                   ; code segment
org 100h                ; code starts at offset 100h    

main proc near
   mov ah,09h           ; function to display a string  
   mov dx,offset message    ; offset ofMessage string terminating with $
   int 21h              ; dos interrupt

   mov ah,4ch           ; function to terminate
   mov al,00
   int 21h              ; Dos Interrupt 
endp 
message db "Hello World $"      ; Message to be displayed terminating with a $
end main

16進数では、次のようになります。

B4 09 BA 0D 01 CD 21 B4 4C B0 00 CD 21 48 65 6C 6C 6F 20 57 6F 72 6C 64 20 24

逆アセンブラは、コードがどこで終わり、文字列「Helloworld」が始まるかをどのように知るのでしょうか。

4

1 に答える 1

1

逆アセンブラは、ファイル内でそのような区別がないため、コードがどこで終了し、データが.comファイル内でどこから始まるかを認識しません。.comファイルでは、.comすべてが同じセグメントにロードされ、DOSはリアルモードで実行され、メモリ保護はまったくありません。たとえば、通常のテキストのように見える難読化されたコードを記述して、コードにジャンプできます。たとえば(DOSがクラッシュする可能性があり、テストされていません):

_start: jmp hello

hello:
db "Hello World!"

ret

したがってdb "Hello World $"、完全に有効な16ビットコードです(Linuxのx86およびx86-64用のudis86逆アセンブラライブラリにudcli付属している逆アセンブラで確認します。

$ echo `echo 'Hello World $' | tr -d "\n" | od -An -t xC` | udcli -x -16

0000000000000000 48               dec ax            ; H
0000000000000001 656c             insb              ; el
0000000000000003 6c               insb              ; l
0000000000000004 6f               outsw             ; o
0000000000000005 20576f           and [bx+0x6f], dl ; <space>Wo
0000000000000008 726c             jb 0x76           ; rl
000000000000000a 642024           and [fs:si], ah   ; d<space>$

ただし、db 0x64 0x20 0x24有効な32ビットまたは64ビットのコードではありません。

これは32ビットの逆アセンブルですdb "Hello World! $"

$ echo `echo 'Hello World $' | tr -d "\n" | od -An -t xC` | udcli -x -32

0000000000000000 48               dec eax            ; H
0000000000000001 656c             insb               ; el
0000000000000003 6c               insb               ; l
0000000000000004 6f               outsd              ; o
0000000000000005 20576f           and [edi+0x6f], dl ; <space>Wo
0000000000000008 726c             jb 0x76            ; rl
000000000000000a 642024           invalid            ; d<space>$

逆アセンブラが実行できることは、ヒューリスティックとコードトレースを使用して、逆アセンブルの一部をコードとして出力し、他の一部をデータとして出力するかどうかを決定することです。しかし、逆アセンブラは、コードがどこで終わり、どこでデータが始まるかを知る.comことはできません。ファイルでは、そのような区別はプログラマーの頭にのみ存在し、場合によってはソースコードとアセンブラーの制限に存在し、バイナリ.comファイル形式自体には存在しないためです。

于 2012-10-02T22:50:46.487 に答える