Difference between revisions of "NSO"

From Nintendo Switch Brew
Jump to navigation Jump to search
Line 97: Line 97:
 
|
 
|
 
| Compressed sections
 
| Compressed sections
 +
|}
 +
 +
Most data in Switch binaries are standard ELF structures, however some are custom.
 +
For example, the MOD header is essentially a replacement for a PT_DYNAMIC program header.
 +
 +
=== MOD ===
 +
All offsets are signed 32bit values relative to the magic field.
 +
The 32bits at image base + 4 must point to the magic field.
 +
The MOD structure is designed such that it can be placed at image base and point to itself.
 +
The 2 fields preceding the magic field get copied around with the structure, even if it is relocated to somewhere besides the image base.
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x00
 +
| 4
 +
| zero padding
 +
|-
 +
| 0x04
 +
| 4
 +
| offset to magic. Always 8 (so it works when MOD is at image_base + 0).
 +
|-
 +
| 0x08
 +
| 4
 +
| magic "MOD0"
 +
|-
 +
| 0x0C
 +
| 4
 +
| .dynamic offset
 +
|-
 +
| 0x10
 +
| 4
 +
| .bss start offset
 +
|-
 +
| 0x14
 +
| 4
 +
| .bss end offset
 +
|-
 +
| 0x18
 +
| 4
 +
| .eh_frame start offset
 +
|-
 +
| 0x1C
 +
| 4
 +
| .eh_frame end offset
 +
|-
 +
| 0x20
 +
| 4
 +
| offset to runtime-generated module object. typically equal to .bss base.
 
|}
 
|}

Revision as of 23:51, 3 July 2017

NSO is the main executable format.

It starts with the "NSO" header and mainly describes .text, .rodata, and .data segments (like a short-form of ELF program headers):

SegmentHeader

Offset Size Description
0x0 4 file offset of data
0x4 4 memory offset loaded to
0x8 4 size of data copied to memory offset (i.e. size after decompression)
0xC 4 alignment used on memory size / size of .bss in the case of .data segment

.rodata-relative extent

Offset Size Description
0x0 4 offset (relative to .rodata)
0x4 4 size of region

NSO Header

Offset Size Description
0x0 4 Magic "NSO0"
0x4 4
0x8 4
0xC 4 Always 0x3f?
0x10 0x10 * 3 SegmentHeader for each segment
0x40 0x20 Value of "build id" from ELF's GNU .note section. Contains variable sized digest, up to 32bytes.
0x60 0x4 * 3 file size of each segment (i.e. LZ4-compressed size)
0x6c 0x24 Padding
0x90 8 .rodata-relative extents of .dynstr
0x98 8 .rodata-relative extents of .dynsym
0xA0 0x20 * 3 SHA256 hashes over the decompressed sections using the above byte-sizes: .text, .rodata, and .data.
0x100 Compressed sections

Most data in Switch binaries are standard ELF structures, however some are custom. For example, the MOD header is essentially a replacement for a PT_DYNAMIC program header.

MOD

All offsets are signed 32bit values relative to the magic field. The 32bits at image base + 4 must point to the magic field. The MOD structure is designed such that it can be placed at image base and point to itself. The 2 fields preceding the magic field get copied around with the structure, even if it is relocated to somewhere besides the image base.

Offset Size Description
0x00 4 zero padding
0x04 4 offset to magic. Always 8 (so it works when MOD is at image_base + 0).
0x08 4 magic "MOD0"
0x0C 4 .dynamic offset
0x10 4 .bss start offset
0x14 4 .bss end offset
0x18 4 .eh_frame start offset
0x1C 4 .eh_frame end offset
0x20 4 offset to runtime-generated module object. typically equal to .bss base.