Documentation
¶
Overview ¶
Package bzimage implements decoding for bzImage files.
The bzImage struct contains all the information about the file and can be used to create a new bzImage.
Index ¶
- Constants
- Variables
- func Equal(a, b []byte) error
- func KVer(k io.ReadSeeker) (string, error)
- type BzImage
- func (b *BzImage) AddInitRAMFS(name string) error
- func (b *BzImage) Diff(b2 *BzImage) string
- func (b *BzImage) ELF() (*elf.File, error)
- func (b *BzImage) InitRAMFS() (int, int, error)
- func (bz *BzImage) KVer() (string, error)
- func (b *BzImage) MarshalBinary() ([]byte, error)
- func (b *BzImage) ReadConfig() (string, error)
- func (b *BzImage) UnmarshalBinary(d []byte) error
- type COFFHeader
- type E820Entry
- type EDDInfo
- type KInfo
- type LinuxHeader
- type LinuxParams
- type OptionalHeader
- type PEImage
Constants ¶
const ( RAM e820type = 1 Reserved e820type = 2 ACPI e820type = 3 NVS e820type = 4 )
E820 types.
const ( NotSet boottype = 0 LoadLin boottype = 1 BootSect boottype = 2 SysLinux boottype = 3 EtherBoot boottype = 4 Kernel boottype = 5 )
Boot types.
const ( RamdiskStartMask = 0x07FF Prompt = 0x8000 Load = 0x4000 CommandLineMagic = 0x7ff CommandLineSize = 256 DefaultInitrdAddrMax = 0x37FFFFFF DefaultBzimageAddrMax = 0x37FFFFFF E820Max = 128 E820Map = 0x2d0 E820NR = 0x1e8 )
Offsets and magic values.
const ( EDDMBRSigMax = 16 EDDMaxNR = 6 /* number of edd_info structs starting at EDDBUF */ EDDDeviceParamSize = 74 )
EDD consts.
const ( EDDExtFixedDiskAccess = 1 << iota EDDExtDeviceLockingAndEjecting EDDExtEnhancedDiskDriveSupport EDDExt64BitExtensions )
EDDExt consts.
const MSDOS = "MZ"
MSDOS tag used in .efi binaries. There are no words.
Variables ¶
var ( // LoaderType contains strings describing boot types. LoaderType = map[boottype]string{ NotSet: "Not set", LoadLin: "loadlin", BootSect: "bootsector", SysLinux: "syslinux", EtherBoot: "etherboot", Kernel: "kernel (kexec)", } // E820 contains strings describing e820types. E820 = map[e820type]string{ RAM: "RAM", Reserved: "Reserved", ACPI: "ACPI", NVS: "NVS", } // HeaderMagic is kernel header magic bytes. HeaderMagic = [4]uint8{'H', 'd', 'r', 'S'} )
var ( // ErrBootSig is returned when the boot sig is missing. ErrBootSig = errors.New("missing 0x55AA boot sig") // ErrBadSig is returned when the kernel header sig is missing. ErrBadSig = errors.New("missing kernel header sig") // ErrBadOff is returned if the version string offset is null. ErrBadOff = errors.New("null version string offset") // ErrParse is returned on a parse error. ErrParse = errors.New("parse error") )
var ( // Debug is a function used to log debug information. It // can be set to, for example, log.Printf. Debug = func(string, ...interface{}) {} )
var ErrCfgNotFound = errors.New("embedded config not found")
ErrCfgNotFound is returned if embedded config is not found.
var ErrKCodeMissing = errors.New("No kernel code was decompressed")
ErrKCodeMissing is returned if kernel code was not decompressed.
Functions ¶
Types ¶
type BzImage ¶
type BzImage struct { Header LinuxHeader BootCode []byte HeadCode []byte KernelCode []byte TailCode []byte // This field contains the CRC read from the image while unmarshaling. // This value is *not* used while marshaling the data to binary; a new CRC32 is calculated. CRC32 uint32 KernelBase uintptr KernelOffset uintptr // Some operations don't need the decompressed code; this speeds them up significantly. NoDecompress bool // contains filtered or unexported fields }
BzImage represents sections extracted from a kernel.
func (*BzImage) AddInitRAMFS ¶
AddInitRAMFS adds an initramfs to the BzImage.
func (*BzImage) Diff ¶
Diff is a convenience function that returns a string showing differences between a bzImage and another bzImage
func (*BzImage) InitRAMFS ¶
InitRAMFS returns a []byte from KernelCode which can be used to save or replace an existing InitRAMFS. The fun part is that there are no symbols; what we do instead is find the programs what are RW and look for the cpio magic in them. If we find it, we see if it can be read as a cpio and, if so, if there is a /dev or /init inside. We repeat until we succeed or there's nothing left.
func (*BzImage) MarshalBinary ¶
MarshalBinary implements the encoding.BinaryMarshaler interface. The marshal'd image is *not* signed.
func (*BzImage) ReadConfig ¶
ReadConfig extracts embedded config from kernel
func (*BzImage) UnmarshalBinary ¶
UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. For now, it hardwires the KernelBase to 0x100000. bzImages were created by a process of evilution, and they are wondrous to behold. "Documentation" can be found at https://www.kernel.org/doc/html/latest/x86/boot.html. bzImages are almost impossible to modify. They form a sandwich with the compressed kernel code in the middle. It's actually a BLT: MBR and bootparams first 512 bytes the MBR includes 0xc0 bytes of boot code which is used for UEFI booting. Then there is "preamble" code which is the kernel decompressor; then the xz compressed kernel; then a library of sorts after the kernel which is called by the early uncompressed kernel code. This is all linked together and forms an essentially indivisible whole -- which we wish to divisible. That said, if you keep layout unchanged, you can modify the uncompressed kernel. For example, when you first build a kernel, you can: dd if=/dev/urandom of=x bs=1048576 count=8 echo x | cpio -o > x.cpio and use that as an initrd, it's more or less an 8 MiB block you can replace as needed. Just make sure nothing grows. And make sure the initramfs is in the same place. Ah, joy.
Important note for signed kernel images: The kernel signature is stripped away and ignored. Users of UnmarshalBinary must separately check the image signature, if required.
type COFFHeader ¶
type COFFHeader struct { Machine [2]byte NumberOfSections [2]byte TimeDateStamp [4]byte PointerToSymbolTable [4]byte NumberOfSymbols [4]byte SizeOfOptionalHeader uint16 Characteristics [2]byte }
COFF Header. Details at: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image
type EDDInfo ¶
type EDDInfo struct { Device uint8 Version uint8 InterfaceSupport uint16 LegacyMaxCylinder uint16 LegacyMaxHead uint8 LegacySectorsPerTrace uint8 EDDDeviceParams [EDDDeviceParamSize]uint8 }
EDDInfo struct.
type KInfo ¶
type KInfo struct {
Release, Version string // uname -r, uname -v respectfully
Builder string // user@hostname in parenthesis, shown by `file` but not `uname`
BuildNum uint64 //#nnn in Version, 300 in example above
BuildTime time.Time // from Version
Maj, Min, Patch uint64 // from Release
LocalVer string // from Release
}
KInfo struct holds info extracted from the kernel's embedded version string
2.6.24.111 (bluebat@linux-vm-os64.site) #606 Mon Apr 14 00:06:11 CEST 2014 4.19.16-norm_boot (user@host) #300 SMP Fri Jan 25 16:32:19 UTC 2019
release (builder) version
maj.min.patch-localver #buildnum SMP buildtime
type LinuxHeader ¶
type LinuxHeader struct { MBRCode [0xc0]uint8 `offset:"0x000"` ExtRamdiskImage uint32 `offset:"0xc0"` ExtRamdiskSize uint32 `offset:"0xc4"` ExtCmdlinePtr uint32 `offset:"0xc8"` O [0x1f1 - 0xcc]uint8 `offset:"0xcc"` SetupSects uint8 `offset:"0x1f1"` RootFlags uint16 `offset:"0x1f2"` Syssize uint32 `offset:"0x1f4"` //(2.04+) RAMSize uint16 `offset:"0x1f8"` Vidmode uint16 `offset:"0x1fa"` RootDev uint16 `offset:"0x1fc"` Bootsectormagic uint16 `offset:"0x1fe"` // 0.00+ Jump uint16 `offset:"0x200"` HeaderMagic [4]uint8 `offset:"0x202"` Protocolversion uint16 `offset:"0x206"` RealModeSwitch uint32 `offset:"0x208"` StartSys uint16 `offset:"0x20c"` Kveraddr uint16 `offset:"0x20e"` TypeOfLoader uint8 `offset:"0x210"` Loadflags uint8 `offset:"0x211"` Setupmovesize uint16 `offset:"0x212"` Code32Start uint32 `offset:"0x214"` RamdiskImage uint32 `offset:"0x218"` RamdiskSize uint32 `offset:"0x21c"` BootSectKludge [4]uint8 `offset:"0x220"` // 2.01+ Heapendptr uint16 `offset:"0x224"` ExtLoaderVer uint8 `offset:"0x226"` ExtLoaderType uint8 `offset:"0x227"` // 2.02+ Cmdlineptr uint32 `offset:"0x228"` // 2.03+ InitrdAddrMax uint32 `offset:"0x22c"` // 2.05+ Kernelalignment uint32 `offset:"0x230"` RelocatableKernel uint8 `offset:"0x234"` MinAlignment uint8 `offset:"0x235"` //(2.10+) XLoadFlags uint16 `offset:"0x236"` // 2.06+ CmdLineSize uint32 `offset:"0x238"` // 2.07+ HardwareSubArch uint32 `offset:"0x23c"` HardwareSubArchData uint64 `offset:"0x240"` // 2.08+ PayloadOffset uint32 `offset:"0x248"` PayloadSize uint32 `offset:"0x24c"` // 2.09+ SetupData uint64 `offset:"0x250"` // 2.10+ PrefAddress uint64 `offset:"0x258"` InitSize uint32 `offset:"0x260"` HandoverOffset uint32 `offset:"0x264"` }
LinuxHeader is the header of Linux/i386 kernel
func (*LinuxHeader) Diff ¶
func (h *LinuxHeader) Diff(i *LinuxHeader) string
Diff is a convenience function that returns a string showing differences between a header and another header.
func (*LinuxHeader) MarshalBinary ¶
func (h *LinuxHeader) MarshalBinary() ([]byte, error)
MarshalBinary implements encoding.BinaryMarshaler
func (*LinuxHeader) Show ¶
func (h *LinuxHeader) Show() []string
Show stringifies a LinuxHeader into a []string.
func (*LinuxHeader) String ¶
func (h *LinuxHeader) String() string
String stringifies a LinuxHeader into comma-separated parts
func (*LinuxHeader) UnmarshalBinary ¶
func (h *LinuxHeader) UnmarshalBinary(b []byte) error
UnmarshalBinary implements encoding.BinaryMarshaler
type LinuxParams ¶
type LinuxParams struct { Origx uint8 `offset:"0x00"` Origy uint8 `offset:"0x01"` ExtMemK uint16 `offset:"0x02"` //-- EXTMEMK sits here OrigVideoPage uint16 `offset:"0x04"` OrigVideoMode uint8 `offset:"0x06"` OrigVideoCols uint8 `offset:"0x07"` OrigVideoeGabx uint16 `offset:"0x0a"` OrigVideoLines uint8 `offset:"0x0e"` OrigVideoIsVGA uint8 `offset:"0x0f"` OrigVideoPoints uint16 `offset:"0x10"` // VESA graphic mode -- linear frame buffer Lfbwidth uint16 `offset:"0x12"` Lfbheight uint16 `offset:"0x14"` Lfbdepth uint16 `offset:"0x16"` Lfbbase uint32 `offset:"0x18"` Lfbsize uint32 `offset:"0x1c"` CLMagic uint16 `offset:"0x20"` // DON'T USE CLOffset uint16 `offset:"0x22"` // DON'T USE Lfblinelength uint16 `offset:"0x24"` Redsize uint8 `offset:"0x26"` Redpos uint8 `offset:"0x27"` Greensize uint8 `offset:"0x28"` Greenpos uint8 `offset:"0x29"` Bluesize uint8 `offset:"0x2a"` Bluepos uint8 `offset:"0x2b"` Rsvdsize uint8 `offset:"0x2c"` Rsvdpos uint8 `offset:"0x2d"` Vesapmseg uint16 `offset:"0x2e"` Vesapmoff uint16 `offset:"0x30"` Pages uint16 `offset:"0x32"` // struct apmbiosinfo apmbiosinfo; Apmbiosinfo [0x40]uint8 `offset:"0x40"` // struct driveinfostruct driveinfo; Driveinfo [0x20]uint8 `offset:"0x80"` // struct sysdesctable sysdesctable; Sysdesctable [0x140]uint8 `offset:"0xa0"` Altmemk uint32 `offset:"0x1e0"` E820MapNr uint8 `offset:"0x1e8"` MountRootReadonly uint16 `offset:"0x1f2"` Ramdiskflags uint16 `offset:"0x1f8"` OrigRootDev uint16 `offset:"0x1fc"` Auxdeviceinfo uint8 `offset:"0x1ff"` Paramblocksignature [4]uint8 `offset:"0x202"` Paramblockversion uint16 `offset:"0x206"` LoaderType uint8 `offset:"0x210"` Loaderflags uint8 `offset:"0x211"` KernelStart uint32 `offset:"0x214"` Initrdstart uint32 `offset:"0x218"` Initrdsize uint32 `offset:"0x21c"` CLPtr uint32 `offset:"0x228"` // USE THIS. InitrdAddrMax uint32 `offset:"0x22c"` /* 2.04+ */ KernelAlignment uint32 `offset:"0x230"` RelocatableKernel uint8 `offset:"0x234"` MinAlignment uint8 `offset:"0x235"` XLoadFlags uint16 `offset:"0x236"` CmdLineSize uint32 `offset:"0x238"` HardwareSubarch uint32 `offset:"0x23C"` HardwareSubarchData uint64 `offset:"0x240"` PayloadOffset uint32 `offset:"0x248"` PayloadLength uint32 `offset:"0x24C"` SetupData uint64 `offset:"0x250"` PrefAddress uint64 `offset:"0x258"` InitSize uint32 `offset:"0x260"` HandoverOffset uint32 `offset:"0x264"` EDDMBRSigBuffer [EDDMBRSigMax]uint32 `offset:"0x290"` // e820map is another cockup from the usual suspects. // Go rounds the size to something reasonable. Oh well. No checking for you. // So the next two offsets are bogus, sorry about that. E820Map [E820Max]E820Entry `offset:"0x2d0"` EDDBuf [EDDMaxNR]EDDInfo `offset:"0xf00"` // `offset:"0xd00"` // contains filtered or unexported fields }
LinuxParams is parameters passed to the 32-bit part of Linux
func (*LinuxParams) MarshalBinary ¶
func (h *LinuxParams) MarshalBinary() ([]byte, error)
MarshalBinary implements encoding.BinaryMarshaler
func (*LinuxParams) Show ¶
func (h *LinuxParams) Show() []string
Show stringifies a LinuxParams into a []string.
func (*LinuxParams) String ¶
func (h *LinuxParams) String() string
String stringifies a LinuxParams into comma-separated parts
func (*LinuxParams) UnmarshalBinary ¶
func (h *LinuxParams) UnmarshalBinary(b []byte) error
UnmarshalBinary implements encoding.BinaryMarshaler
type OptionalHeader ¶
type OptionalHeader struct { Magic uint16 // contains filtered or unexported fields }
Standard fields in all PE Optional Headers. Details at: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-standard-fields-image-only
type PEImage ¶
type PEImage struct { PEMagic [4]byte COFFHeader OptionalHeader }
PE Image file. Details at: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers