home *** CD-ROM | disk | FTP | other *** search
- /* unlzexe.c
- * unlzexe ver 0.2 (PC-VAN UTJ44266 Kou )
- * UNLZEXE converts the compressed file by lzexe(ver.0.90,0.91) to the
- * UNcompressed executable one.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #define FAILURE 1
- #define SUCCESS 0
-
- typedef unsigned int WORD;
- typedef unsigned char BYTE;
-
-
- main(int argc,char **argv){
- int rdhead(FILE *,int *);
- void mkreltbl(FILE *,FILE *,int);
- void unpack(FILE *,FILE *);
- void wrhead(FILE *);
-
- FILE *ifile,*ofile;
- int ver;
-
- printf("UNLZEXE Ver. 0.2\n");
- if(argc!=3){
- printf("usage:UNLZEXE packedfile unpackedfile");
- exit(1);
- }
- if((ifile=fopen(argv[1],"rb"))==NULL){
- printf("'%s' :not found.",argv[1]);
- exit(1);
- }
-
- if(rdhead(ifile,&ver)!=SUCCESS){
- printf("'%s' is not LZEXE file.",argv[1]);
- }else {
- if((ofile=fopen(argv[2],"w+b"))==NULL){
- printf("'%s' :can't open.",argv[2]);
- fclose(ifile);
- exit(1);
- }
- printf("file '%s' is compressed by LZEXE Ver. ",argv[1]);
- switch(ver){
- case 90: printf("0.90\n"); break;
- case 91: printf("0.91\n"); break;
- }
- mkreltbl(ifile,ofile,ver);
- unpack(ifile,ofile);
- wrhead(ofile);
- fclose(ofile);
- printf("unpacked file '%s' is generated.\n",argv[2]);
- }
- fclose(ifile);
- }
-
- /*-------------------------------------------*/
- static WORD ihead[0x10],ohead[0x10],inf[8];
- static WORD allocsize;
- static long fpos,loadsize;
-
- /* EXE header test (is it LZEXE file?) */
- int rdhead(FILE *ifile ,int *ver){
- if(fread(ihead,sizeof ihead[0],0x10,ifile)!=0x10)
- return FAILURE;
- memcpy(ohead,ihead,sizeof ihead[0] * 0x10);
- if(ihead[0]!=0x5a4d || ihead[4]!=2 || ihead[0x0d]!=0)
- return FAILURE;
- if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ09",4)==0){
- *ver=90; return SUCCESS ;
- }
- if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ91",4)==0){
- *ver=91; return SUCCESS ;
- }
- return FAILURE;
- }
-
- /* make relocation table */
- void mkreltbl(FILE *ifile,FILE *ofile,int ver) {
- void reloc90();
- void reloc91();
- int i;
-
- allocsize=((ihead[1]+16-1)>>4) + ((ihead[2]-1)<<5) - ihead[4] + ihead[5];
- fpos=(long)(ihead[0x0b]+ihead[4])<<4; /* goto CS:0000 */
- fseek(ifile,fpos,SEEK_SET);
- fread(inf, sizeof inf[0], 0x08, ifile);
- ohead[0x0a]=inf[0]; /* IP */
- ohead[0x0b]=inf[1]; /* CS */
- ohead[0x08]=inf[2]; /* SP */
- ohead[0x07]=inf[3]; /* SS */
- /* inf[4]:size of compressed load module (PARAGRAPH)*/
- /* inf[5]:increase of load module size (PARAGRAPH)*/
- /* inf[6]:size of decompressor with compressed relocation table (BYTE) */
- /* inf[7]:check sum of decompresser with compressd relocation table(Ver.0.90) */
- ohead[0x0c]=0x1c; /* start position of relocation table */
- fseek(ofile,0x1cL,SEEK_SET);
- switch(ver){
- case 90: reloc90(ifile,ofile,fpos);
- break;
- case 91: reloc91(ifile,ofile,fpos);
- break;
- }
- i=ohead[3]*4+ohead[0x0c];
- ohead[4]=((i+0x1ff) & ~0x1ff)>>4;
-
- for(i=0x200-(i & 0x1ff); i>0; i--)
- putc(0, ofile);
- }
- /* for LZEXE ver 0.90 */
- void reloc90(FILE *ifile,FILE *ofile,long fpos) {
- unsigned int c;
- WORD rel_count=0;
- WORD rel_item[2]; /* [0]:offset, [1]:segment */
-
- fseek(ifile,fpos+0x19d,SEEK_SET);
- /* 0x19d=compressed relocation table address */
- for(rel_item[1]=0;rel_item[1]<0x10;rel_item[1]++) {
- if((c=getw(ifile))==0)
- continue;
- else {
- for(;c>0;c--) {
- rel_item[0]=getw(ifile);
- putw(rel_item[0],ofile);
- putw(rel_item[1],ofile);
- rel_count++;
- }
- }
- }
- ohead[3]=rel_count;
- }
- /* for LZEXE ver 0.91*/
- void reloc91(FILE *ifile,FILE *ofile,long fpos) {
- WORD span;
- WORD rel_count=0;
- WORD rel_item[2]; /* [0]:offset, [1]:segment */
-
- fseek(ifile,fpos+0x158,SEEK_SET);
- /* 0x158=compressed relocation table address */
- rel_item[0]=0; rel_item[1]=0;
- for(;;) {
- if((span=getc(ifile))==0) {
- span=getw(ifile);
- if(span==0){
- rel_item[1] += 0x0fff;
- continue;
- } else if(span==1){
- break;
- }
- }
- rel_item[0] += span;
- rel_item[1] += (rel_item[0] & ~0x0f)>>4;
- rel_item[0] &= 0x0f;
- putw(rel_item[0],ofile);
- putw(rel_item[1],ofile);
- rel_count++;
- }
- ohead[3]=rel_count;
- }
-
- /*---------------------*/
- typedef struct {
- FILE *fp;
- WORD buf;
- BYTE count;
- } bitstream;
-
- void initbits(bitstream *,FILE *);
- int getbit(bitstream *);
-
- /*---------------------*/
- /* decompressor routine */
- void unpack(FILE *ifile,FILE *ofile){
- int len;
- int span;
- long fpos;
- bitstream bits;
- static BYTE data[0x4500], *p=data;
-
- fpos=(long)(ihead[0x0b]-inf[4]+ihead[4])<<4;
- fseek(ifile,fpos,SEEK_SET);
- fpos=(long)ohead[4]<<4;
- fseek(ofile,fpos,SEEK_SET);
- initbits(&bits,ifile);
- printf(" unpacking. ");
- for(;;){
- if(p-data>0x4000){
- fwrite(data,sizeof data[0],0x2000,ofile);
- p-=0x2000;
- memcpy(data,data+0x2000,p-data);
- putchar('.');
- }
- if(getbit(&bits)) {
- *p++=getc(ifile);
- continue;
- }
- if(!getbit(&bits)) {
- len=getbit(&bits)<<1;
- len |= getbit(&bits);
- len += 2;
- span=getc(ifile) | 0xff00;
- } else {
- span=(BYTE)getc(ifile);
- len=getc(ifile);
- span |= ((len & ~0x07)<<5) | 0xe000;
- len = (len & 0x07)+2;
- if (len==2) {
- len=getc(ifile);
-
- if(len==0)
- break;
-
- if(len==1)
- continue; /* segment change */
- else
- len++;
- }
- }
- for( ;len>0;len--,p++){
- *p=*(p+span);
- }
- }
- if(p!=data)
- fwrite(data,sizeof data[0],p-data,ofile);
- loadsize=ftell(ofile)-fpos;
- printf("end\n");
- }
-
- /* write EXE header*/
- void wrhead(FILE *ofile) {
- if(ihead[6]!=0) {
- ohead[5]=allocsize-((loadsize+15)>>4);
- if(ihead[6]!=0xffff)
- ohead[6]-=(ihead[5]-ohead[5]);
- }
- ohead[1]=(loadsize+(ohead[4]<<4))&0x1ff;
- ohead[2]=(loadsize+(ohead[4]<<4)+0x1ff) >>9;
- fseek(ofile,0L,SEEK_SET);
- fwrite(ohead,sizeof ohead[0],0x0e,ofile);
- }
- /*-------------------------------------------*/
-
- /* get compress information bit by bit */
- void initbits(bitstream *p,FILE *filep){
- p->fp=filep;
- p->count=0x10;
- p->buf=getw(filep);
- /* printf("%04x ",p->buf); */
- }
-
- int getbit(bitstream *p) {
- int b;
- b = p->buf & 1;
- if(--p->count == 0){
- (p->buf)=getw(p->fp);
- /* printf("%04x ",p->buf); */
- p->count= 0x10;
- }else
- p->buf >>= 1;
-
- return b;
- }
-