0x01 磁盘分区和引导flag
我的机器本地操作系统是fedora21, grub安装在第一块磁盘/dev/sda, 首先执行dd if=/dev/sda of=mbr.bin bs=512 count=1提取出我本地磁盘的mbr.bin,就是/dev/sda的前512个字节。 根据mbr的,了解到从0x1BE开始的64个字节为磁盘分区信息,写了个parse简单分析分区信息,见 , 最后两个字节为0x55, 0xaa,告诉bios这是一个bootloader。
00000000: eb63 90d0 bc00 7c8e c08e d8be 007c bf0000000010: 06b9 0002 fcf3 a450 681c 06cb fbb9 040000000020: bdbe 0780 7e00 007c 0b0f 850e 0183 c51000000030: e2f1 cd18 8856 0055 c646 1105 c646 100000000040: b441 bbaa 55cd 135d 720f 81fb 55aa 750900000050: f7c1 0100 7403 fe46 1066 0080 0100 000000000060: 0000 0000 fffa 9090 f6c2 8074 05f6 c27000000070: 7402 b280 ea79 7c00 0031 c08e d88e d0bc00000080: 0020 fba0 647c 3cff 7402 88c2 52be 057c00000090: b441 bbaa 55cd 135a 5272 3d81 fb55 aa75000000a0: 3783 e101 7432 31c0 8944 0440 8844 ff89000000b0: 4402 c704 1000 668b 1e5c 7c66 895c 0866000000c0: 8b1e 607c 6689 5c0c c744 0600 70b4 42cd000000d0: 1372 05bb 0070 eb76 b408 cd13 730d 5a84000000e0: d20f 83de 00be 857d e982 0066 0fb6 c688000000f0: 64ff 4066 8944 040f b6d1 c1e2 0288 e88800000100: f440 8944 080f b6c2 c0e8 0266 8904 66a100000110: 607c 6609 c075 4e66 a15c 7c66 31d2 66f700000120: 3488 d131 d266 f774 043b 4408 7d37 fec100000130: 88c5 30c0 c1e8 0208 c188 d05a 88c6 bb0000000140: 708e c331 dbb8 0102 cd13 721e 8cc3 601e00000150: b900 018e db31 f6bf 0080 8ec6 fcf3 a51f00000160: 61ff 265a 7cbe 807d eb03 be8f 7de8 340000000170: be94 7de8 2e00 cd18 ebfe 4752 5542 200000000180: 4765 6f6d 0048 6172 6420 4469 736b 005200000190: 6561 6400 2045 7272 6f72 0d0a 00bb 0100000001a0: b40e cd10 ac3c 0075 f4c3 0000 0000 0000000001b0: 0000 0000 0000 0000 845d 7b16 0000 8020000001c0: 2100 07fe ffff 0008 0000 0080 4f12 0070000001d0: bfb2 8386 1531 0088 4f12 0000 4006 00fe000001e0: ffff 83fe ffff 0088 8f18 00a0 0f00 00fe000001f0: ffff 05fe ffff 0028 9f18 0038 9921 55aa
如上是我的mbr.bin的16进制
0x02 BootLoader的数据段和代码段
既然已经确定后面66个字节不是bootloader的代码和数据,那么我们使用ndisasm反汇编前446个字节的数据就行。
.code00000000 EB63 jmp short 0x65 ;跳转到0x65.end.unused00000002 90 nop00000003 D0BC007C sar byte [si+0x7c00],100000007 8EC0 mov es,ax00000009 8ED8 mov ds,ax0000000B BE007C mov si,0x7c000000000E BF0006 mov di,0x60000000011 B90002 mov cx,0x20000000014 FC cld00000015 F3A4 rep movsb00000017 50 push ax00000018 681C06 push word 0x61c0000001B CB retf0000001C FB sti0000001D B90400 mov cx,0x400000020 BDBE07 mov bp,0x7be00000023 807E0000 cmp byte [bp+0x0],0x000000027 7C0B jl 0x3400000029 0F850E01 jnz word 0x13b0000002D 83C510 add bp,byte +0x1000000030 E2F1 loop 0x2300000032 CD18 int 0x1800000034 885600 mov [bp+0x0],dl00000037 55 push bp00000038 C6461105 mov byte [bp+0x11],0x50000003C C6461000 mov byte [bp+0x10],0x000000040 B441 mov ah,0x4100000042 BBAA55 mov bx,0x55aa00000045 CD13 int 0x1300000047 5D pop bp00000048 720F jc 0x590000004A 81FB55AA cmp bx,0xaa550000004E 7509 jnz 0x5900000050 F7C10100 test cx,0x100000054 7403 jz 0x5900000056 FE4610 inc byte [bp+0x10]00000059 6600800100 o32 add [bx+si+0x1],al0000005E 0000 add [bx+si],al00000060 0000 add [bx+si],al00000062 0000 add [bx+si],al.end.data00000064 FF db 0xff.end.code00000065 FA cli ;屏蔽中断00000066 90 nop ;滑行00000067 90 nop00000068 F6C280 test dl,0x80 ;比较dl是否为0x800000006B 7405 jz 0x720000006D F6C270 test dl,0x7000000070 7402 jz 0x7400000072 B280 mov dl,0x8000000074 EA797C0000 jmp word 0x0:0x7c7900000079 31C0 xor ax,ax0000007B 8ED8 mov ds,ax0000007D 8ED0 mov ss,ax0000007F BC0020 mov sp,0x200000000082 FB sti00000083 A0647C mov al,[0x7c64]00000086 3CFF cmp al,0xff00000088 7402 jz 0x8c0000008A 88C2 mov dl,al0000008C 52 push dx0000008D BE057C mov si,0x7c0500000090 B441 mov ah,0x4100000092 BBAA55 mov bx,0x55aa00000095 CD13 int 0x1300000097 5A pop dx00000098 52 push dx00000099 723D jc 0xd80000009B 81FB55AA cmp bx,0xaa550000009F 7537 jnz 0xd8000000A1 83E101 and cx,byte +0x1000000A4 7432 jz 0xd8000000A6 31C0 xor ax,ax000000A8 894404 mov [si+0x4],ax000000AB 40 inc ax000000AC 8844FF mov [si-0x1],al000000AF 894402 mov [si+0x2],ax000000B2 C7041000 mov word [si],0x10000000B6 668B1E5C7C mov ebx,[0x7c5c]000000BB 66895C08 mov [si+0x8],ebx000000BF 668B1E607C mov ebx,[0x7c60]000000C4 66895C0C mov [si+0xc],ebx000000C8 C744060070 mov word [si+0x6],0x7000000000CD B442 mov ah,0x42000000CF CD13 int 0x13000000D1 7205 jc 0xd8000000D3 BB0070 mov bx,0x7000000000D6 EB76 jmp short 0x14e000000D8 B408 mov ah,0x8000000DA CD13 int 0x13000000DC 730D jnc 0xeb000000DE 5A pop dx000000DF 84D2 test dl,dl000000E1 0F83DE00 jnc word 0x1c3000000E5 BE857D mov si,0x7d85000000E8 E98200 jmp word 0x16d000000EB 660FB6C6 movzx eax,dh000000EF 8864FF mov [si-0x1],ah000000F2 40 inc ax000000F3 66894404 mov [si+0x4],eax000000F7 0FB6D1 movzx dx,cl000000FA C1E202 shl dx,byte 0x2000000FD 88E8 mov al,ch000000FF 88F4 mov ah,dh00000101 40 inc ax00000102 894408 mov [si+0x8],ax00000105 0FB6C2 movzx ax,dl00000108 C0E802 shr al,byte 0x20000010B 668904 mov [si],eax0000010E 66A1607C mov eax,[0x7c60]00000112 6609C0 or eax,eax00000115 754E jnz 0x16500000117 66A15C7C mov eax,[0x7c5c]0000011B 6631D2 xor edx,edx0000011E 66F734 div dword [si]00000121 88D1 mov cl,dl00000123 31D2 xor dx,dx00000125 66F77404 div dword [si+0x4]00000129 3B4408 cmp ax,[si+0x8]0000012C 7D37 jnl 0x1650000012E FEC1 inc cl00000130 88C5 mov ch,al00000132 30C0 xor al,al00000134 C1E802 shr ax,byte 0x200000137 08C1 or cl,al00000139 88D0 mov al,dl0000013B 5A pop dx0000013C 88C6 mov dh,al0000013E BB0070 mov bx,0x700000000141 8EC3 mov es,bx00000143 31DB xor bx,bx00000145 B80102 mov ax,0x20100000148 CD13 int 0x130000014A 721E jc 0x16a0000014C 8CC3 mov bx,es0000014E 60 pushaw0000014F 1E push ds00000150 B90001 mov cx,0x10000000153 8EDB mov ds,bx00000155 31F6 xor si,si00000157 BF0080 mov di,0x80000000015A 8EC6 mov es,si0000015C FC cld0000015D F3A5 rep movsw0000015F 1F pop ds00000160 61 popaw00000161 FF265A7C jmp word [0x7c5a]00000165 BE807D mov si,0x7d8000000168 EB03 jmp short 0x16d0000016A BE8F7D mov si,0x7d8f0000016D E83400 call word 0x1a400000170 BE947D mov si,0x7d9400000173 E82E00 call word 0x1a400000176 CD18 int 0x1800000178 EBFE jmp short 0x178.end.data0000017A 475255422000 ;GRUB 00000180 47656F6D00 ;Geom00000185 48617264204469736B00 ;Hard Disk0000018F 5265616400 ;Read00000193 204572726F720D0A00 ; Error\r\n .end.code0000019D BB0100 mov bx,0x1000001A0 B40E mov ah,0xe000001A2 CD10 int 0x10000001A4 AC lodsb000001A5 3C00 cmp al,0x0000001A7 75F4 jnz 0x19d000001A9 C3 ret.end.data000001AA 0000 add [bx+si],al000001AC 0000 add [bx+si],al000001AE 0000 add [bx+si],al000001B0 0000 add [bx+si],al000001B2 0000 add [bx+si],al.end.unused000001B4 0000 add [bx+si],al000001B6 0000 add [bx+si],al000001B8 845D7B test [di+0x7b],bl000001BB 16 push ss000001BC 0000 add [bx+si],al.end
如上代码其实可以在github的grub2的源码中找到,,使用的是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段是我还没有分析出来的,目测是一些垃圾数据。