Class: EFIValidate::EFIValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/efivalidate/efi_validator.rb

Overview

Class that represents a single run of a validator against a firmware

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser, file) ⇒ EFIValidator

Returns a new instance of EFIValidator.



6
7
8
9
10
11
12
13
14
# File 'lib/efivalidate/efi_validator.rb', line 6

def initialize(parser, file)
  @parser = parser

  reader = File.open(file, mode: 'rb')
  @data = reader.read
  reader.close

  perform_core_sec_fixup if @parser.rows.any?(&:core_sec?)
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



4
5
6
# File 'lib/efivalidate/efi_validator.rb', line 4

def data
  @data
end

#errorsObject (readonly)

Returns the value of attribute errors.



4
5
6
# File 'lib/efivalidate/efi_validator.rb', line 4

def errors
  @errors
end

#parserObject (readonly)

Returns the value of attribute parser.



4
5
6
# File 'lib/efivalidate/efi_validator.rb', line 4

def parser
  @parser
end

Instance Method Details

#get_region(offset, length) ⇒ Object



28
29
30
# File 'lib/efivalidate/efi_validator.rb', line 28

def get_region(offset, length)
  @data[offset, length] || ''
end

#perform_core_sec_fixupObject



32
33
34
35
36
37
# File 'lib/efivalidate/efi_validator.rb', line 32

def perform_core_sec_fixup
  # Apple zeros out what appears to be a hash and checksum before validating the SEC_CORE region

  @data[-0x100, 0x80] = "\0" * 0x80
  @data[-0x04, 0x04] = "\0" * 0x04
end

#valid?Boolean

Returns:

  • (Boolean)


43
44
45
46
47
# File 'lib/efivalidate/efi_validator.rb', line 43

def valid?
  validate

  errors.count.zero?
end

#validateObject



39
40
41
# File 'lib/efivalidate/efi_validator.rb', line 39

def validate
  validate! unless @errors
end

#validate!Object



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/efivalidate/efi_validator.rb', line 16

def validate!
  @errors = []

  @parser.rows.reject(&:privacy_row?).each do |row|
    section_data = get_region(row.ealf_offset, row.ealf_length)

    calculated_hash = @parser.header.create_hash.hexdigest section_data

    @errors << EFIValidationError.new(row, section_data, calculated_hash) unless calculated_hash == row.hash
  end
end