From abbd25e7f6e19afaf4c09a8ee9184c7bf71f3d81 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Sun, 17 Nov 2024 07:54:29 -0500 Subject: [PATCH] patterns: Added Windows Notepad cache file pattern (#297) * Added Windows Notepad Cache file parser. * Fixed Notepad windowstate link in readme * Added a test file for notepad-cache.hexpat --- README.md | 3 +- patterns/notepad-cache.hexpat | 82 ++++++++++++++++++ .../test_data/notepad-cache.hexpat.bin | Bin 0 -> 417 bytes 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 patterns/notepad-cache.hexpat create mode 100644 tests/patterns/test_data/notepad-cache.hexpat.bin diff --git a/README.md b/README.md index 4a6ff877..c651d1aa 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | NBT | | [`patterns/nbt.hexpat`](patterns/nbt.hexpat) | Minecraft NBT format | | NE | | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields | | nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format | -| NotepadWindowState | | [`patterns/notepad-windowstate.hexpat`](patterns/notepad-windowstate.hexpat) | Windows 11 Notepad - Window State .bin file | +| NotepadCache | | [`patterns/notepad-cache.hexpat`](patterns/notepad-cache.hexpat) | Windows Notepad Cache | +| NotepadWindowState | | [`patterns/notepadwindowstate.hexpat`](patterns/notepadwindowstate.hexpat) | Windows 11 Notepad - Window State .bin file | | NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files | | NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC | | OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format | diff --git a/patterns/notepad-cache.hexpat b/patterns/notepad-cache.hexpat new file mode 100644 index 00000000..cb7b0395 --- /dev/null +++ b/patterns/notepad-cache.hexpat @@ -0,0 +1,82 @@ +#pragma author sethhall +#pragma description Windows Notepad Cache Files + +// This was written based on the following blog post: +// https://u0041.co/posts/articals/exploring-windows-artifacts-notepad-files/ + +import type.leb128; +import type.time; +import type.magic; +import std.time; + +using uLEB128 = type::uLEB128; + +enum Encodings: u8 { + ANSI = 0x01, + UTF_16LE = 0x02, + UTF_16BE = 0x03, + UTF_8BOM = 0x04, + UTF_8 = 0x05, +}; + +enum LineEndings: u8 { + CRLF = 0x01, + CR = 0x02, + LF = 0x03, +}; + +struct ConfigBlock { + bool word_wrap; + bool rtl; + bool show_unicode; + uLEB128 version; + u16 unknown; +}; + +struct UnsavedChunk { + uLEB128 cursor_position; + uLEB128 deletion_number; + uLEB128 addition_number; + char16 chars[addition_number]; + char crc32[4] [[format("hash_format"), comment("CRC32 hash of the entire unsaved chunk structure")]]; +}; + +struct Notepad_File { + type::Magic<"NP\0"> signature [[comment("File signature")]]; + bool is_saved; + if ( is_saved ) { + uLEB128 path_length; + char16 path[path_length] [[comment("Path of saved file on disk")]]; + uLEB128 file_size; + Encodings encoding; + LineEndings line_endings; + uLEB128 last_write [[format("format_filetime")]]; + char sha256[32] [[format("hash_format")]]; + u8 unknown1; + } + u8 unknown2; + uLEB128 selection_start; + uLEB128 selection_end; + ConfigBlock config_block; + type::uLEB128 content_length; + char16 content[content_length]; + bool contain_unsaved_data; + char crc32[4] [[format("hash_format")]]; + UnsavedChunk unsaved_chunks[while(!std::mem::eof())]; +}; + +fn hash_format(auto bytes) { + str hash_hex; + for(u8 i=0, i < sizeof(bytes), i+=1) { + hash_hex = hash_hex + std::format("{:02X}",bytes[i]); + } + return hash_hex; +}; + +fn format_filetime(uLEB128 data) { + // We will only support dates back to the epoch + std::time::Time time64 = std::time::to_utc((data / 10000000.0) - 11644473600.0); + return std::time::format(time64, "%c"); +}; + +Notepad_File file @ $; \ No newline at end of file diff --git a/tests/patterns/test_data/notepad-cache.hexpat.bin b/tests/patterns/test_data/notepad-cache.hexpat.bin new file mode 100644 index 0000000000000000000000000000000000000000..9a3d62fd1c85ac8acf4ff5deb02dfc2c0cd4bedd GIT binary patch literal 417 zcmeYZU|>{pX0T$2VF+i)WXNMkVaR7FXD9~pLl{ySav2JMtURDt36NL7kO-8IXGjC8 z%mMO2szBn!KvEBgD}Y#?mGSzQ*O&e`?taU7hqp|^;F15cve!>Jwl(ow__^x3LEHz= z30Ji3UxY90S;N4nuFlB7z{JR?9>S0TG_;sO0ZJwUSump&;1=qDMPVvo&VcDD20E_{ z=$sS=2Av5(j3Ep!+7kC`GB9Q^EE6^SpvAzL$?#)cRiZWnV=+VN z>G$-tP%AZ{*eZN