/* * $Id: postproc.c,v 1.5 2003/06/22 11:12:28 andrew_belov Exp $ * --------------------------------------------------------------------------- * This program stores the CRC and file size of ARJ.EXE in it, so an * integrity check may be performed with ARJ i. * */ #include "arj.h" /* Operations */ #define PP_NONE 0 /* No action */ #define PP_DEFAULT 1 /* Calculate and store the CRC */ #define PP_ARJSFX 2 /* Remove LZEXE signature */ /* Errorlevels/return codes. If something went wrong, look here */ #define POSTPROC_ERL_SUCCESS 0 #define POSTPROC_ERL_WARNING 1 /* Non-fatal error */ #define POSTPROC_ERL_CANTOPEN 2 /* Can't open file */ #define POSTPROC_ERL_BAD_EXE 3 /* Malformed EXE file */ #define POSTPROC_ERL_NO_INTEGR 4 /* Integrity pattern not found */ #define POSTPROC_ERL_CANT_WRITE 5 /* Data was not written */ /* Patterns in EXE files */ static unsigned char reg_crc_pattern[]={0xB0, 0x01, 0xB0, 0x02, 0xB0, 0x03, 0xB0, 0x04, 0xB0, 0x05, 0}; static unsigned char encryption_pattern[]={0xB0, 0x02, 0xB0, 0x02, 0xB0, 0x03, 0xB0, 0x04, 0xB0, 0x05, 0}; static unsigned char integrity_pattern[]={0xB0, 0x03, 0xB0, 0x02, 0xB0, 0x03, 0xB0, 0x04, 0xB0, 0x05, 0}; static unsigned short self_check[]={0x9090, 0x9090, 0x138, 0x9090, 0x9090}; /* Processing buffer */ static char buf[PROC_BLOCK_SIZE]; static void _fput_dword(const unsigned long l, FILE *stream) { #ifdef WORDS_BIGENDIAN fputc(l ,stream); fputc(l>>8 ,stream); fputc(l>>16,stream); fputc(l>>24,stream); #else fwrite(&l,4,1,stream); #endif } /* Standard postprocessing for ARJ and REARJ */ static int pp_default(FILE *stream) { int rp_len; long cur_pos, wr_pos; int bytes_read, byte_ctr; char *pb_ptr; long fsize; int c; fseek(stream, 0L, SEEK_END); fsize=ftell(stream); fseek(stream, 0L, SEEK_SET); rp_len=strlen((char *)integrity_pattern); cur_pos=0L; while(1) { fseek(stream, cur_pos, SEEK_SET); if((bytes_read=fread(buf, 1, PROC_BLOCK_SIZE, stream))==0) { printf("Patch not found\n"); return(POSTPROC_ERL_BAD_EXE); } bytes_read-=rp_len; pb_ptr=buf; byte_ctr=0; while(byte_ctr=0; p_len--) ; if(p_len>0) printf("Slack area is clogged (%u byte(s) remaining) - can't stamp the ARJSFX signature!\n", p_len+1); else { strcpy(buf+0x79, "aRJsfX"); fseek(stream, 0L, SEEK_SET); fwrite(buf, 1, 128, stream); printf("ARJSFX signature installed at offset 0x79\n"); } } #elif defined(SUNOS) /* Some "free" space in the ELF header ... Reliable? For Linux as well? Info: */ p_len=16; sig_found=0; if(fread(buf, 1, p_len, stream) [-sfx],\n" "Where: is the EXE name to patch,\n" " -sfx does ARJSFX postprocessing (packing and signing)\n" " e.g, to patch ARJ.EXE, type POSTPROC ARJ.EXE\n"); exit(POSTPROC_ERL_WARNING); } build_crc32_table(); /* Determine the type of post-processing */ if(argc==2) pp_type=PP_DEFAULT; else if(!strcmp(argv[2], "-sfx")) pp_type=PP_ARJSFX; /* Pack the SFX */ #ifndef NP_SFX if(pp_type==PP_ARJSFX) pack_sfx(argv[1]); #endif if((stream=fopen(argv[1], m_rbp))==NULL) { printf("Can't open %s\n", argv[1]); exit(POSTPROC_ERL_CANTOPEN); } /* Run the corresponding routine */ switch(pp_type) { case PP_DEFAULT: rc=pp_default(stream); break; case PP_ARJSFX: rc=pp_arjsfx(stream); break; default: printf("No postprocessing action specified\n"); rc=POSTPROC_ERL_WARNING; } fclose(stream); return(rc); }