Module: MachO::Utils

Defined in:
lib/macho/utils.rb

Overview

A collection of utility functions used throughout ruby-macho.

Class Method Summary collapse

Class Method Details

.big_magic?(num) ⇒ Boolean

Compares the given number to valid big-endian magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid big-endian magic number



121
122
123
# File 'lib/macho/utils.rb', line 121

def self.big_magic?(num)
  [Headers::MH_MAGIC, Headers::MH_MAGIC_64].include? num
end

.compressed_magic?(num) ⇒ Boolean

Compares the given number to the known magic number for a compressed Mach-O slice.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid compressed header magic number



128
129
130
# File 'lib/macho/utils.rb', line 128

def self.compressed_magic?(num)
  num == Headers::COMPRESSED_MAGIC
end

.fat_magic32?(num) ⇒ Boolean

Compares the given number to valid 32-bit Fat magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid 32-bit fat magic number



86
87
88
# File 'lib/macho/utils.rb', line 86

def self.fat_magic32?(num)
  num == Headers::FAT_MAGIC
end

.fat_magic64?(num) ⇒ Boolean

Compares the given number to valid 64-bit Fat magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid 64-bit fat magic number



93
94
95
# File 'lib/macho/utils.rb', line 93

def self.fat_magic64?(num)
  num == Headers::FAT_MAGIC_64
end

.fat_magic?(num) ⇒ Boolean

Compares the given number to valid Fat magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid Fat magic number



79
80
81
# File 'lib/macho/utils.rb', line 79

def self.fat_magic?(num)
  [Headers::FAT_MAGIC, Headers::FAT_MAGIC_64].include? num
end

.little_magic?(num) ⇒ Boolean

Compares the given number to valid little-endian magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid little-endian magic number



114
115
116
# File 'lib/macho/utils.rb', line 114

def self.little_magic?(num)
  [Headers::MH_CIGAM, Headers::MH_CIGAM_64].include? num
end

.magic32?(num) ⇒ Boolean

Compares the given number to valid 32-bit Mach-O magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid 32-bit magic number



100
101
102
# File 'lib/macho/utils.rb', line 100

def self.magic32?(num)
  [Headers::MH_MAGIC, Headers::MH_CIGAM].include? num
end

.magic64?(num) ⇒ Boolean

Compares the given number to valid 64-bit Mach-O magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid 64-bit magic number



107
108
109
# File 'lib/macho/utils.rb', line 107

def self.magic64?(num)
  [Headers::MH_MAGIC_64, Headers::MH_CIGAM_64].include? num
end

.magic?(num) ⇒ Boolean

Compares the given number to valid Mach-O magic numbers.

Parameters:

  • num (Integer)

    the number being checked

Returns:

  • (Boolean)

    whether num is a valid Mach-O magic number



72
73
74
# File 'lib/macho/utils.rb', line 72

def self.magic?(num)
  Headers::MH_MAGICS.key?(num)
end

.nullpad(size) ⇒ String

Returns a string of null bytes of the requested (non-negative) size

Parameters:

  • size (Integer)

    the size of the nullpad

Returns:

  • (String)

    the null string (or empty string, for size = 0)

Raises:

  • (ArgumentError)

    if a non-positive nullpad is requested



31
32
33
34
35
# File 'lib/macho/utils.rb', line 31

def self.nullpad(size)
  raise ArgumentError, "size < 0: #{size}" if size.negative?

  "\x00" * size
end

.pack_strings(fixed_offset, alignment, strings = {}) ⇒ Array<String, Hash>

Packs tagged strings into an aligned payload.

Parameters:

  • fixed_offset (Integer)

    the baseline offset for the first packed string

  • alignment (Integer)

    the alignment value to use for packing

  • strings (Hash) (defaults to: {})

    the labeled strings to pack

Returns:

  • (Array<String, Hash>)

    the packed string and labeled offsets



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/macho/utils.rb', line 53

def self.pack_strings(fixed_offset, alignment, strings = {})
  offsets = {}
  next_offset = fixed_offset
  payload = +""

  strings.each do |key, string|
    offsets[key] = next_offset
    payload << string
    payload << Utils.nullpad(1)
    next_offset += string.bytesize + 1
  end

  payload << Utils.nullpad(padding_for(fixed_offset + payload.bytesize, alignment))
  [payload.freeze, offsets]
end

.padding_for(size, alignment) ⇒ Integer

Returns the number of bytes needed to pad the given size to the given alignment.

Parameters:

  • size (Integer)

    the unpadded size

  • alignment (Integer)

    the number to alignment the size with

Returns:

  • (Integer)

    the number of pad bytes required



23
24
25
# File 'lib/macho/utils.rb', line 23

def self.padding_for(size, alignment)
  round(size, alignment) - size
end

.round(value, round) ⇒ Integer

Rounds a value to the next multiple of the given round.

Parameters:

  • value (Integer)

    the number being rounded

  • round (Integer)

    the number being rounded with

Returns:

  • (Integer)

    the rounded value

See Also:



11
12
13
14
15
16
# File 'lib/macho/utils.rb', line 11

def self.round(value, round)
  round -= 1
  value += round
  value &= ~round
  value
end

.specialize_format(format, endianness) ⇒ String

Converts an abstract (native-endian) String#unpack format to big or little.

Parameters:

  • format (String)

    the format string being converted

  • endianness (Symbol)

    either :big or :little

Returns:

  • (String)

    the converted string



42
43
44
45
# File 'lib/macho/utils.rb', line 42

def self.specialize_format(format, endianness)
  modifier = endianness == :big ? ">" : "<"
  format.tr("=", modifier)
end