diff --git a/cmds/utk/utk.go b/cmds/utk/utk.go index 6fc50b67..181c7739 100644 --- a/cmds/utk/utk.go +++ b/cmds/utk/utk.go @@ -105,6 +105,7 @@ func main() { } } + log.Warnf("%v", args) if err := utk.Run(args...); err != nil { log.Fatalf("%v", err) } diff --git a/pkg/uefi/file.go b/pkg/uefi/file.go index 4820716a..7f3123ea 100644 --- a/pkg/uefi/file.go +++ b/pkg/uefi/file.go @@ -298,13 +298,17 @@ func (f *File) Apply(v Visitor) error { // ApplyChildren calls the visitor on each child node of File. func (f *File) ApplyChildren(v Visitor) error { + log.Warnf("apply children") if f.NVarStore != nil { + log.Warnf("nvar %v", v) if err := f.NVarStore.Apply(v); err != nil { return err } return nil } + log.Warnf("sections %v", f.Sections) for _, s := range f.Sections { + log.Warnf("apply %v %v", v, s) if err := s.Apply(v); err != nil { return err } @@ -489,7 +493,7 @@ func NewFile(buf []byte) (*File, error) { } for i, offset := 0, f.DataOffset; offset < f.Header.ExtendedSize; i++ { - s, err := NewSection(f.buf[offset:], i) + s, err := NewSection(f.buf[offset:], offset, i) if err != nil { return nil, fmt.Errorf("error parsing sections of file %v: %v", f.Header.GUID, err) } diff --git a/pkg/uefi/firmwarevolume.go b/pkg/uefi/firmwarevolume.go index dea6cb08..a035ccf9 100644 --- a/pkg/uefi/firmwarevolume.go +++ b/pkg/uefi/firmwarevolume.go @@ -185,6 +185,7 @@ func FindFirmwareVolumeOffset(data []byte) int64 { ) for offset = 32; offset+4 < int64(len(data)); offset += 8 { if bytes.Equal(data[offset:offset+4], fvSig) { + log.Warnf("_FVH@%x", data[offset+4:offset+20]) return offset - 40 // the actual volume starts 40 bytes before the signature } } diff --git a/pkg/uefi/section.go b/pkg/uefi/section.go index b85ba11f..dac64576 100644 --- a/pkg/uefi/section.go +++ b/pkg/uefi/section.go @@ -119,6 +119,48 @@ func (s *SectionGUIDDefined) GetBinHeaderLen() uint32 { return uint32(unsafe.Sizeof(s.SectionGUIDDefinedHeader)) } +// SectionCompressionHeader contains the fields for a EFI_SECTION_COMPRESSION +// encapsulated section header. +type SectionCompressionHeader struct { + UncompressedLength uint32 + CompressionType uint8 +} + +// SectionCompression contains the type specific fields for a +// EFI_SECTION_COMPRESSION section. +type SectionCompression struct { + SectionCompressionHeader + + // Metadata + Compression string +} + +// GetBinHeaderLen returns the length of the binary typ specific header +func (s *SectionCompression) GetBinHeaderLen() uint32 { + return uint32(unsafe.Sizeof(s.SectionCompressionHeader)) +} + +// SectionCompressionHeader contains the fields for a EFI_SECTION_COMPRESSION +// encapsulated section header. +type SectionCompressionExtHeader struct { + UncompressedLength uint32 + CompressionType uint8 +} + +// SectionCompression contains the type specific fields for a +// EFI_SECTION_COMPRESSION section. +type SectionCompressionExt struct { + SectionCompressionExtHeader + + // Metadata + Compression string +} + +// GetBinHeaderLen returns the length of the binary typ specific header +func (s *SectionCompressionExt) GetBinHeaderLen() uint32 { + return uint32(unsafe.Sizeof(s.SectionCompressionExtHeader)) +} + // TypeHeader interface forces type specific headers to report their length type TypeHeader interface { GetBinHeaderLen() uint32 @@ -194,6 +236,7 @@ type Section struct { // Metadata for extraction and recovery ExtractPath string FileOrder int `json:"-"` + Offset uint64 // Type specific fields // TODO: It will be simpler if this was not an interface @@ -343,8 +386,8 @@ func (s *Section) GenSecHeader() error { // NewSection parses a sequence of bytes and returns a Section // object, if a valid one is passed, or an error. -func NewSection(buf []byte, fileOrder int) (*Section, error) { - s := Section{FileOrder: fileOrder} +func NewSection(buf []byte, offset uint64, fileOrder int) (*Section, error) { + s := Section{FileOrder: fileOrder, Offset: offset} // Read in standard header. r := bytes.NewReader(buf) if err := binary.Read(r, binary.LittleEndian, &s.Header.SectionHeader); err != nil { @@ -395,8 +438,23 @@ func NewSection(buf []byte, fileOrder int) (*Section, error) { copy(s.buf, newBuf) } + DEBUG := true + // Section type specific data switch s.Header.Type { + case SectionTypeCompression: + // NOTE: HERE BE DRAGONS + if DEBUG { + log.Warnf("[section] Compressed Section:\n %+v", s.Header) + } + typeSpec := &SectionCompression{} + if err := binary.Read(r, binary.LittleEndian, &typeSpec.SectionCompressionHeader); err != nil { + return nil, err + } + s.TypeSpecific = &TypeSpecificHeader{Type: SectionTypeCompression, Header: typeSpec} + if DEBUG { + log.Warnf("[section] SectionCompression:\n %+v", typeSpec) + } case SectionTypeGUIDDefined: typeSpec := &SectionGUIDDefined{} if err := binary.Read(r, binary.LittleEndian, &typeSpec.SectionGUIDDefinedHeader); err != nil { @@ -422,7 +480,7 @@ func NewSection(buf []byte, fileOrder int) (*Section, error) { } for i, offset := 0, uint64(0); offset < uint64(len(encapBuf)); i++ { - encapS, err := NewSection(encapBuf[offset:], i) + encapS, err := NewSection(encapBuf[offset:], offset, i) if err != nil { return nil, fmt.Errorf("error parsing encapsulated section #%d at offset %d: %v", i, offset, err) diff --git a/pkg/utk/utk.go b/pkg/utk/utk.go index c42e1942..a099fa7f 100644 --- a/pkg/utk/utk.go +++ b/pkg/utk/utk.go @@ -20,7 +20,7 @@ func Run(args ...string) error { return errors.New("at least one argument is required") } - v, err := visitors.ParseCLI(args[1:]) + visitor, err := visitors.ParseCLI(args[1:]) if err != nil { return err } @@ -56,5 +56,5 @@ func Run(args ...string) error { } // Execute the instructions from the command line. - return visitors.ExecuteCLI(parsedRoot, v) + return visitors.ExecuteCLI(parsedRoot, visitor) } diff --git a/pkg/visitors/insert.go b/pkg/visitors/insert.go index ad6719b8..ac176b24 100644 --- a/pkg/visitors/insert.go +++ b/pkg/visitors/insert.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "github.com/linuxboot/fiano/pkg/log" "github.com/linuxboot/fiano/pkg/uefi" ) @@ -220,6 +221,7 @@ func (v *Insert) Visit(f uefi.Firmware) error { switch f := f.(type) { case *uefi.FirmwareVolume: for i := 0; i < len(f.Files); i++ { + log.Warnf("file %d", i) if f.Files[i] == v.FileMatch { // TODO: use InsertWherePreposition to define the location, instead of InsertType switch v.InsertType { @@ -241,6 +243,7 @@ func (v *Insert) Visit(f uefi.Firmware) error { } } + log.Warnf("apply") return f.ApplyChildren(v) } @@ -343,6 +346,7 @@ func genInsertFileCLI() func(args []string) (uefi.Visitor, error) { } // Insert File. + log.Warnf("1") return &Insert{ Predicate: pred, NewFile: file,