fq
fq copied to clipboard
Add MBR format
Related to issue #23
This is a first pass, it breaks down the MBR into the code_area, the partition_table, and the signature (magic number denoting the end of the boot record)
Future work
- Disassemble the 16-bit opcodes in the code area for example
objdump -D -Mintel,i8086 -b binary -m i386 format/mbr/testdata/mbr.bin | head -15
format/mbr/testdata/mbr.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: fa cli
1: bc 00 7c mov sp,0x7c00
4: 31 c0 xor ax,ax
6: 8e d0 mov ss,ax
8: 8e c0 mov es,ax
a: 8e d8 mov ds,ax
c: 52 push dx
d: be 00 7c mov si,0x7c00
Background
MBR is short for Master Boot Record. It is the legacy method of booting, the code area is limited to 446 bytes, and it's all 16-bit x86 opcodes. Old BIOS code knows how to call into it and execute the instructions there. MBR also has a 64-byte partition table that can store up to 4 partitions. The GPT partitioning scheme obsoletes this, and allows for more partitions, but that requires UEFI to work.
For more information on MBR, see: https://thestarman.pcministry.com/asm/mbr/PartTables.htm#mbr
Nice start! will be interesting to get started with ISA decoding in fq, have some ideas but nothing clear yet so we will probably have to try things out :)
Just comment here, IM or send me an email if you have any questions or want to discuss something
Tried the x86_16 decoder, seems to work ok. But i'm not that pleased with the current output, it would be nice to split out more operands and such.. hmm
$ go run fq.go -o line_bytes=4 -d raw 'tobytes[0:446] | x86_16 | dd' mbr.bin
│00 01 02 03│0123│.[0:193]: (x86_16)
│ │ │ [0]{}:
0x000│fa │. │ opcode: "cli" (raw bits)
│ │ │ op: "cli" (0xfa000000)
│ │ │ [1]{}:
0x000│ bc 00 7c│ ..|│ opcode: "mov sp, 0x7c00" (raw bits)
│ │ │ op: "mov" (0xbc000000)
│ │ │ [2]{}:
0x004│31 c0 │1. │ opcode: "xor ax, ax" (raw bits)
│ │ │ op: "xor" (0x31c00000)
│ │ │ [3]{}:
0x004│ 8e d0│ ..│ opcode: "mov ss, ax" (raw bits)
│ │ │ op: "mov" (0x8ed00000)
│ │ │ [4]{}:
0x008│8e c0 │.. │ opcode: "mov es, ax" (raw bits)
│ │ │ op: "mov" (0x8ec00000)
│ │ │ [5]{}:
0x008│ 8e d8│ ..│ opcode: "mov ds, ax" (raw bits)
│ │ │ op: "mov" (0x8ed80000)
│ │ │ [6]{}:
0x00c│52 │R │ opcode: "push dx" (raw bits)
│ │ │ op: "push" (0x52000000)
│ │ │ [7]{}:
0x00c│ be 00 7c│ ..|│ opcode: "mov si, 0x7c00" (raw bits)
│ │ │ op: "mov" (0xbe000000)
│ │ │ [8]{}:
0x010│bf 00 06 │... │ opcode: "mov di, 0x600" (raw bits)
│ │ │ op: "mov" (0xbf000000)
....
Probably going to pick up work on this next week, it's Hack Week at SUSE
🥳 let me know if you have questions or want to discuss something
Cleaned up some of the Try* things https://github.com/wader/fq/pull/302 if you switch to d.*U*() instead of d.Bits it should be fine.
Also fixed some of the doc typos https://github.com/wader/fq/pull/303
Just a note if you start working on this again: in master format documentation is now .md files again, so you can convert format/mbr/mbr.jq into a normal markdown file, see macho.md etc, and then embed it, see macho.go etc. Then it will be used both for generating documentation and cli help.
Format registration on master have changed a bit but should be straight forward to copy/paste from msgpack.go etc and rename some things and also do the same for formats.go