From 190f9d891bea457ca80d0103e0d578ed7054f9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarkko=20P=C3=B6yry?= Date: Sat, 3 Jan 2026 21:24:31 +0200 Subject: [PATCH] patterns: Add ASCII CPIO patterns. (#473) --- README.md | 2 + patterns/cpio_new_ascii.hexpat | 46 ++++++++++++++++++ patterns/cpio_portable_ascii.hexpat | 41 ++++++++++++++++ .../test_data/cpio_new_ascii.hexpat.cpio | Bin 0 -> 512 bytes .../test_data/cpio_portable_ascii.hexpat.cpio | Bin 0 -> 289 bytes 5 files changed, 89 insertions(+) create mode 100644 patterns/cpio_new_ascii.hexpat create mode 100644 patterns/cpio_portable_ascii.hexpat create mode 100644 tests/patterns/test_data/cpio_new_ascii.hexpat.cpio create mode 100644 tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio diff --git a/README.md b/README.md index c90c17d..d7e2c0f 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | Chromium Pak | | [`patterns/chromium_pak.hexpat`](patterns/chromium_pak.hexpat) | Chromium pak file | | COFF | `application/x-coff` | [`patterns/coff.hexpat`](patterns/coff.hexpat) | Common Object File Format (COFF) executable | | CPIO | `application/x-cpio` | [`patterns/cpio.hexpat`](patterns/cpio.hexpat) | Old Binary CPIO Format | +| CPIO | | [`patterns/cpio_portable_ascii.hexpat`](patterns/cpio_portable_ascii.hexpat) | Portable ASCII CPIO Format | +| CPIO | | [`patterns/cpio_new_ascii.hexpat`](patterns/cpio_new_ascii.hexpat) | "New" ASCII CPIO Format | | CrashLvl | | [`patterns/Crashlvl.hexpat`](patterns/Crashlvl.hexpat) | Crash Bandicoot - Back in Time (fan game) User created level format | | CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format | | DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface | diff --git a/patterns/cpio_new_ascii.hexpat b/patterns/cpio_new_ascii.hexpat new file mode 100644 index 0000000..e85085d --- /dev/null +++ b/patterns/cpio_new_ascii.hexpat @@ -0,0 +1,46 @@ +#pragma author gunjambi +#pragma description "New" ASCII CPIO +#pragma magic [ 30 37 30 37 30 31 ] @ 0x00 + +import std.time; +import std.string; + +namespace new_ascii { + fn format_hex_time(str value) { + return std::time::format(std::time::to_utc(std::string::parse_int(value, 16))); + }; + fn parse_hex(str field) { + return std::string::parse_int(field, 16); + }; + + struct Cpio { + char c_magic[6]; + if (c_magic != "070701") { + std::error("Invalid CPIO Magic!"); + } + + char c_ino[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_mode[8]; + char c_uid[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_gid[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_nlink[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_mtime[8] [[format("new_ascii::format_hex_time")]]; + char c_filesize[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_devmajor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_devminor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_rdevmajor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_rdevminor[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_namesize[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + char c_check[8] [[format("new_ascii::parse_hex"), transform("new_ascii::parse_hex")]]; + + char filename[c_namesize - 1]; + padding[1]; + if (filename == "TRAILER!!!") + break; + padding[(4 - ((6 + c_namesize) % 4)) % 4]; + + u8 data[c_filesize]; + padding[(4 - (c_filesize % 4)) % 4]; + }; +} +new_ascii::Cpio cpio[while(true)] @ 0x00; diff --git a/patterns/cpio_portable_ascii.hexpat b/patterns/cpio_portable_ascii.hexpat new file mode 100644 index 0000000..50fe9ba --- /dev/null +++ b/patterns/cpio_portable_ascii.hexpat @@ -0,0 +1,41 @@ +#pragma author gunjambi +#pragma description Portable ASCII CPIO +#pragma magic [ 30 37 30 37 30 37 ] @ 0x00 + +import std.time; +import std.string; + +namespace portable_ascii { + fn format_octal_time(str value) { + return std::time::format(std::time::to_utc(std::string::parse_int(value, 8))); + }; + fn parse_octal_string(str field) { + return std::string::parse_int(field, 8); + }; + + struct Cpio { + char c_magic[6]; + if (c_magic != "070707") { + std::error("Invalid CPIO Magic!"); + } + + char c_dev[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_ino[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_mode[6]; + char c_uid[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_gid[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_nlink[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_rdev[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_mtime[11] [[format("portable_ascii::format_octal_time")]]; + char c_namesize[6] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + char c_filesize[11] [[format("portable_ascii::parse_octal_string"), transform("portable_ascii::parse_octal_string")]]; + + char filename[c_namesize - 1]; + padding[1]; + if (filename == "TRAILER!!!") + break; + + u8 data[c_filesize]; + }; +} +portable_ascii::Cpio cpio[while(true)] @ 0x00; diff --git a/tests/patterns/test_data/cpio_new_ascii.hexpat.cpio b/tests/patterns/test_data/cpio_new_ascii.hexpat.cpio new file mode 100644 index 0000000000000000000000000000000000000000..8d753db59eff6d7ac0b860b97b71d9e6b209362c GIT binary patch literal 512 zcmXpoH!wFaG%zqQGBI_v0MZ5)hE8T68VfKqvotleFm^M6$~i)4Hzx>f?21JXNC+;T zT9KGrkdvyPs8>=^!jPztoS#>cnpaZHzyNdw*d2z3j;;n^`w6OV literal 0 HcmV?d00001 diff --git a/tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio b/tests/patterns/test_data/cpio_portable_ascii.hexpat.cpio new file mode 100644 index 0000000000000000000000000000000000000000..dfaa037fbd0e1de187b0f29bd26e907a38df63d9 GIT binary patch literal 289 zcmXpoHvmBdFf=qUFf%hl2tZjtVGuAhH8e6cHZU|dGXZlE3Jr}?D-v@Ha#HmZ^-3yA z7!nnd^Ycnl^Gb@rHXz$!M3fyy1_q{JI}ln8jbU~qC4ntTO2TamNG~=3^$D7kp)ry` PNRXqak86;kq9OwTv~xhO literal 0 HcmV?d00001