logo

deblob

remove binary executables from a directory git clone https://anongit.hacktivis.me/git/deblob.git/
commit: fa7a501dc77a11a96d5c73ad9a69feecbe01a398
parent ca7c71ba82abfdfa5fa2fdf4632bf6d50d10148f
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Tue, 30 Sep 2025 22:23:35 +0200

Java JAR detection: Check for extra field properly and META-INF/*

Diffstat:

MREADME.md8+++++++-
Mdeblob.12+-
Mmain.ha37+++++++++++++++++++++++++++++++++----
3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md @@ -8,6 +8,12 @@ See the `deblob.1` manpage for more information. Project permalink: <https://hacktivis.me/projects/deblob> +## Tarballs +- deblob: <https://distfiles.hacktivis.me/releases/deblob/> +- deblob-test: <https://distfiles.hacktivis.me/releases/deblob-test/> + +Signify public keys at <https://distfiles.hacktivis.me/releases/signify/> + ## Dependencies ### Common - hare 0.24+ @@ -16,7 +22,7 @@ Project permalink: <https://hacktivis.me/projects/deblob> ### tests - `ar` - C Compiler -- [deblob-test](https://hacktivis.me/git/deblob-test/) as submodule +- [deblob-test](https://hacktivis.me/git/deblob-test/) either as submodule or tarball version 0.11 ### linting Those are only needed during development. diff --git a/deblob.1 b/deblob.1 @@ -168,7 +168,7 @@ to hare as "deblob". Generic formats and executables based on them: .Bl -dash -compact .It -Generic Archives: Tarballs, Distro Packages, ZIP (including Java\~Jar), Cabinet (CAB), Microsoft Compound File (including MSI), … +Generic Archives: Tarballs, Distro Packages, ZIP, Cabinet (CAB), Microsoft Compound File (including MSI), … .It Filesystems, disk dumps, databases .El diff --git a/main.ha b/main.ha @@ -88,6 +88,7 @@ const racket: []u8 = ['r', 'a', 'c', 'k', 'e', 't']; const zip: []u8 = ['P', 'K', 0x03, 0x04]; const jar: []u8 = [0xFE, 0xCA, 0, 0]; const shebang: []u8 = ['#', '!']; +const meta_inf_: []u8 = ['M', 'E', 'T', 'A', '-', 'I', 'N', 'F', '/']; let found: bool = false; let json_out: io::handle = 0; @@ -163,8 +164,26 @@ fn id_blob(filename: str) (void | str | fs::error | io::error) = { }; if (bytes::hasprefix(buffer, zip)) { - if(bytes::equal(jar, buffer[0x27..0x2B])) { - return "Java JAR"; + // Check first filename + // Optional in JAR and probably doesn't have to be the first filename + // but it's how it's usually done + // + // So far seen either META-INF/ and \xFE\xCA\x00\x00 in extra or just META-INF/MANIFEST.MF + + const fname_len = endian::legetu16(buffer[0x1A..0x1C]); + if(fname_len < 256) + { + const fname_start = 0x1Eu16; + if(fname_len >= 9 && bytes::equal(meta_inf_, buffer[fname_start..fname_start+9])) { + return "Java JAR"; + }; + + const extra_start = fname_start+fname_len; + const extra_len = endian::legetu16(buffer[0x1D..0x1E]); + if(extra_len == 4 && bytes::equal(jar, buffer[extra_start..extra_start+extra_len])) + { + return "Java JAR"; + }; }; }; @@ -383,7 +402,12 @@ fn check_dir(dirname: str) (void | nomem | errors::invalid | io::error) = { case nomem => fmt::fatal("deblob: error: os::readdir({}): Out of Memory", dirname); }; - assert(len(files_before) == 61); + + const files_before_exp = 63z; + if(len(files_before) != files_before_exp) + { + fmt::fatalf("deblob: expected {} in files_before, got {}\n", files_before_exp, len(files_before)); + }; const ret = check_dir(dirname); assert(ret is void); @@ -396,7 +420,12 @@ fn check_dir(dirname: str) (void | nomem | errors::invalid | io::error) = { case nomem => fmt::fatal("deblob: error: os::readdir({}): Out of Memory", dirname); }; - assert(len(files_after) == 30); + + const files_after_exp = 31z; + if(len(files_after) != files_after_exp) + { + fmt::fatalf("deblob: expected {} in files_before, got {}\n", files_after_exp, len(files_after)); + }; }; export fn main() void = {