minix_R3.3.0-588a35b.iso引导文件反汇编

本文详细解析了BIF引导文件的工作原理,包括如何从CD读取数据到内存、查找Boot文件的过程以及相关指令的解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

;Note: 在ISO中,扇区大小至少为2048字节,大部分是2048字节(见ECMA-119),BIF引导文件位于14号扇区
00000000  E9FD03            jmp 0x400           
00000003  skipping 0x1FA bytes ;filled with 0
000001FD  0055AA            add [di-0x56],dl
000001FF  skipping 0x201 bytes ;filled with 0
00000400  EB7E              jmp short 0x480
00000402  6690D1B6867878            
00000409  skipping 0x10 bytes
00000419  C201
0000041B  skipping 0x65 bytes

;将本文件全部内容复制到0x1000处
;eax:0x0000aa55 ecs:00090000 edx:000000e0 ebx:00000000 esp:0000ffd6 ebp:00000000 esi:000e0000 rdi:0000f782
00000480  31C0              xor ax,ax
00000482  8ED8              mov ds,ax
00000484  8EC0              mov es,ax
00000486  8ED0              mov ss,ax
00000488  BC007C            mov sp,0x7c00
0000048B  89E6              mov si,sp
0000048D  BF0010            mov di,0x1000
00000490  B90004            mov cx,0x400 
00000493  F3A5              rep movsw   
;eax:0x00000000 ecs:00090000 edx:000000e0 ebx:00000000 esp:00007c00 ebp:00000000 esi:000e8400 rdi:00001800          

;从内存地址0x149a继续往下执行
00000495  EA9A140000        jmp 0x0:0x149a          

;暂不知道该指令有何作用
;[0x15b0]=0x0d000006
0000049A  8816B115          mov [0x15b1],dl     
;[0x15b0]=0x0d00e006

;显示字符串
;[0x15b3-0x15da]0x0d0aNetBSD/x86 cd9660 Primary Bootstrap0x0d0a00
0000049E  BEB315            mov si,0x15b3           
;eax:0x00000000 ecs:00090000 edx:000000e0 ebx:00000000 esp:00007c00 ebp:00000000 esi:000e15b3 rdi:00001800  
000004A1  E8EC00            call 0x590              

;从扇区号16读取1个扇区到内存0x1800处
000004A4  66B810000000      mov eax,0x10            ;扇区号16
000004AA  B601              mov dh,0x1              ;1个扇区
000004AC  66BB00180000      mov ebx,0x00001800      ;内存地址0x1800
000004B2  E88E00            call 0x543              

000004B5  803F01            cmp byte [bx],0x1       
000004B8  740F              jz 0x4c9                ;找到了Primary Volume Descriptor

;未找到Primary Volume Descriptor
000004BA  6640              inc eax                 ;寻找下一个扇区
000004BC  803FFF            cmp byte [bx],0xff      ;如果是Volume Descriptor Set Terminator
000004BF  75E9              jnz 0x4aa               ;如果不是Volume Descriptor Set Terminator,表明Descriptor未结束,继续读扇区

;如果是Volume Descriptor Set Terminator 说明Primary Volume Descriptor不存在
000004C1  BE0B16            mov si,0x160b       
000004C4  E8C900            call 0x590              ;显示"Press any key to boot from CD"
000004C7  EB77              jmp short 0x540         ;暂停CPU运行

;找到了Primary Volume Descriptor,把根目录内容复制到地址0x2000处
000004C9  BB9C18            mov bx,0x189c           ;根目录记录(Directory Record)
000004CC  668B4702          mov eax,[bx+0x2]        ;根目录所在扇区
000004D0  668B570A          mov edx,[bx+0xa]        ;根目录数据大小(占4字节)
000004D4  66C1EA0B          shr edx,0xb             ;除以2048,得到所占扇区数 0x12345678
000004D8  88D6              mov dh,dl               ;数据大小不能超过522240(0xFF*0x800)个字节
000004DA  66BB00200000      mov ebx,0x00002000      
000004E0  E86000            call 0x543              ;读扇区

;开始在根目录寻找BOOT文件
000004E3  803F00            cmp byte [bx],0x0       
000004E6  741D              jz 0x505                ;读到了目录末尾
000004E8  89DE              mov si,bx               
000004EA  83C621            add si,0x21             ;指向文件名或目录名所在地址
000004ED  8A4F20            mov cl,[bx+0x20]        ;文件名或目录名长度
000004F0  BF4116            mov di,0x1641           ;[0x1641-0x1648]=BOOT;10x00
000004F3  8A04              mov al,[si]             
000004F5  3805              cmp [di],al             
000004F7  7508              jnz 0x501               
000004F9  46                inc si
000004FA  47                inc di
000004FB  FEC9              dec cl
000004FD  75F4              jnz 0x4f3               
000004FF  EB0C              jmp short 0x50d     

00000501  031F              add bx,[bx]             ;如果文件名或目录名不是BOOT;1 继续读下一个目录
00000503  EBDE              jmp short 0x4e3

;根目录不存在boot文件
00000505  BE3016            mov si,0x1630
00000508  E88500            call 0x590                  ;显示"Can't find /boot"
0000050B  EB33              jmp short 0x540             ;处理器进入暂停状态

;根目录存在boot文件
0000050D  668B4702          mov eax,[bx+0x2]            ;boot文件所在扇区
00000511  668B570A          mov edx,[bx+0xa]            ;boot文件大小
00000515  6681C2FF070000    add edx,0x7ff               ;当文件大小不是所占扇区的整数倍时,加上0x7ff可以把文件全部读完
0000051C  66C1EA0B          shr edx,byte 0xb            ;除以2048,得到文件所占扇区数
00000520  88D6              mov dh,dl                   ;dh指定了读取的扇区数,把dl赋值给dh
00000522  66BB00000100      mov ebx,0x10000             ;加载到内存0x10000处
00000528  E81800            call 0x543          

0000052B  66BE08140000      mov esi,0x1408              ;
00000531  6631D2            xor edx,edx
00000534  8A16B115          mov dl,[0x15b1]
00000538  6631DB            xor ebx,ebx
0000053B  9A00000010        call 0x1000:0x0             ;从boot开始执行

;CPU暂停运行
00000540  F4                hlt                             
00000541  EBFD              jmp short 0x540

;-----------------@method:读扇区---------------------
;@param eax 需要读取扇区号(低32位)
;       dh  读取扇区数(低8位)      
;       ebx 目的内存地址(32位)     要求16字节对齐
;@return null
;@description   初始值:[0x15a0-0x15af]=0x10000000000000000000000000000000 用来保存int 13h ah=0x42功能所需的16字节数据
;               [0x15a0-0x15a1]=结构体长度(2字节),0x10表示数据长度是16字节,该值是固定的
;               [0x15a2-0x15a3]=读取的扇区数(2字节)
;               [0x15a4-0x15a5]=偏移地址(2字节)
;               [0x15a6-0x15a7]=段地址(2字节)
;               [0x15a8-0x15ab]=读取的扇区号的低32位(4字节)
;               [0x15ac-0x15af]=读取的扇区号的高32位(4字节)

00000543  6660              pusha                           
00000545  66A3A815          mov [0x15a8],eax                
00000549  66C1EB04          shr ebx,0x04                    ;得到段地址
0000054D  891EA615          mov [0x15a6],bx         

00000551  8836A215          mov [0x15a2],dh     

;若读取超过32个扇区,先读32个       
00000555  80FE20            cmp dh,0x20
00000558  7E05              jng 0x55f       
0000055A  C606A21520        mov byte [0x15a2],0x20  

;有何用?
0000055F  8A16B115          mov dl,[0x15b1]                 ;[0x15b0-0x15b1]=0x06,0xe0, dl=0xe0

;将ds:si指向结构体入口地址
00000563  BEA015            mov si,0x15a0                   
00000566  B442              mov ah,0x42

;dx=01e0 dx在int 0x13前后没有变化,暂不清楚为何压栈
00000568  52                push dx                         
00000569  CD13              int 0x13                        
0000056B  5A                pop dx                          

0000056C  7215              jc 0x583        ;读取失败

;读取成功               
0000056E  8106A6150010      add word [0x15a6],0x1000        ;跳过0x10000个地址(0x20*0x800=0x10000)
00000574  668306A81520      add dword [0x15a8],byte+0x20    ;跳过20个扇区
0000057A  2A36A215          sub dh,[0x15a2]                 ;是否读完扇区,如果扇区未读完则继续读,如果读完该程序结束   
0000057E  75D1              jnz 0x551                       
00000580  6661              popa                            
00000582  C3                ret     

;读取失败                                                                       
00000583  80FC80            cmp ah,0x80
00000586  74DE              jz 0x566        ;超时错误再读 其他错误显示字符串,然后让CPU暂停运行
00000588  BEFD15            mov si,0x15fd   ;[0x15fd-0x160a]=Can't read CD0x00
0000058B  E80200            call 0x590      
0000058E  EBB0              jmp short 0x540

;-----------------@method:显示字符串--------------------
;@param ds:si 指向字符串所在地址
;@return null
00000590  60                pusha                           
00000591  AC                lodsb
00000592  B40E              mov ah,0xe
00000594  BB0100            mov bx,0x1                      ;黑色背景,蓝色前景,不闪烁
00000597  CD10              int 0x10
00000599  AC                lodsb                           
0000059A  84C0              test al,al                      
0000059C  75F4              jnz 0x592                       ;字符串未结束,继续显示下一个字符
0000059E  61                popa
0000059F  C3                ret                             

000005A0  10              
000005A1  skipping 0xF bytes    ;filled with 0
000005B0  06                
000005B1  0000              
000005B3  0D0A                
000005B5  skipping 0x93 bytes   ;NetBSD/x86 cd9660 Primary Bootstrap0x0D0A000D0A000D0APress any key to boot from CD0x00.0x00Can't read CD0x00Can't find Primary Volume Descriptor0x00Can't find /boot0x00

00000648  skipping 0x1B6 bytes  ;filled with 0
000007FE  0000              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值