Newsgroups: comp.os.msdos.djgpp Subject: Re: Licence management under DJGPP? Message-ID: <01bc9324$12fe6960$ed8033cf@pentium> From: "George Kinney" Date: 18 Jul 97 02:32:32 GMT References: Organization: The Unknown Programmers NNTP-Posting-Host: 207.51.128.237 Lines: 171 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk James MacDonald wrote in article ... > > I want to distribute my program as a full and an evaluation version. > Both would be the same EXE file, the same size, but one would be stamped > with a registration code and one would not. > > Perhaps the evaluation one would have REGREGREGREGREGEREG in it as a > placeholder for a code to turn it into a full one. Yes it is possible. just declare a const char[] holding the string in your code. then you can scan the exe for the string, and replace it. However, there are a couple of things to be wary of. DO NOT write past the end of the space you've reserved. (the EXE will likely bomb if you do. Not a good registration incentive) DO NOT compress the executable, or you are not going to find the string The code below is from the snippets collection, and is a simple file checksum generator. (to help ward against unauthorized changes, like viruses.) You should be able to pull the parts you need to do the find and replace deal in here. It's really not difficult. Not to mention it might be yet another useful addition to make. --------->8 Cut Here 8<------------------------------------------ #include #include #include #include /* This is the checksum self-test stuff DO NOT ATTEMPT TO USE THIS ON COMPRESSED EXECUTABLES!!!!!!!!!!!!!!! For obvious reasons, it will not work, and you're program will always fail the check. */ static struct { unsigned char marker[16]; unsigned long checksum; } marker_struct = {"CHECKEXE MARKER",0L}; /* Call this at program startup. The very first time it is called, it will calc the exe's checksum, and store it in the file. On every subsequent run, it will compare the calc'd checksum with the stored checksum. If they don't match, it aborts. (like if it's been infected or modified) From the c-snippets collection */ void checkexe(char *fname) { FILE *fptr; unsigned int c; int first_time = 0, i; char buffer[14]; unsigned long chksum = 0L; unsigned long l; unsigned long marker_offset; unsigned char *charptr; time_t tm; fptr = fopen(fname,"r+b"); if(fptr == NULL) { fprintf(stderr,"checkexe : unable to open input file '%s'\n", fname); exit(99); } setvbuf(fptr, NULL, _IOFBF, 32767); /* try to get a 32K buffer */ /* * If this is the first time the check has been run, scan the entire file * to find the marker. Otherwise proceed. */ if(marker_struct.checksum == 0L) { first_time = 1; c = fgetc(fptr); while(!feof(fptr)) { if(c == (unsigned int)marker_struct.marker[0]) { fread(buffer,sizeof(buffer),1,fptr); if(memcmp(buffer,&marker_struct.marker[1], sizeof(buffer)) == 0) { marker_offset = ftell(fptr) + 1L; break; } fseek(fptr,-13L,SEEK_CUR); } c = fgetc(fptr); } if(feof(fptr)) { fprintf(stderr,"checkexe : unable to locate marker\n"); exit(99); } /* Change the marker field to random values */ tm = time(NULL); srand((unsigned int)tm); for(i = 0 ; i < sizeof(marker_struct.marker) ; ++i) marker_struct.marker[i] = (unsigned char) rand(); fseek(fptr,marker_offset - sizeof(marker_struct.marker),SEEK_SET); fwrite(marker_struct.marker,sizeof(marker_struct.marker),1,fptr); } /* Calculate the checksum for the entire file */ rewind(fptr); c = fgetc(fptr); for(l = 0 ; !feof(fptr) ; ++l) { chksum += (unsigned long)c; c = fgetc(fptr); } if(first_time) { marker_struct.checksum = chksum; fseek(fptr,marker_offset,SEEK_SET); fwrite(&marker_struct.checksum,sizeof(unsigned long),1,fptr); } else { charptr = (unsigned char*) &marker_struct.checksum; for(i = 0 ; i < sizeof(marker_struct.checksum) ; ++i) chksum -= (unsigned long)(charptr[i]); if(chksum != marker_struct.checksum) { fprintf(stderr, "\acheckexe : %s has been altered, " "possibly by a virus\n", fname); exit(99); } } fclose(fptr); return; }