问题描述
我正在浏览 Nick Blundell 的 os-dev。在使用NASM编译引导扇区汇编代码后,他在那里查看了bin文件中的十六进制数据。有没有办法手动解释所有512字节,只需查看代码。比如说,下面是代码
mov ah,0x0E
;First attempt
mov al,the_secret
int 10h
;Second attempt
mov al,[the_secret]
int 10h
;Third attempt
mov bx,the_secret
add bx,0x7c00
mov al,[bx]
int 10h
;Fourth attempt
mov al,[0x7c1e]
int 0x10
jmp $
the_secret: db "X"
times 510 - ($ - $$) db 0
dw 0xaa55
以上代码编译后生成一个512字节的bin文件。是否可以仅通过查看代码来确定所有 512 个字节?我认为这应该是可能的,否则他不会知道 the_secret 存在于 0x7c1e。 如果可能,请指导我阅读解释这一部分的相关文章。谢谢
解决方法
您是否尝试过使用 ndisasm foo.bin
?您会发现 mov bx,0x1d
包含机密地址,以及另一个 mov al,[0x7c1e]
。然后,您将查看该地址(0x7c00 加载地址)处的反汇编,并查看字节。而且,它是无限循环跳转后的第一个字节,这也使它在一个很明显的地方。
$ nasm foo.asm
$ ndisasm foo
00000000 B40E mov ah,0xe
00000002 B01D mov al,0x1d ; use the address as an ASCII code...
00000004 CD10 int 0x10
00000006 A01D00 mov al,[0x1d]
00000009 CD10 int 0x10
0000000B BB1D00 mov bx,0x1d
0000000E 81C3007C add bx,0x7c00
00000012 8A07 mov al,[bx]
00000014 CD10 int 0x10
00000016 A01E7C mov al,[0x7c1e]
00000019 CD10 int 0x10
0000001B EBFE jmp short 0x1b
0000001D 58 pop ax ;;; This 0x58 is actually the ASCII code
0000001E 0000 add [bx+si],al
00000020 0000 add [bx+si],al
...
000001FE 55 push bp
000001FF AA stosb
看起来这个引导加载程序在启动时假定 DS = 0,但实际上并不打算将 DS 本身设置为匹配隐式默认值 org 0
。较早的 mov al,[0x1d]
将适用于 DS=0x07C0 的另一个可能的情况。 (引导加载程序通常以 CS:IP = 07C0:0000
或 0000:7C00
开头,但我不确定 DS 是否通常设置为任何相关内容。最好假设没有。)
此外,从您发布的来源来看,秘密位于二进制文件的 0x1d
偏移处,而不是 0x1e
。所以 mov al,[0x7c1e]
是错误的。 mov al,[0x7c00 + the_secret]
应该是有意义的,并会进行调整以适应标签的最终位置。