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

在十六进制它看起来像这样:

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

反汇编程序如何知道代码在哪里结束以及字符串“Hello world”从哪里开始?

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 回答