1 
2 /* #include "config.h" */
3 
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 
main(int argv,char * argc[])8 int main(int argv, char * argc[])
9 {
10   int xor_base = -1;
11 
12   FILE * inf;
13   FILE * ouf;
14   char a, b;
15   int  i, j;
16   char outfile[1024];
17   int inbracket = 0, quoted = 0;
18   unsigned long count;
19 
20 
21   /*  char command[1024]; */
22 
23   if ( argv < 3)
24     {
25       fprintf(stderr,"\nUsage: encode <XOR_VAL> "\
26 	      "<file>\n\n");
27       fprintf(stderr,"    This program will:\n");
28       fprintf(stderr,"    - take as input a source code file <file>,\n");
29       fprintf(stderr,"    - search for literal strings inclosed by _(), "\
30 	      "like '_(string)',\n");
31       fprintf(stderr,"    - replace _(string) by "\
32 	      "_(string XOR <XOR_VAL>),\n");
33       fprintf(stderr,
34 	      "    - and output the result to './x_<file>'.\n\n");
35       fprintf(stderr,"    _() is supposed to be defined as a macro in "\
36 	      "the code, that\n");
37       fprintf(stderr,"    will allow the program to decode the xor'ed string "\
38 	      "at runtime.\n");
39       fprintf(stderr,"    The effect is that the compiled executable does "\
40 	      "not contain literal\n");
41       fprintf(stderr,"    strings that may trivially be found with the Unix "\
42 	      "'strings' command,\n");
43       fprintf(stderr,"    and thus reveal the nature of "\
44 	      "the program.\n");
45 
46       return -1;
47     }
48 
49   --argv; ++argc;
50 
51   xor_base = atoi(argc[0]);
52 
53   if (xor_base < 0 || (xor_base > 0 && xor_base < 128) || xor_base > 255)
54     {
55       fprintf(stderr, "\nERROR: encode: XOR_VAL=%d is out of "\
56 	      "range (0, 128..255)\n",
57 	      xor_base);
58       fprintf(stderr, "** please follow these steps to fix the problem:\n\n");
59       fprintf(stderr, "   make clean\n");
60       fprintf(stderr, "   ./configure [more options] "\
61 	      "--with-stealth=XOR_VAL (range 0, 128..255)\n");
62       fprintf(stderr, "   make\n\n");
63       return -1;
64     }
65 
66   /*  fprintf(stderr, "<XOR_CODE> %d\n", xor_base); */
67 
68   --argv; ++argc;
69 
70   /*  fprintf(stderr, "File: %d\n", argv); */
71 
72   while (argv > 0)
73     {
74       inf = fopen(argc[0], "r");
75       if (inf == NULL)
76 	{
77 	  fprintf(stderr, "Error opening %s\n", argc[0]);
78 	  return -1;
79 	}
80       /* outfile name
81        */
82       i = 0; j = 0;
83       while (argc[0][i] != '\0')
84 	{
85 	  if (argc[0][i] == '/') j = i+1;
86 	  ++i;
87 	}
88       i = 0;
89       outfile[0] = 'x';
90       outfile[1] = '_';
91       outfile[2] = '\0';
92       while (argc[0][j+i] != '\0')
93 	{
94 	  outfile[i+2] = argc[0][j+i];
95 	  ++i;
96 	}
97       outfile[i+2] = '\0';
98       ouf = fopen(outfile, "w");
99       if (ouf == NULL)
100 	{
101 	  fprintf(stderr, "Error opening %s\n", outfile);
102 	  return -1;
103 	}
104 
105       /*  fprintf(stderr, "File: %s\n", argc[0]); */
106       count = 0;
107 
108       while (fread(&a, 1, 1, inf) != 0)
109 	{
110 	  count++;
111 
112 	  if (a == '"' && quoted == 0)
113 	    {
114 	      quoted = 1;
115 	      fwrite(&a, 1, 1, ouf);
116 	      continue;
117 	    }
118 
119 	  if (a == '"' && quoted == 1)
120 	    {
121 	      quoted = 0;
122 	      fwrite(&a, 1, 1, ouf);
123 	      continue;
124 	    }
125 
126 	  if (a == '\n' && quoted == 1)
127 	    {
128 	      quoted = 0;
129 	      fwrite(&a, 1, 1, ouf);
130 	      continue;
131 	    }
132 
133 	  /* macro start ?
134 	   */
135 	  if (a == '_' && inbracket == 0 && quoted == 0)
136 	    {
137 	      fwrite(&a, 1, 1, ouf);
138 	      b = '\0';
139 	      fread(&b, 1, 1, inf);
140 	      count++;
141 	      fwrite(&b, 1, 1, ouf);
142 	      if (b == '(') inbracket = 1;
143 	      continue;
144 	    }
145 
146 	  /* macro end
147 	   */
148 	  if (a == ')' && quoted == 0    && inbracket == 1)
149 	    {
150 	      inbracket = 0;
151 	      /*  fprintf(stdout, "\n"); */
152 	      fwrite(&a, 1, 1, ouf);
153 	      continue;
154 	    }
155 
156 	  /* in a bracket
157 	   */
158 	  if (inbracket == 1 && quoted == 1)
159 	    {
160 	      /*  fprintf(stdout, "%c", a); */
161 	      if (a == '\\')
162                 {
163                   fread(&b, 1, 1, inf);
164 
165 		  /* escape sequences
166 		   */
167                   if (b == 't' || b == 'n' || b == 'r' || b == '"')
168 		    {
169 		      fwrite(&a, 1, 1, ouf);
170 		      fwrite(&b, 1, 1, ouf);
171 		    }
172 
173                   else
174                     {
175                       a ^= (char) xor_base;
176                       b ^= (char) xor_base;
177                     }
178                 }
179               else
180                 {
181 	          a ^= (char) xor_base;
182 	          fwrite(&a, 1, 1, ouf);
183                 }
184 	      continue;
185 	    }
186 
187 	  fwrite(&a, 1, 1, ouf);
188 	}
189 
190       /*  fprintf(stderr, "Bytes read: %ld\n", count); */
191       /*  sprintf(command, "mv tempfile %s", argc[0]); */
192       /* system(command); */
193 
194       fclose(ouf);
195       fclose(inf);
196       --argv; ++argc;
197     }
198   return 0;
199 }
200 
201