void taus_set_from_state (UINT32 * state, UINT32 * state0) { state[0] = state0[0] | (UINT32) 0x03; state[1] = state0[1] | (UINT32) 0x09; state[2] = state0[2] | (UINT32) 0x17; /* 'warm up' */ taus_get_long (state); taus_get_long (state); taus_get_long (state); taus_get_long (state); taus_get_long (state); taus_get_long (state); return; }
int main(int argc, char *argv[]) { int file; unsigned long i = argc; /* dummy use of argc to fix compiler warning */ unsigned long len = 0; struct stat sbuf; struct stat fbuf; /* For compression. */ lzo_byte * inbuf; lzo_byte * outbuf; int r; lzo_uint in_len; lzo_uint out_len; char * p; char fname[128]; #if defined (__linux__) char pname[128]; #endif UINT32 pid; /* no SUID */ if (getuid() != geteuid()) { setuid(getuid()); } /* reset umask */ umask(0); astate[0] = programkey_0[0]; astate[1] = programkey_0[1]; astate[2] = programkey_0[2]; taus_set_from_state (cstate, astate); out_len = (unsigned long) programlen_compressed_0; len = (unsigned long) programlen_0; outbuf = program_0; /* Decode. */ for (i = 0; i < out_len; ++i) { outbuf[i] ^= (taus_get_long (cstate) & 0xff); } inbuf = (lzo_byte *) malloc (sizeof(lzo_byte) * len); /* * Step 1: initialize the LZO library */ if (lzo_init() != LZO_E_OK) { return 1; } /* * Step 2: decompress again, now going from `out' to `in' */ r = lzo1x_decompress_safe (outbuf, out_len, inbuf, &in_len, NULL); if (r == LZO_E_OK && in_len == len) { /* printf("decompressed %lu bytes back into %lu bytes\n", (long) out_len, (long) in_len); */ ; } else { /* printf("internal error - decompression failed: %d\n", r); */ return 2; } /* * Step 3: choose a filename */ nameIt: p = fname; /* --- use /tmp if the sticky bit is set --- */ #if defined(S_ISVTX) set4 (p, '/', 't', 'm', 'p'); p += 4; *p = '\0'; if ( 0 != stat(fname, &sbuf)) { if ( (sbuf.st_mode & S_ISVTX) != S_ISVTX) { p = fname; set4 (p, '/', 'u', 's', 'r'); p += 4; set4 (p, '/', 'b', 'i', 'n'); p += 4; } } #else set4 (p, '/', 'u', 's', 'r'); p += 4; set4 (p, '/', 'b', 'i', 'n'); p += 4; #endif set4 (p, '/', 't', 'm', 'p'); p += 4; cstate[0] ^= (UINT32) getpid (); cstate[1] ^= (UINT32) time (NULL); cstate[0] |= (UINT32) 0x03; cstate[1] |= (UINT32) 0x09; pid = (UINT32) (taus_get_long (cstate) ^ taus_get_long (cstate)); for (i = 0; i < 4; ++i) { *p = 'a' + (pid % 26); pid /= 26; ++p; } pid = (UINT32) (taus_get_long (cstate) ^ taus_get_long (cstate)); for (i = 0; i < 4; ++i) { *p = 'a' + (pid % 26); pid /= 26; ++p; } pid = (UINT32) (taus_get_long (cstate) ^ taus_get_long (cstate)); for (i = 0; i < 3; ++i) { *p = 'a' + (pid % 26); pid /= 26; ++p; } *p = '\0'; if ( (-1) != stat(fname, &sbuf) || errno != ENOENT) { /* because cstate[2] is not initialized, the next name will * be different */ goto nameIt; } if ((file = open (fname, O_CREAT|O_EXCL|O_WRONLY, 0700)) < 0) { return (4); } write(file, inbuf, in_len); #if defined(__linux__) if ( 0 != fstat(file, &sbuf)) { return (5); } /* Must reopen for read only. */ close(file); file = open (fname, O_RDONLY, 0); if ( 0 != fstat(file, &fbuf)) { return (6); } /* check mode, inode, owner, and device, to make sure it is the same file */ if (sbuf.st_mode != fbuf.st_mode || sbuf.st_ino != fbuf.st_ino || sbuf.st_uid != fbuf.st_uid || sbuf.st_gid != fbuf.st_gid || sbuf.st_dev != fbuf.st_dev ) { close ( file ); return ( 6 ); } p = pname; set4(p, '/', 'p', 'r', 'o'); p += 4; set2(p, 'c', '/'); p += 2; set4(p, 's', 'e', 'l', 'f'); p += 4; set4(p, '/', 'f', 'd', '/'); p += 4; sprintf(p, "%d", file); if (0 == access(pname, R_OK|X_OK)) { unlink (fname); fcntl (file, F_SETFD, FD_CLOEXEC); execve (pname, argv, environ); return (8); } #endif /* /proc not working, or not linux */ close (file); if ( (i = fork()) != 0) { wait (NULL); execve (fname, argv, environ); unlink (fname); return (9); } else if (i == 0) { if (0 == fork()) { sleep (3); unlink (fname); } return (0); } /* only reached in case of error */ unlink (fname); return (-1); }
int main(int argc, char * argv[]) { FILE * fd; unsigned long clen; char * data; struct stat sbuf; char * ptest; unsigned long i; int status; unsigned long len = 0; unsigned long have = 0; /* For compression. */ lzo_byte * inbuf; lzo_byte * outbuf; int r; lzo_uint in_len; lzo_uint out_len; UINT32 len_raw; UINT32 len_cmp; astate[0] = EXEPACK_STATE_0; astate[1] = EXEPACK_STATE_1; astate[2] = EXEPACK_STATE_2; if (argc < 4) { fprintf(stderr, "Usage: exepack_fill <container_file> <infile> <outfile>\n"); exit (EXIT_FAILURE); } if (0 != stat (argv[1], &sbuf)) { fprintf(stderr, "exepack_fill: could not access file %s\n", argv[1]); return (-1); } clen = sbuf.st_size; data = (char *) malloc (clen * sizeof(char)); if (data == NULL) return (-1); fd = fopen (argv[1], "r"); if (fd == NULL) return (-1); if (clen != fread (data, 1, clen, fd)) return (-1); fclose (fd); /******************* * * THE DATA * *******************/ if (stat (argv[2], &sbuf) < 0) { perror ("exepack_fill"); exit (EXIT_FAILURE); } len = (unsigned long) sbuf.st_size; /* Because the input block may be incompressible, * we must provide a little more output space in case that compression * is not possible. */ inbuf = (lzo_byte *) malloc (sizeof(lzo_byte) * len); outbuf = (lzo_byte *) malloc (sizeof(lzo_byte) * (len + len / 64 + 16 + 3)); in_len = len; if (NULL == inbuf || NULL == outbuf) { fprintf(stderr, "exepack_fill: Out of memory."); exit (EXIT_FAILURE); } if (NULL == (fd = fopen(argv[2], "r"))) { perror ("exepack_fill"); exit (EXIT_FAILURE); } have = fread (inbuf, 1, len, fd); fclose (fd); if (have != len) { fprintf (stderr, "exepack_mkdata: Error reading %s", argv[2]); exit (EXIT_FAILURE); } /* * Step 1: initialize the LZO library */ if (lzo_init() != LZO_E_OK) { fprintf(stderr, "exepack_fill: lzo_init() failed\n"); return 3; } /* * Step 3: compress from `in' to `out' with LZO1X-1 */ r = lzo1x_1_compress(inbuf, in_len, outbuf, &out_len, wrkmem); if (r == LZO_E_OK) printf("exepack_fill: compressed %lu bytes into %lu bytes\n", (long) in_len, (long) out_len); else { /* this should NEVER happen */ printf("exepack_fill: internal error - compression failed: %d\n", r); return 2; } /* check for an incompressible block */ if (out_len >= in_len) { printf("exepack_fill: Incompressible data.\n"); } taus_set_from_state (cstate, astate); for (i = 0; i < out_len; ++i) { outbuf[i] ^= (taus_get_long (cstate) & 0xff); } len_raw = in_len; len_cmp = out_len; if ( (unsigned long) len_cmp > (unsigned long) clen) { printf("exepack_fill: Compressed length (%ld) exceeds container length (%ld).\n", (long) len_cmp, (long) clen); return (8); } /*********** * * Fill program * **********/ status = replaceData (data, clen, "LLLL", (char *) &len_raw, sizeof(UINT32)); if (status < 0) { printf("exepack_fill: Could not write raw lenght %d.\n", len_raw); return (8); } status = replaceData (data, clen, "CCCC", (char *) &len_cmp, sizeof(UINT32)); if (status < 0) { printf("exepack_fill: Could not write compressed lenght %d.\n", len_cmp); return (8); } status = replaceData (data, clen, "CONTAINER", (char *) outbuf, out_len); if (status < 0) { printf("exepack_fill: Could not write program data.\n"); return (8); } /*********** * * Write program * **********/ if ( NULL == (fd = fopen(argv[3], "w" ))) { perror ("exepack_fill"); exit (EXIT_FAILURE); } fwrite (data, 1, clen, fd); fclose (fd); ptest = my_locate("LLLL", data, clen); if (ptest != NULL) { printf("exepack_fill: ERROR: program length not updated.\n"); return (8); } ptest = my_locate("CCCC", data, clen); if (ptest != NULL) { printf("exepack_fill: ERROR: compressed program length not updated.\n"); return (8); } ptest = my_locate("CONTAINER", data, clen); if (ptest != NULL) { printf("exepack_fill: ERROR: program data not updated.\n"); return (8); } return 0; }