Path: utzoo!attcan!uunet!cs.utexas.edu!mailrus!ncar!mephisto!mcnc!duke!romeo!drh From: drh@romeo.cs.duke.edu (D. Richard Hipp) Newsgroups: comp.lang.c Subject: Re: C obfuscator (Obfuscator code attached) Message-ID: <19858@duke.cs.duke.edu> Date: 29 May 90 13:24:27 GMT Sender: news@duke.cs.duke.edu Reply-To: drh@duke.cs.edu Lines: 51 The program below reads a C program from standard input, strips away all unnecessary white space and writes the results to standard output. The result is a program which has been obfuscated. Unfortunately, this technique is probably not adequate for a secure source code distribution, since "cb" will unravel everything into a nicely indented program again. To make things really incomprehensible, one needs to change local identifiers to weird strings like "__X__88s", rewrite control structures as goto's, insert "red herring" code, and so forth. Such radical changes will require a complete parse of the input program, however, and this is more than I want to tackle right now. BTW: the program obfuscates itself without error, but I can still almost promise you that it has bugs. Use with care. -------------------------------- Cut Here ----------------------------------- #include #include #include typedef enum{WHITE,ID,STRING,OP,NL}tokentype;int putx(x)char*x;{static int ccnt=0;if(x==0){if(ccnt)printf("\n");ccnt=0;}else{ccnt+=strlen(x);if( ccnt>70&&isalnum(*x)){printf("\n");ccnt=0;}printf("%s",x);}}int convert(t, x)tokentype t;char*x;{static int state=1;switch(state){case 1:putx(x); if(t==NL)state=6;if(t==ID)state=2;break;case 2:if(t==WHITE){state=3;} else if(t==NL){state=7;}else{putx(x);if(t==ID)state=2;else state=1;}break; case 3:if(t==ID){putx(" ");putx(x);state=2;}else{putx(x);if(t==WHITE)state= 3;else if(t==NL)state=7;else state=1;}break;case 4:printf("%s",x);if(t== WHITE)printf(" ");if(t==NL){printf("\n");state=6;}else if(t==OP&&*x=='\\'){ state=5;}break;case 5:printf("%s",x);if(t==WHITE)printf(" ");if(t==NL) printf("\n");if(t==OP&&*x=='\\'){state=5;}else{state=4;}break;case 6:if(t== OP&&*x=='#'){putx(0);printf("#");state=4;}else{putx(x);if(t==ID)state=2; else if(t==NL)state=6;else state=1;}break;case 7:if(t==ID){putx(" ");putx( x);state=2;}else if(t==OP&&*x=='#'){putx(0);printf("#");state=4;}else{ putx(x);if(t==WHITE)state=3;else if(t==NL)state=7;else state=1;}break;}} #define LINESIZE 500 int tokenize(fp)FILE*fp;{char line[LINESIZE];register char*cp,c;int incomment=0;char*start;tokentype t;while(fgets(line,LINESIZE,fp)){for(cp=line;( c=*cp)!=0;){if(incomment){char pc;start=cp;do{pc=c;c=*++cp;}while(c!=0&&( c!='/'||pc!='*'));if(c!=0){incomment=0;c=*++cp;}else{break;}}if(c==' '|| c=='\t'){do c=*++cp;while(c==' '||c=='\t');convert(WHITE,"");}start=cp; if(isalpha(c)||c=='_'){do c=*++cp;while(isalnum(c)||c=='_');t=ID;}else if(c=='0'){if(cp[1]=='x'||cp[1]=='X'){cp++;do c=*++cp;while(isxdigit(c));} else{do c=*++cp;while(isdigit(c)&&c!='8'&&c!='9');}t=ID;}else if(isdigit(c)){ do c=*++cp;while(isdigit(c));if(c=='.'){cp++;do c=*++cp;while(isdigit(c));} if(c=='e'||c=='E'){c=*++cp;if(c=='+'||c=='-')c=*++cp;while(isdigit(c))c=*++ cp;}t=ID;}else if(c=='"'){do{c=*++cp;if(c=='\\'){cp+=2;c=*cp;}}while(c!= 0&&c!='"');if(c)cp++;t=STRING;}else if(c=='\''){do{c=*++cp;if(c=='\\'){ cp+=2;c=*cp;}}while(c!=0&&c!='\'');if(c)cp++;t=STRING;}else if(c=='/'&& cp[1]=='*'){incomment=1;cp++;}else if(c=='\n'){cp++;t=NL;start=cp;}else{ if(c!=0)cp++;t=OP;}if(!incomment&&start