bzimage

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 2, 2023 License: BSD-3-Clause Imports: 21 Imported by: 9

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

View Source
const (
	RAM      e820type = 1
	Reserved e820type = 2
	ACPI     e820type = 3
	NVS      e820type = 4
)

E820 types.

View Source
const (
	NotSet    boottype = 0
	LoadLin   boottype = 1
	BootSect  boottype = 2
	SysLinux  boottype = 3
	EtherBoot boottype = 4
	Kernel    boottype = 5
)

Boot types.

View Source
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.

View Source
const (
	EDDMBRSigMax       = 16
	EDDMaxNR           = 6 /* number of edd_info structs starting at EDDBUF  */
	EDDDeviceParamSize = 74
)

EDD consts.

View Source
const (
	EDDExtFixedDiskAccess = 1 << iota
	EDDExtDeviceLockingAndEjecting
	EDDExtEnhancedDiskDriveSupport
	EDDExt64BitExtensions
)

EDDExt consts.

View Source
const MSDOS = "MZ"

MSDOS tag used in .efi binaries. There are no words.

Variables

View Source
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'}
)
View Source
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")
)
View Source
var (

	// Debug is a function used to log debug information. It
	// can be set to, for example, log.Printf.
	Debug = func(string, ...interface{}) {}
)
View Source
var ErrCfgNotFound = errors.New("embedded config not found")

ErrCfgNotFound is returned if embedded config is not found.

View Source
var ErrKCodeMissing = errors.New("No kernel code was decompressed")

ErrKCodeMissing is returned if kernel code was not decompressed.

Functions

func Equal

func Equal(a, b []byte) error

Equal compares two kernels and returns true if they are equal.

func KVer

func KVer(k io.ReadSeeker) (string, error)

KVer reads the kernel version string. See also: (*BZImage)Kver()

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

func (b *BzImage) AddInitRAMFS(name string) error

AddInitRAMFS adds an initramfs to the BzImage.

func (*BzImage) Diff

func (b *BzImage) Diff(b2 *BzImage) string

Diff is a convenience function that returns a string showing differences between a bzImage and another bzImage

func (*BzImage) ELF

func (b *BzImage) ELF() (*elf.File, error)

ELF extracts the KernelCode.

func (*BzImage) InitRAMFS

func (b *BzImage) InitRAMFS() (int, int, error)

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) KVer

func (bz *BzImage) KVer() (string, error)

KVer reads the kernel version string. See also: KVer() above.

func (*BzImage) MarshalBinary

func (b *BzImage) MarshalBinary() ([]byte, error)

MarshalBinary implements the encoding.BinaryMarshaler interface. The marshal'd image is *not* signed.

func (*BzImage) ReadConfig

func (b *BzImage) ReadConfig() (string, error)

ReadConfig extracts embedded config from kernel

func (*BzImage) UnmarshalBinary

func (b *BzImage) UnmarshalBinary(d []byte) error

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 added in v0.11.0

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 E820Entry

type E820Entry struct {
	Addr    uint64
	Size    uint64
	MemType e820type
}

E820Entry is one e820 entry.

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

func ParseDesc

func ParseDesc(desc string) (KInfo, error)

ParseDesc parses the output of KVer() or BzImage.KVer(), returning a KInfo struct.

func (KInfo) Equal

func (l KInfo) Equal(r KInfo) bool

Equal compares two KInfo structs and returns true if the content is identical.

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 added in v0.9.0

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 added in v0.9.0

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 added in v0.9.0

func (h *LinuxParams) MarshalBinary() ([]byte, error)

MarshalBinary implements encoding.BinaryMarshaler

func (*LinuxParams) Show added in v0.9.0

func (h *LinuxParams) Show() []string

Show stringifies a LinuxParams into a []string.

func (*LinuxParams) String added in v0.9.0

func (h *LinuxParams) String() string

String stringifies a LinuxParams into comma-separated parts

func (*LinuxParams) UnmarshalBinary added in v0.9.0

func (h *LinuxParams) UnmarshalBinary(b []byte) error

UnmarshalBinary implements encoding.BinaryMarshaler

type OptionalHeader added in v0.11.0

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 added in v0.11.0

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL