Files
ImHex-Patterns/patterns/nro.hexpat
Mrmaxmeier df97fc7257 patterns/includes: More misc cleanups (#353)
* patterns/zip: simplify find_sequence_in_range check

hex(340282366920938463463374607431768211455) =
0xffffffffffffffffffffffffffffffff

* patterns/7z: use Magic<> for signature, add pragma

* patterns/{nro, ogg}: use Magic<> for signature

* patterns/ttf: refactor, check magic

Use the "Field field @ position;" syntax instead of saving and restoring
the cursor position.

* readme: fix copy-paste error in pattern listing
2025-03-22 13:46:06 +01:00

77 lines
1.4 KiB
Rust

#pragma author WerWolv
#pragma description Nintendo Switch NRO
#pragma magic [ 4E 52 4F 30 ] @ 0x10
import std.io;
import std.sys;
import type.magic;
struct MOD0 {
char magic[4];
u32 dynamic_offset [[name(".dynamic offset")]];
u32 bss_start_offset [[name(".bss start offset")]];
u32 bss_end_offset [[name(".bss end offset")]];
u32 eh_frane_hdr_start_offset [[name(".eh_frame_hdr start offset")]];
u32 eh_frane_hdr_end_offset [[name(".eh_frame_hdr end offset")]];
u32 runtime_generated_module_object_offset;
};
struct Start {
padding[4];
MOD0 *mod0 : u32;
char hb_magic[8];
};
struct SegmentHeader {
u32 offset;
u32 size;
};
struct Header {
type::Magic<"NRO0"> magic;
u32 version;
u32 file_size;
u32 flags;
SegmentHeader segment_header_1[3];
u32 bss_size;
padding[4];
u8 module_id[0x20];
u32 dso_handle_offset;
padding[4];
SegmentHeader segment_header_2[3];
};
struct AssetSection {
u8 *asset_offset : u64 [[pointer_base("asset_ptr")]];
u64 size;
};
struct AssetHeader {
if (is_homebrew()) {
char magic[4];
u32 version;
AssetSection icon;
AssetSection nacp;
AssetSection romfs;
}
};
fn asset_ptr(u128 offset) {
return header.file_size;
};
fn is_homebrew() {
return start.hb_magic == "HOMEBREW";
};
Start start @ 0x00;
Header header @ $;
AssetHeader assets @ header.file_size;
fn main() {
if (is_homebrew())
std::print("This is a Homebrew NRO!");
};