我的机器本地操作系统是fedora21, grub安装在第一块磁盘/dev/sda, 首先执行dd if=/dev/sda of=mbr.bin bs=512 count=1提取出我本地磁盘的mbr.bin,就是/dev/sda的前512个字节。 根据mbr的wiki,了解到从0x1BE开始的64个字节为磁盘分区信息,写了个parse简单分析分区信息,见 parse_mbr, 最后两个字节为0x55, 0xaa,告诉bios这是一个bootloader。
00000000: eb63 90d0 bc00 7c8e c08e d8be 007c bf00
00000010: 06b9 0002 fcf3 a450 681c 06cb fbb9 0400
00000020: bdbe 0780 7e00 007c 0b0f 850e 0183 c510
00000030: e2f1 cd18 8856 0055 c646 1105 c646 1000
00000040: b441 bbaa 55cd 135d 720f 81fb 55aa 7509
00000050: f7c1 0100 7403 fe46 1066 0080 0100 0000
00000060: 0000 0000 fffa 9090 f6c2 8074 05f6 c270
00000070: 7402 b280 ea79 7c00 0031 c08e d88e d0bc
00000080: 0020 fba0 647c 3cff 7402 88c2 52be 057c
00000090: b441 bbaa 55cd 135a 5272 3d81 fb55 aa75
000000a0: 3783 e101 7432 31c0 8944 0440 8844 ff89
000000b0: 4402 c704 1000 668b 1e5c 7c66 895c 0866
000000c0: 8b1e 607c 6689 5c0c c744 0600 70b4 42cd
000000d0: 1372 05bb 0070 eb76 b408 cd13 730d 5a84
000000e0: d20f 83de 00be 857d e982 0066 0fb6 c688
000000f0: 64ff 4066 8944 040f b6d1 c1e2 0288 e888
00000100: f440 8944 080f b6c2 c0e8 0266 8904 66a1
00000110: 607c 6609 c075 4e66 a15c 7c66 31d2 66f7
00000120: 3488 d131 d266 f774 043b 4408 7d37 fec1
00000130: 88c5 30c0 c1e8 0208 c188 d05a 88c6 bb00
00000140: 708e c331 dbb8 0102 cd13 721e 8cc3 601e
00000150: b900 018e db31 f6bf 0080 8ec6 fcf3 a51f
00000160: 61ff 265a 7cbe 807d eb03 be8f 7de8 3400
00000170: be94 7de8 2e00 cd18 ebfe 4752 5542 2000
00000180: 4765 6f6d 0048 6172 6420 4469 736b 0052
00000190: 6561 6400 2045 7272 6f72 0d0a 00bb 0100
000001a0: b40e cd10 ac3c 0075 f4c3 0000 0000 0000
000001b0: 0000 0000 0000 0000 845d 7b16 0000 8020
000001c0: 2100 07fe ffff 0008 0000 0080 4f12 0070
000001d0: bfb2 8386 1531 0088 4f12 0000 4006 00fe
000001e0: ffff 83fe ffff 0088 8f18 00a0 0f00 00fe
000001f0: ffff 05fe ffff 0028 9f18 0038 9921 55aa
如上是我的mbr.bin的16进制
既然已经确定后面66个字节不是bootloader的代码和数据,那么我们使用ndisasm反汇编前446个字节的数据就行。
.code
00000000 EB63 jmp short 0x65 ;跳转到0x65
.end
.unused
00000002 90 nop
00000003 D0BC007C sar byte [si+0x7c00],1
00000007 8EC0 mov es,ax
00000009 8ED8 mov ds,ax
0000000B BE007C mov si,0x7c00
0000000E BF0006 mov di,0x600
00000011 B90002 mov cx,0x200
00000014 FC cld
00000015 F3A4 rep movsb
00000017 50 push ax
00000018 681C06 push word 0x61c
0000001B CB retf
0000001C FB sti
0000001D B90400 mov cx,0x4
00000020 BDBE07 mov bp,0x7be
00000023 807E0000 cmp byte [bp+0x0],0x0
00000027 7C0B jl 0x34
00000029 0F850E01 jnz word 0x13b
0000002D 83C510 add bp,byte +0x10
00000030 E2F1 loop 0x23
00000032 CD18 int 0x18
00000034 885600 mov [bp+0x0],dl
00000037 55 push bp
00000038 C6461105 mov byte [bp+0x11],0x5
0000003C C6461000 mov byte [bp+0x10],0x0
00000040 B441 mov ah,0x41
00000042 BBAA55 mov bx,0x55aa
00000045 CD13 int 0x13
00000047 5D pop bp
00000048 720F jc 0x59
0000004A 81FB55AA cmp bx,0xaa55
0000004E 7509 jnz 0x59
00000050 F7C10100 test cx,0x1
00000054 7403 jz 0x59
00000056 FE4610 inc byte [bp+0x10]
00000059 6600800100 o32 add [bx+si+0x1],al
0000005E 0000 add [bx+si],al
00000060 0000 add [bx+si],al
00000062 0000 add [bx+si],al
.end
.data
00000064 FF db 0xff
.end
.code
00000065 FA cli ;屏蔽中断
00000066 90 nop ;滑行
00000067 90 nop
00000068 F6C280 test dl,0x80 ;比较dl是否为0x80
0000006B 7405 jz 0x72
0000006D F6C270 test dl,0x70
00000070 7402 jz 0x74
00000072 B280 mov dl,0x80
00000074 EA797C0000 jmp word 0x0:0x7c79
00000079 31C0 xor ax,ax
0000007B 8ED8 mov ds,ax
0000007D 8ED0 mov ss,ax
0000007F BC0020 mov sp,0x2000
00000082 FB sti
00000083 A0647C mov al,[0x7c64]
00000086 3CFF cmp al,0xff
00000088 7402 jz 0x8c
0000008A 88C2 mov dl,al
0000008C 52 push dx
0000008D BE057C mov si,0x7c05
00000090 B441 mov ah,0x41
00000092 BBAA55 mov bx,0x55aa
00000095 CD13 int 0x13
00000097 5A pop dx
00000098 52 push dx
00000099 723D jc 0xd8
0000009B 81FB55AA cmp bx,0xaa55
0000009F 7537 jnz 0xd8
000000A1 83E101 and cx,byte +0x1
000000A4 7432 jz 0xd8
000000A6 31C0 xor ax,ax
000000A8 894404 mov [si+0x4],ax
000000AB 40 inc ax
000000AC 8844FF mov [si-0x1],al
000000AF 894402 mov [si+0x2],ax
000000B2 C7041000 mov word [si],0x10
000000B6 668B1E5C7C mov ebx,[0x7c5c]
000000BB 66895C08 mov [si+0x8],ebx
000000BF 668B1E607C mov ebx,[0x7c60]
000000C4 66895C0C mov [si+0xc],ebx
000000C8 C744060070 mov word [si+0x6],0x7000
000000CD B442 mov ah,0x42
000000CF CD13 int 0x13
000000D1 7205 jc 0xd8
000000D3 BB0070 mov bx,0x7000
000000D6 EB76 jmp short 0x14e
000000D8 B408 mov ah,0x8
000000DA CD13 int 0x13
000000DC 730D jnc 0xeb
000000DE 5A pop dx
000000DF 84D2 test dl,dl
000000E1 0F83DE00 jnc word 0x1c3
000000E5 BE857D mov si,0x7d85
000000E8 E98200 jmp word 0x16d
000000EB 660FB6C6 movzx eax,dh
000000EF 8864FF mov [si-0x1],ah
000000F2 40 inc ax
000000F3 66894404 mov [si+0x4],eax
000000F7 0FB6D1 movzx dx,cl
000000FA C1E202 shl dx,byte 0x2
000000FD 88E8 mov al,ch
000000FF 88F4 mov ah,dh
00000101 40 inc ax
00000102 894408 mov [si+0x8],ax
00000105 0FB6C2 movzx ax,dl
00000108 C0E802 shr al,byte 0x2
0000010B 668904 mov [si],eax
0000010E 66A1607C mov eax,[0x7c60]
00000112 6609C0 or eax,eax
00000115 754E jnz 0x165
00000117 66A15C7C mov eax,[0x7c5c]
0000011B 6631D2 xor edx,edx
0000011E 66F734 div dword [si]
00000121 88D1 mov cl,dl
00000123 31D2 xor dx,dx
00000125 66F77404 div dword [si+0x4]
00000129 3B4408 cmp ax,[si+0x8]
0000012C 7D37 jnl 0x165
0000012E FEC1 inc cl
00000130 88C5 mov ch,al
00000132 30C0 xor al,al
00000134 C1E802 shr ax,byte 0x2
00000137 08C1 or cl,al
00000139 88D0 mov al,dl
0000013B 5A pop dx
0000013C 88C6 mov dh,al
0000013E BB0070 mov bx,0x7000
00000141 8EC3 mov es,bx
00000143 31DB xor bx,bx
00000145 B80102 mov ax,0x201
00000148 CD13 int 0x13
0000014A 721E jc 0x16a
0000014C 8CC3 mov bx,es
0000014E 60 pushaw
0000014F 1E push ds
00000150 B90001 mov cx,0x100
00000153 8EDB mov ds,bx
00000155 31F6 xor si,si
00000157 BF0080 mov di,0x8000
0000015A 8EC6 mov es,si
0000015C FC cld
0000015D F3A5 rep movsw
0000015F 1F pop ds
00000160 61 popaw
00000161 FF265A7C jmp word [0x7c5a]
00000165 BE807D mov si,0x7d80
00000168 EB03 jmp short 0x16d
0000016A BE8F7D mov si,0x7d8f
0000016D E83400 call word 0x1a4
00000170 BE947D mov si,0x7d94
00000173 E82E00 call word 0x1a4
00000176 CD18 int 0x18
00000178 EBFE jmp short 0x178
.end
.data
0000017A 475255422000 ;GRUB
00000180 47656F6D00 ;Geom
00000185 48617264204469736B00 ;Hard Disk
0000018F 5265616400 ;Read
00000193 204572726F720D0A00 ; Error\r\n
.end
.code
0000019D BB0100 mov bx,0x1
000001A0 B40E mov ah,0xe
000001A2 CD10 int 0x10
000001A4 AC lodsb
000001A5 3C00 cmp al,0x0
000001A7 75F4 jnz 0x19d
000001A9 C3 ret
.end
.data
000001AA 0000 add [bx+si],al
000001AC 0000 add [bx+si],al
000001AE 0000 add [bx+si],al
000001B0 0000 add [bx+si],al
000001B2 0000 add [bx+si],al
.end
.unused
000001B4 0000 add [bx+si],al
000001B6 0000 add [bx+si],al
000001B8 845D7B test [di+0x7b],bl
000001BB 16 push ss
000001BC 0000 add [bx+si],al
.end
如上代码其实可以在github的grub2的源码中找到,boot.S,使用的是gas汇编器编译,gnu asm语法,对照着来看,和我的mbr.bin一模一样。 但是真正的code段有主要在第一行是一个段内直接近转移,跳刀0x65开始执行,然后一路执行直到指令 jmp short 0x178 这行,就如一个死循环,因为0x178就是自身,之后的0x17A开始的是数据段,对照boot.S源码可以看到
notification_string: .asciz "GRUB "
geometry_error_string: .asciz "Geom"
hd_probe_error_string: .asciz "Hard Disk"
read_error_string: .asciz "Read"
general_error_string: .asciz " Error\r\n"
上面的.unused段是我还没有分析出来的,目测是一些垃圾数据。
评论
暂无评论~~