Class: Nxo::NsoFile
Constant Summary collapse
- NSO_MAGIC =
"NSO0"- NSO_VERSION =
0
Constants inherited from NxoFile
Instance Attribute Summary collapse
-
#build_id ⇒ Object
readonly
Returns the value of attribute build_id.
-
#extents ⇒ Object
readonly
Returns the value of attribute extents.
-
#segments ⇒ Object
readonly
Returns the value of attribute segments.
Attributes inherited from NxoFile
Instance Method Summary collapse
-
#initialize(f, options = {}) ⇒ NsoFile
constructor
A new instance of NsoFile.
Methods inherited from NxoFile
#[], #bss, #data, #fs_sdk_versions, #name_heuristic, #rodata, #text
Constructor Details
#initialize(f, options = {}) ⇒ NsoFile
Returns a new instance of NsoFile.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/nxo/nso.rb', line 12 def initialize(f, = {}) @f = f @f.pos = 0 magic, version, flags = @f.read(0x10).unpack("a4L<x4L<") if magic != NSO_MAGIC then raise Error::InvalidMagicError.new(magic, NSO_MAGIC) end if version != NSO_VERSION then raise Error::UnknownVersionError.new(version, NSO_VERSION) end segment_headers = 3.times.map do Hash[[:file_offset, :memory_offset, :decompressed_size, :misc].zip(@f.read(0x10).unpack("L<L<L<L<"))] end module_offset, module_file_size, bss_size = segment_headers.map do |sh| sh[:misc] end @build_id = @f.read(0x20) @f.read(3 * 0x4).unpack("L<L<L<").each_with_index do |size, i| segment_headers[i][:compressed_size] = size end @f.pos = 0x88 @extents = Hash[[:api_info, :dynstr, :dynsym].zip(@f.read(0x18).unpack("Q<Q<Q<"))] @f.read(3 * 0x20).unpack("a32a32a32").each_with_index do |hash, i| segment_headers[i][:hash] = hash end location_counter = 0 segments = [:text, :rodata, :data].each_with_index.map do |name, i| sh = segment_headers[i] @f.pos = sh[:file_offset] contents = @f.read(sh[:compressed_size]) if flags[i] == 1 then # is compressed contents = LZ4::Raw.decompress(contents, sh[:decompressed_size])[0] end if flags[i+3] == 1 && ![:disable_hash_check] then # check hash if Digest::SHA256.digest(contents) != sh[:hash] then raise Error::HashCheckError.new(name) end end if sh[:memory_offset] < location_counter then raise Error::AddressMismatchError.new(name, sh[:memory_offset], location_counter) end location_counter = sh[:memory_offset] + contents.bytesize Segment.new(name, sh[:memory_offset], contents) end + [Segment.new("bss", location_counter, 0.chr * bss_size)] super(segments) end |
Instance Attribute Details
#build_id ⇒ Object (readonly)
Returns the value of attribute build_id.
73 74 75 |
# File 'lib/nxo/nso.rb', line 73 def build_id @build_id end |
#extents ⇒ Object (readonly)
Returns the value of attribute extents.
74 75 76 |
# File 'lib/nxo/nso.rb', line 74 def extents @extents end |
#segments ⇒ Object (readonly)
Returns the value of attribute segments.
75 76 77 |
# File 'lib/nxo/nso.rb', line 75 def segments @segments end |