From 2a8e13711ff3adeaed06ddd090b22150fbb95339 Mon Sep 17 00:00:00 2001 From: Colton Thomas Date: Thu, 16 Oct 2025 11:15:12 -0600 Subject: [PATCH] changed library class --- sign4j/linux/README.txt | 18 ++++ sign4j/linux/sign4j | Bin 0 -> 16952 bytes sign4j/linux/sign4j.c | 222 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 sign4j/linux/README.txt create mode 100755 sign4j/linux/sign4j create mode 100644 sign4j/linux/sign4j.c diff --git a/sign4j/linux/README.txt b/sign4j/linux/README.txt new file mode 100644 index 0000000..a05b644 --- /dev/null +++ b/sign4j/linux/README.txt @@ -0,0 +1,18 @@ +sign4j version 3.0 +------------------ + +sign4j is a very simple utility to digitally sign executables containing an appended jar file, like those created by launch4j. + +It works by first signing a temporary file to detect the size of the applied signature, and by then adding that size to a counter in the ZIP_END_HEADER of the embedded jar, so as to pretend that the signature is a comment belonging to it. That way the jar remains formally correct, and java accepts it. + +This manipulation must be done atomically with the signing process, because doing it before would invalidate the jar file, while doing it later would break the signature. That's why the whole command line of your signing tool must be passed to sign4j, which will do the job. + +Any signing tool can be used, as long as the name of the output file can be recognized among its parameters. This is currently done by either using an -out option if present, or taking the last filename with an exe suffix after all supplied options. + +If the involved tool is able to remove a previous signature before adding the new one (as is normally the case) the initial test can be performed on the target executable itself, avoiding the creation of a temporary file. You can use the option --onthespot to signal that to sign4j. + +The option --strict can be used to suppress the use of double quotes around parameters that strictly don't need them. The option --verbose shows diagnostics about intermediary steps of the process. + +This utility can also be used to sign normal executables, but then it will remember you that the file can be signed directly. + +Please send comments to bramfeld@diogen.de diff --git a/sign4j/linux/sign4j b/sign4j/linux/sign4j new file mode 100755 index 0000000000000000000000000000000000000000..b743a7a9857fcbf654d0c3adebad5c4bbd053b48 GIT binary patch literal 16952 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 +#include +#include +#include +#include +#include +#include +#include + +#define ZIP_END_HEADER "\x50\x4B\x05\x06" +#define END_HEADER_SIZE 22 +#define MAX_COMMENT_SIZE 0xFFFF +#define SWAP_BLOCK_SIZE (4 * 1024 * 1024) +#define TEST_FILE_NAME "sign4j_temporary.exe" +#define SIGN4J_VERSION "3.0" + +typedef unsigned char byte; + +char command[4096]; +byte* image = 0; + +void usage (void); +void quit (int rsn); +void clear (void); + +int main (int argc, char* argv[]) +{ + char bfr[2]; + char* inf; + char* outf; + char* trg; + byte* lmt; + long lng, ext, off, blck, sgm; + int fd, td; + int fnd, spt, unq, vrb, qts, cmn; + int i, j, n; + byte* p; + + inf = outf = 0, fnd = spt = unq = vrb = 0; + for (i = 1; i < argc && argv[i][0] == '-'; i++) + if (! strcmp (argv[i], "--onthespot")) + spt = 1; + else if (! strcmp (argv[i], "--strict")) + unq = 1; + else if (! strcmp (argv[i], "--verbose")) + vrb = 1; + j = i; + for (i = j + 1; i < argc; i++) + if (! strcmp (argv[i], "-in") && i < argc - 1) + inf = argv[++i], fnd = 1; + else if (! strcmp (argv[i], "-out") && i < argc - 1) + outf = argv[++i], fnd = 1; + else if (argv[i][0] == '-' || (argv[i][0] == '/' && strlen (argv[i]) < 5)) + (! fnd ? (inf = outf = 0) : 0); + else if (! fnd && (n = strlen (argv[i])) > 4 && ! strcasecmp (argv[i] + n - 4, ".exe")) + inf = outf = argv[i]; + if (! inf || ! outf) + usage (); + atexit (clear); + + if ((fd = open (inf, O_RDONLY)) < 0) + quit (1); + if ((lng = lseek (fd, 0, SEEK_END)) < 0) + quit (2); + blck = (lng > SWAP_BLOCK_SIZE ? SWAP_BLOCK_SIZE : lng); + if (! (image = (byte*) malloc (blck))) + quit (4); + sgm = (blck > END_HEADER_SIZE + MAX_COMMENT_SIZE ? END_HEADER_SIZE + MAX_COMMENT_SIZE : blck); + if (lseek (fd, -sgm, SEEK_END) < 0 || read (fd, image, sgm) != sgm) + quit (2); + for (p = image + sgm - END_HEADER_SIZE; p > image; p--) + if (! memcmp (p, ZIP_END_HEADER, 4) && ((p[END_HEADER_SIZE - 1] << 8) | p[END_HEADER_SIZE - 2]) == (image + sgm) - (p + END_HEADER_SIZE)) + break; + if (p > image) + { + off = lng - ((image + sgm) - (p + END_HEADER_SIZE - 2)); + cmn = (p[END_HEADER_SIZE - 1] << 8) | p[END_HEADER_SIZE - 2]; + + if (! spt && (inf == outf || ! strcmp (inf, outf))) + { + printf ("Making temporary file\n"); + if ((td = open (TEST_FILE_NAME, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) + quit (5); + if (lseek (fd, 0, SEEK_SET) < 0) + quit (2); + for (ext = lng; ext > 0; ext -= blck) + { + sgm = (ext > blck ? blck : ext); + if (read (fd, image, sgm) != sgm || write (td, image, sgm) != sgm) + quit (6); + } + close (td); + trg = TEST_FILE_NAME; + } + else + trg = outf; + close (fd); + + strcpy (command, " "); + for (i = j; i < argc; i++) + { + p = (argv[i] == outf ? trg : argv[i]); + qts = (! unq || strchr (p, 32)); + if (qts) + strcat (command, "\""); + strcat (command, p); + if (qts) + strcat (command, "\""); + strcat (command, " "); + } + if (! vrb) + strcat (command, " > /dev/null"); + system (command); + + if ((td = open (trg, O_RDONLY)) < 0) + quit (7); + if ((ext = lseek (td, 0, SEEK_END)) < 0) + quit (7); + close (td); + if ((cmn += ext - lng) < 0 || cmn > MAX_COMMENT_SIZE) + quit (8); + + if ((fd = open (inf, O_WRONLY)) < 0) + quit (1); + if (lseek (fd, off, SEEK_SET) < 0) + quit (3); + bfr[0] = cmn & 0xFF; + bfr[1] = (cmn >> 8) & 0xFF; + if (write (fd, bfr, 2) != 2) + quit (3); + close (fd); + } + else + { + close (fd); + printf ("You don't need sign4j to sign this file\n"); + } + + strcpy (command, " "); + for (i = j; i < argc; i++) + { + p = argv[i]; + qts = (! unq || strchr (p, 32)); + if (qts) + strcat (command, "\""); + strcat (command, p); + if (qts) + strcat (command, "\""); + strcat (command, " "); + } + return system (command); +} + + +void usage () +{ + printf ("\nThis is sign4j version " SIGN4J_VERSION "\n\n"); + printf ("Usage: sign4j [options] \n\n"); + printf (" * options:\n"); + printf (" --onthespot avoid the creation of a temporary file (your tool must be able to sign twice)\n"); + printf (" --strict supress the use of double quotes around parameters that strictly don't need them\n"); + printf (" --verbose show diagnostics about intermediary steps of the process\n"); + printf (" * arguments must specify verbatim the command line for your signing tool\n"); + printf (" * only one file can be signed on each invocation\n"); + exit (-1); +} + +void quit (int rsn) +{ + switch (rsn) + { + case 1: puts ("Could not open file\n"); break; + case 2: puts ("Could not read file\n"); break; + case 3: puts ("Could not write file\n"); break; + case 4: puts ("Not enough memory\n"); break; + case 5: puts ("Could not open temporary\n"); break; + case 6: puts ("Could not write temporary\n"); break; + case 7: puts ("Could not read target\n"); break; + case 8: puts ("Unsupported operation\n"); break; + } + exit (-1); +} + +void clear () +{ + if (access (TEST_FILE_NAME, 0) == 0) + remove (TEST_FILE_NAME); + if (image) + free (image); +}