Skip to content

Commit 7f80b2d

Browse files
Added :endian option to MachOStructure#field
Now instead of having types that dictated endianness like :uint32_net endianness is just an option passed to the field method. Ex. field name, :uint64, :endian => :big I also moved the utils.rb file to the top of the includes in the macho.rb file to access Utils#specialize_format in the #field method. I also changed the :bin_string field type to :binary to make it more succinct.
1 parent fea8132 commit 7f80b2d

File tree

4 files changed

+31
-28
lines changed

4 files changed

+31
-28
lines changed

lib/macho.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require "open3"
44

5+
require_relative "macho/utils"
56
require_relative "macho/structure"
67
require_relative "macho/view"
78
require_relative "macho/headers"
@@ -10,7 +11,6 @@
1011
require_relative "macho/macho_file"
1112
require_relative "macho/fat_file"
1213
require_relative "macho/exceptions"
13-
require_relative "macho/utils"
1414
require_relative "macho/tools"
1515

1616
# The primary namespace for ruby-macho.

lib/macho/headers.rb

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,10 @@ module Headers
505505
# @see MachO::FatArch
506506
class FatHeader < MachOStructure
507507
# @return [Integer] the magic number of the header (and file)
508-
field :magic, :uint32_net
508+
field :magic, :uint32, :endian => :big
509509

510510
# @return [Integer] the number of fat architecture structures following the header
511-
field :nfat_arch, :uint32_net
511+
field :nfat_arch, :uint32, :endian => :big
512512

513513
# @return [String] the serialized fields of the fat header
514514
def serialize
@@ -532,19 +532,19 @@ def to_h
532532
# @see MachO::Headers::FatHeader
533533
class FatArch < MachOStructure
534534
# @return [Integer] the CPU type of the Mach-O
535-
field :cputype, :uint32_net
535+
field :cputype, :uint32, :endian => :big
536536

537537
# @return [Integer] the CPU subtype of the Mach-O
538-
field :cpusubtype, :uint32_net, :mask => CPU_SUBTYPE_MASK
538+
field :cpusubtype, :uint32, :endian => :big, :mask => CPU_SUBTYPE_MASK
539539

540540
# @return [Integer] the file offset to the beginning of the Mach-O data
541-
field :offset, :uint32_net
541+
field :offset, :uint32, :endian => :big
542542

543543
# @return [Integer] the size, in bytes, of the Mach-O data
544-
field :size, :uint32_net
544+
field :size, :uint32, :endian => :big
545545

546546
# @return [Integer] the alignment, as a power of 2
547-
field :align, :uint32_net
547+
field :align, :uint32, :endian => :big
548548

549549
# @return [String] the serialized fields of the fat arch
550550
def serialize
@@ -572,13 +572,13 @@ def to_h
572572
# @see MachO::Headers::FatHeader
573573
class FatArch64 < FatArch
574574
# @return [Integer] the file offset to the beginning of the Mach-O data
575-
field :offset, :uint64_net
575+
field :offset, :uint64, :endian => :big
576576

577577
# @return [Integer] the size, in bytes, of the Mach-O data
578-
field :size, :uint64_net
578+
field :size, :uint64, :endian => :big
579579

580580
# @return [void]
581-
field :reserved, :uint32_net, :default => 0
581+
field :reserved, :uint32, :endian => :big, :default => 0
582582

583583
# @return [String] the serialized fields of the fat arch
584584
def serialize
@@ -733,31 +733,31 @@ def to_h
733733
# Prelinked kernel/"kernelcache" header structure
734734
class PrelinkedKernelHeader < MachOStructure
735735
# @return [Integer] the magic number for a compressed header ({COMPRESSED_MAGIC})
736-
field :signature, :uint32_net
736+
field :signature, :uint32, :endian => :big
737737

738738
# @return [Integer] the type of compression used
739-
field :compress_type, :uint32_net
739+
field :compress_type, :uint32, :endian => :big
740740

741741
# @return [Integer] a checksum for the uncompressed data
742-
field :adler32, :uint32_net
742+
field :adler32, :uint32, :endian => :big
743743

744744
# @return [Integer] the size of the uncompressed data, in bytes
745-
field :uncompressed_size, :uint32_net
745+
field :uncompressed_size, :uint32, :endian => :big
746746

747747
# @return [Integer] the size of the compressed data, in bytes
748-
field :compressed_size, :uint32_net
748+
field :compressed_size, :uint32, :endian => :big
749749

750750
# @return [Integer] the version of the prelink format
751-
field :prelink_version, :uint32_net
751+
field :prelink_version, :uint32, :endian => :big
752752

753753
# @return [void]
754-
field :reserved, :bin_string, :size => 40, :unpack => "L>10"
754+
field :reserved, :binary, :size => 40, :unpack => "L>10"
755755

756756
# @return [void]
757-
field :platform_name, :bin_string, :size => 64
757+
field :platform_name, :binary, :size => 64
758758

759759
# @return [void]
760-
field :root_path, :bin_string, :size => 256
760+
field :root_path, :binary, :size => 256
761761

762762
# @return [Boolean] whether this prelinked kernel supports KASLR
763763
def kaslr?

lib/macho/load_commands.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def initialize(endianness, alignment)
367367
# LC_UUID.
368368
class UUIDCommand < LoadCommand
369369
# @return [Array<Integer>] the UUID
370-
field :uuid, :bin_string, :size => 16, :unpack => "C16"
370+
field :uuid, :binary, :size => 16, :unpack => "C16"
371371

372372
# @return [String] a string representation of the UUID
373373
def uuid_string

lib/macho/structure.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@ module Fields
1515
# @api private
1616
BYTE_SIZE = {
1717
# Binary slices
18-
:bin_string => nil,
18+
:binary => nil,
1919
:string => nil,
2020
:int32 => 4,
2121
:uint32 => 4,
22-
:uint32_net => 4,
2322
:uint64 => 8,
24-
:uint64_net => 8,
2523
# Classes
2624
:view => 0,
2725
:lcstr => 4,
@@ -38,13 +36,11 @@ module Fields
3836
# @api private
3937
FORMAT_CODE = {
4038
# Binary slices
41-
:bin_string => "a",
39+
:binary => "a",
4240
:string => "Z",
4341
:int32 => "l=",
4442
:uint32 => "L=",
45-
:uint32_net => "L>", # Same as N
4643
:uint64 => "Q=",
47-
:uint64_net => "Q>",
4844
# Classes
4945
:view => "",
5046
:lcstr => "L=",
@@ -137,10 +133,12 @@ def inherited(subclass) # rubocop:disable Lint/MissingSuper
137133
# :unpack [String] string format
138134
# :default [Value] default value
139135
# :to_s [Boolean] flag for generating #to_s
136+
# :endian [Symbol] optionally specify :big or :little endian
140137
# @api private
141138
def field(name, type, **options)
142139
raise ArgumentError, "Invalid field type #{type}" unless Fields::FORMAT_CODE.key?(type)
143140

141+
# Get field idx for size_list and fmt_list
144142
idx = if @field_idxs.key?(name)
145143
@field_idxs[name]
146144
else
@@ -151,8 +149,13 @@ def field(name, type, **options)
151149
@field_idxs.size - 1
152150
end
153151

152+
# Add to size_list and fmt_list
154153
@size_list[idx] = Fields::BYTE_SIZE[type] || options[:size]
155-
@fmt_list[idx] = Fields::FORMAT_CODE[type]
154+
@fmt_list[idx] = if options[:endian]
155+
Utils.specialize_format(Fields::FORMAT_CODE[type], options[:endian])
156+
else
157+
Fields::FORMAT_CODE[type]
158+
end
156159
@fmt_list[idx] += options[:size].to_s if options.key?(:size)
157160

158161
# Generate methods

0 commit comments

Comments
 (0)