added demo of signal/uid handling feature
[tridge/junkcode.git] / regdecrypt.c
1 /* This program takes an 'encrypted' Windows 95 share password and decrypts it.
2  * Look at:
3  * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Network\LanMan
4  * to find a machine's shares.  Within the data for each share are two
5  * registry entries, Parm1enc and Parm2enc.  Parm1enc is the "Full access"
6  * password.  Parm2enc is the "Read only" password.
7  *
8  * David Ross  2/9/96
9  * snakey@cs.umd.edu
10  *
11  * Do not distribute this program for any commercial purpose without first
12  * contacting me for permission.
13  *
14  * DO NOT USE THIS PROGRAM FOR ILLEGAL OR UNETHICAL PURPOSES!
15  *
16  * A technical description of the 'code' can be found later on in this
17  * document. 
18  *
19  * Oh yeah...  a totally unsolicited self promotion here...  If anyone has
20  * a job for a junior year Computer Science student for summer '96, please
21  * let me know!  I'm familiar with Windows and Mac networking (especially 
22  * involving TCP/IP), fluent in C and C++, and working on becoming a
23  * proficient Windows programmer.
24  *
25  */
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #define BUFFER 30
31
32 int DecodeCharOne(unsigned char *);
33 int DecodeCharTwo(unsigned char *);
34 int DecodeCharThree(unsigned char *);
35 int DecodeCharFour(unsigned char *);
36 int DecodeCharFive(unsigned char *);
37 int DecodeCharSix(unsigned char *);
38 int DecodeCharSeven(unsigned char *);
39 int DecodeCharEight(unsigned char *);
40
41 main() {
42
43   int i;           /* Generic counter */
44   int eocc = 0;    /* Records if there has been an error */
45
46   /* The following structure stores the encoded bytes.  Decoded values
47    * replace the encoded values as the decoding process moves along
48    * The initial values show here are not used and are unimportant
49    */
50   unsigned char mybytes[] = { 0x15, 0xba, 0x6d, 0x86, 0x73, 0x89, 0xf4, 0x4a };
51   unsigned short tempshort;   /* Used as a go-between from sscanf() to
52                                  mybytes[] so unaligned data accesses
53                                  don't occur */
54
55   int goupto = 0;  /* Records how many characters there are to be decoded */
56   
57   /* The following code handles input */
58   char inpt[BUFFER];
59   char *inptptr;
60   
61   printf("Input the byte code in hex (ex: 76 d5 09 e3): ");
62   fgets(inpt, BUFFER, stdin);
63   
64   inptptr = strtok(inpt, " ");
65   if (inpt[0] != '\n')
66     while ((inptptr != NULL) && (goupto < 8)) {
67       sscanf(inptptr, "%hx", &tempshort);
68       mybytes[goupto++] = tempshort;
69       inptptr = strtok(NULL, " ");
70     }
71   
72   /* Decode all the characters.  I could have made this stop immediately
73    * after an error has been found, but it really doesn't matter
74    */
75   if (!DecodeCharOne(&mybytes[0])) eocc = 1;
76   if (!DecodeCharTwo(&mybytes[1])) eocc = 1;
77   if (!DecodeCharThree(&mybytes[2])) eocc = 1;
78   if (!DecodeCharFour(&mybytes[3])) eocc = 1;
79   if (!DecodeCharFive(&mybytes[4])) eocc = 1;
80   if (!DecodeCharSix(&mybytes[5])) eocc = 1;
81   if (!DecodeCharSeven(&mybytes[6])) eocc = 1;
82   if (!DecodeCharEight(&mybytes[7])) eocc = 1;
83
84   /* If the password could be decoded, print it */
85   if (eocc) printf("The encrypted password is invalid.\n");
86   else {
87     printf("The decoded password is: \"");
88     for (i = 0; i < goupto; i++) printf("%c",mybytes[i]);
89     printf("\"\n");
90   }
91 }  /* End of main() */
92
93 /*
94  * I will document this function, but not the seven other functions
95  * which decode the subsequent seven characters.  All of these functions
96  * are essentially the same.  Multiple functions are necessary though
97  * because each column of the password has a different set of encoding
98  * patterns.
99  *
100  * The following section will attempt to explain the encoding scheme
101  * for share passwords as stored in the Windows 95 registry.  I will
102  * try to explain this as clearly as I can, however I really have no
103  * background in encryption.  If you have any questions, please feel
104  * free to send them to me at snakey@cs.umd.edu.
105  *
106  * First off, share passwords can be anywhere from one character to
107  * eight.  "Read only" passwords and "Full access" passwords both use
108  * the same encoding scheme, and so they both can be decoded by this
109  * program.  There is a one-to-one relationship between the number of
110  * characters in a password and the number of bytes in the encoded
111  * password stored in the registry.  In fact, each encoded byte directly
112  * corresponds to the letter in the corresponding column of the
113  * unencoded password!  Ie: If I change a password "passwd" to "masswd",
114  * only the first byte of the encrypted password will change.  Knowing
115  * this, it is easy to see that all that needs to be done to decode
116  * the password is to find a mapping from an encoded byte to a decoded
117  * letter.  That's what this program does.  Unfortunately, things get
118  * a little tricky because a letter in the first column of a password
119  * is encoded using a slightly different algorithm than a letter
120  * in the second column, and so on.
121  *
122  * There is another complexity which we do not really need to worry
123  * about to a great extent, but we still need to be aware of.  Many
124  * characters, when entered into a password, map to the same encoded
125  * byte.  The best example of this is that both 'A' and 'a' are the
126  * same as far as share passwords are concerned.  There are numerous
127  * other examples of this, and this allows us to effectively limit the
128  * range of characters we need to be able to decode.  The range of
129  * ASCII values we will have to be able to decode turns out to be
130  * from 32 to 159.  ASCII values higher than 159 tend to map to
131  * encoded bytes which also represent more normal ASCII values.  So
132  * if a user manages to create a password with high ASCII values
133  * in it, that password will still be decoded by this program.
134  * Although the decoded password won't look the same as the original,
135  * it will work just as well.
136  *
137  * With all of the preliminaries out of the way, I can now move on
138  * to describing the mapping from an encoded byte to it's corresponding
139  * ASCII value.  I think the best way to describe this would be through
140  * a picture of exactly how the characters from 32 to 63 are mapped
141  * out in the code for the first letter in a password.  This table goes
142  * beyond the 80 column format maintained in the rest of this document,
143  * but it is really the best solution.  If the table below doesn't look
144  * right, load this file up in a text editor that supports greater than
145  * 80 columns.
146  *
147  *   Encoded byte (hex)    - 1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 14 11 10 0F OE 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
148  *   ASCII value (decimal) - 42 43 40 41 46 47 44 45 34 35 32 33 38 39 36 37 58 59 56 57 62 63 60 61 50 51 48 49 54 55 52 53
149  *   Pair #                - |_6_| |_5_| |_8_| |_7_| |_2_| |_1_| |_4_| |_3_| |14_| |13_| |16_| |15_| |10_| |_9_| |12_| |11_|
150  *   Quad #                - |__________2__________| |__________1__________| |__________3__________| |__________4__________|
151  *   32 byte block #       - |______________________________________________1______________________________________________|
152  *
153  * The "Pair #", "Quad #", and "32 byte block #" rows each are there to
154  * make the general ordering of the code more visible.  The first thing to
155  * note is that the range of encoded byte values runs from 00 to 1f.  This
156  * will not always be the case for the first set of 32 characters.  In
157  * fact, the next set of 32 characters (ASCII 64 to ASCII 95) is not in
158  * the range of 20 to 3f in encoded form.  I never concerned myself with
159  * predicting exactly where each of the four 32 byte ranges are aligned
160  * within the range of 0 to 256.  In my decoding scheme, I simply specify
161  * the location of the first character in a 32 byte block (which I have
162  * pre-determined via experimentation) and determine the locations of the
163  * rest of the characters in the block relative to the inital value.  This
164  * amounts to a total of four hand-decoded characters for the entire code.
165  *
166  * From a starting point which is given (in this case the fact that ASCII
167  * 32 is encoded as 0x15), my decoding scheme follows a pattern that is
168  * probably already apparent to you if you have examined the above table
169  * closely.  First, if the encoded byte number is odd, it simple subtracts
170  * one from this byte number to get the byte number of the encoded form of
171  * the subsequent character.  This is much more simple than it sounds.
172  * As an example, given that the code for ASCII 32 is 0x15, the program
173  * knows that the code for ASCII 33 must be 0x14.  The tricky part is that
174  * this is not always true for every code.  Recall that there is a different
175  * coding scheme for each of the 8 columns in a password, and that the above
176  * table only describes the coding scheme for the first column.  Other columns
177  * reverse this relationship between the two ASCII values of a certain pair.
178  *
179  * Pairs are grouped into units of four, appearing in a predefined pattern.
180  * In this case, the first pair (by first I mean the pair with the lowest
181  * set of ASCII values) is put in the second slot of a quad (which contains
182  * four pairs).  The second pair is put in the first slot, the third is put
183  * in the fourth quad, and the fourth is put in the third quad.  This changes
184  * depending on the specific code used (of the 8 possible).
185  *
186  * Quads also fill a block in the same manner, however the ordering is NOT
187  * necessarily the same as the way pairs fit into quads!  As I described
188  * above, there are four blocks, and they fit into the entire range of
189  * 128 values just as pairs fit into quads and quads fit into blocks,
190  * via a pattern determined by whoever invented this encoding scheme.  It
191  * is important to realize that the range of 128 possible encoded
192  * values can be anywhere within the range of 0 to 256.  Ie: One block can
193  * be positioned from 0x00 to 0x1f, while another block in the same code
194  * can be positioned from 0xa0 to 0xbf.
195  *
196  * I realize that the above description is a bit complex, and it doesn't
197  * really cover much of _how_ my program decodes the the encoded values.
198  * If you honestly can't understand a word I've said, just go back to
199  * the table and really take a long look at it.  Print it out, put it
200  * under your pillow when you go to sleep.  Sooner or later the order
201  * of it all will dawn on you and you should be able to step through
202  * my code and see how it derives its answer, at least for the
203  * DecodeCharOne() routine.  Seven other tables (which I have rough
204  * copies of here on notebook paper) were needed to come up with
205  * the seven other decoders for the seven other character places.
206  *
207  */
208
209 int DecodeCharOne(unsigned char *mychar) {
210   int i = 0;        /* Keeps track of the decoded character # minus 32 */
211   int cletter = 1;  /* Sets the current letter of the 8 char quad */
212   int blockl1 = 1;  /* Sets the current quad */
213   int blockl2 = 1;  /* Sets the current 32 char block */
214   int retval = 1;
215   /* We are on this col of the table: */
216   unsigned char code = 0x15;    /* The code for a space */
217   
218   /* This is the main loop.  It walks through each decoded character, finds
219    * its corresponding encoded value, and looks to see if that's the same as
220    * the encoded value we are looking for.  If it is, we have found our
221    * decoded character!
222    */
223   while((i<256) && (code != *mychar)) {
224     switch (cletter) {
225     case 1:
226       code--;
227       cletter++;
228       break;
229     case 2:
230       code += 3;
231       cletter++;
232       break;
233     case 3:
234       code--;
235       cletter++;
236       break;
237     case 4:
238       code -= 5;
239       cletter++;
240       break;
241     case 5:
242       code--;
243       cletter++;
244       break;
245     case 6:
246       code+=3;
247       cletter++;
248       break;
249     case 7:
250       code--;
251       cletter++;
252       break;
253     case 8:
254       cletter = 1;
255       switch (blockl1) {    /* After we hit character number 8, we have */
256       case 1:               /* to do a relative jump to the next quad */
257         code += 11;
258         blockl1++;
259         break;
260       case 2:
261         code -= 21;
262         blockl1++;
263         break;
264       case 3:
265         code += 11;
266         blockl1++;
267         break;
268       case 4:
269         blockl1 = 1;
270         switch (blockl2) {       /* After we hit the last quad, we have to */
271         case 1:                  /* jump to the next 32 character block. */
272           code = 0x75;
273           blockl2++;
274           break;
275         case 2:
276           code = 0x55;
277           blockl2++;
278           break;
279         case 3:
280           code = 0xb5;
281           blockl2++;
282           break;
283         case 4:
284           code = 0x15;
285           blockl2 = 1;
286           break;
287         }
288         break;
289       }
290       break;
291     }
292     i++;
293   }
294   if (i == 256) retval = 0;
295   else *mychar = i + 32;
296   return retval;
297 }  /* End of DecodeCharOne() */
298
299 int DecodeCharTwo(unsigned char *mychar) {
300   int i = 0;
301   int cletter = 1;
302   int blockl1 = 1;
303   int blockl2 = 1;
304   int retval = 1;
305   unsigned char code = 0xba;    /* The code for a space */
306   while((i<256) && (code != *mychar)) {
307     switch (cletter) {
308     case 1:
309       code++;
310       cletter++;
311       break;
312     case 2:
313       code -= 3;
314       cletter++;
315       break;
316     case 3:
317       code++;
318       cletter++;
319       break;
320     case 4:
321       code += 5;
322       cletter++;
323       break;
324     case 5:
325       code++;
326       cletter++;
327       break;
328     case 6:
329       code -= 3;
330       cletter++;
331       break;
332     case 7:
333       code++;
334       cletter++;
335       break;
336     case 8:
337       cletter = 1;
338       switch (blockl1) {
339       case 1:
340         code -= 11;
341         blockl1++;
342         break;
343       case 2:
344         code -= 11;
345         blockl1++;
346         break;
347       case 3:
348         code -= 11;
349         blockl1++;
350         break;
351       case 4:
352         blockl1 = 1;
353         switch (blockl2) {
354         case 1:
355           code = 0xda;
356           blockl2++;
357           break;
358         case 2:
359           code = 0xfa;
360           blockl2++;
361           break;
362         case 3:
363           code = 0x1a;
364           blockl2++;
365           break;
366         case 4:
367           code = 0xba;
368           blockl2 = 1;
369           break;
370         }
371         break;
372       }
373       break;
374     }
375     i++;
376   }
377   if (i == 256) retval = 0;
378   else *mychar = i + 32;
379   return retval;
380 }  /* End of DecodeCharTwo() */
381
382 int DecodeCharThree(unsigned char *mychar) {
383   int i = 0;
384   int cletter = 1;
385   int blockl1 = 1;
386   int blockl2 = 1;
387   int retval = 1;
388   unsigned char code = 0x6d;    /* The code for a space */
389   while((i<256) && (code != *mychar)) {
390     switch (cletter) {
391     case 1:
392       code--;
393       cletter++;
394       break;
395     case 2:
396       code += 3;
397       cletter++;
398       break;
399     case 3:
400       code--;
401       cletter++;
402       break;
403     case 4:
404       code -= 5;
405       cletter++;
406       break;
407     case 5:
408       code--;
409       cletter++;
410       break;
411     case 6:
412       code += 3;
413       cletter++;
414       break;
415     case 7:
416       code--;
417       cletter++;
418       break;
419     case 8:
420       cletter = 1;
421       switch (blockl1) {
422       case 1:
423         code -= 5;
424         blockl1++;
425         break;
426       case 2:
427         code += 27;
428         blockl1++;
429         break;
430       case 3:
431         code -= 5;
432         blockl1++;
433         break;
434       case 4:
435         blockl1 = 1;
436         switch (blockl2) {
437         case 1:
438           code = 0x0d;
439           blockl2++;
440           break;
441         case 2:
442           code = 0x2d;
443           blockl2++;
444           break;
445         case 3:
446           code = 0xcd;
447           blockl2++;
448           break;
449         case 4:
450           code = 0x6d;
451           blockl2 = 1;
452           break;
453         }
454         break;
455       }
456       break;
457     }
458     i++;
459   }
460   if (i == 256) retval = 0;
461   else *mychar = i + 32;
462   return retval;
463 }  /* End of DecodeCharThree() */
464
465 int DecodeCharFour(unsigned char *mychar) {
466   int i = 0;
467   int cletter = 1;
468   int blockl1 = 1;
469   int blockl2 = 1;
470   int retval = 1;
471   unsigned char code = 0x86;    /* The code for a space */
472   while((i<256) && (code != *mychar)) {
473     switch (cletter) {
474     case 1:
475       code++;
476       cletter++;
477       break;
478     case 2:
479       code -= 3;
480       cletter++;
481       break;
482     case 3:
483       code++;
484       cletter++;
485       break;
486     case 4:
487       code -= 3;
488       cletter++;
489       break;
490     case 5:
491       code++;
492       cletter++;
493       break;
494     case 6:
495       code -= 3;
496       cletter++;
497       break;
498     case 7:
499       code++;
500       cletter++;
501       break;
502     case 8:
503       cletter = 1;
504       switch (blockl1) {
505       case 1:
506         code += 13;
507         blockl1++;
508         break;
509       case 2:
510         code += 13;
511         blockl1++;
512         break;
513       case 3:
514         code += 13;
515         blockl1++;
516         break;
517       case 4:
518         blockl1 = 1;
519         switch (blockl2) {
520         case 1:
521           code = 0xe6;
522           blockl2++;
523           break;
524         case 2:
525           code = 0xc6;
526           blockl2++;
527           break;
528         case 3:
529           code = 0x26;
530           blockl2++;
531           break;
532         case 4:
533           code = 0x86;
534           blockl2 = 1;
535           break;
536         }
537         break;
538       }
539       break;
540     }
541     i++;
542   }
543   if (i == 256) retval = 0;
544   else *mychar = i + 32;
545   return retval;
546 }   /* End of DecodeCharFour() */
547
548 int DecodeCharFive(unsigned char *mychar) {
549   int i = 0;
550   int cletter = 1;
551   int blockl1 = 1;
552   int blockl2 = 1;
553   int retval = 1;
554   unsigned char code = 0x73;    /* The code for a space */
555   while((i<256) && (code != *mychar)) {
556     switch (cletter) {
557     case 1:
558       code--;
559       cletter++;
560       break;
561     case 2:
562       code--;
563       cletter++;
564       break;
565     case 3:
566       code--;
567       cletter++;
568       break;
569     case 4:
570       code += 7;
571       cletter++;
572       break;
573     case 5:
574       code--;
575       cletter++;
576       break;
577     case 6:
578       code--;
579       cletter++;
580       break;
581     case 7:
582       code--;
583       cletter++;
584       break;
585     case 8:
586       cletter = 1;
587       switch (blockl1) {
588       case 1:
589         code += 7;
590         blockl1++;
591         break;
592       case 2:
593         code -= 25;
594         blockl1++;
595         break;
596       case 3:
597         code += 7;
598         blockl1++;
599         break;
600       case 4:
601         blockl1 = 1;
602         switch (blockl2) {
603         case 1:
604           code = 0x13;
605           blockl2++;
606           break;
607         case 2:
608           code = 0x33;
609           blockl2++;
610           break;
611         case 3:
612           code = 0x23;
613           blockl2++;
614           break;
615         case 4:
616           code = 0x73;
617           blockl2 = 1;
618           break;
619         }
620         break;
621       }
622       break;
623     }
624     i++;
625   }
626   if (i == 256) retval = 0;
627   else *mychar = i + 32;
628   return retval;
629 }    /* End of DecodeCharFive() */
630
631 int DecodeCharSix(unsigned char *mychar) {
632   int i = 0;
633   int cletter = 1;
634   int blockl1 = 1;
635   int blockl2 = 1;
636   int retval = 1;
637   unsigned char code = 0x89;    /* The code for a space */
638   while((i<256) && (code != *mychar)) {
639     switch (cletter) {
640     case 1:
641       code--;
642       cletter++;
643       break;
644     case 2:
645       code += 3;
646       cletter++;
647       break;
648     case 3:
649       code--;
650       cletter++;
651       break;
652     case 4:
653       code += 3;
654       cletter++;
655       break;
656     case 5:
657       code--;
658       cletter++;
659       break;
660     case 6:
661       code += 3;
662       cletter++;
663       break;
664     case 7:
665       code--;
666       cletter++;
667       break;
668     case 8:
669       cletter = 1;
670       switch (blockl1) {
671       case 1:
672         code -= 13;
673         blockl1++;
674         break;
675       case 2:
676         code += 19;
677         blockl1++;
678         break;
679       case 3:
680         code -= 13;
681         blockl1++;
682         break;
683       case 4:
684         blockl1 = 1;
685         switch (blockl2) {
686         case 1:
687           code = 0xe9;
688           blockl2++;
689           break;
690         case 2:
691           code = 0xc9;
692           blockl2++;
693           break;
694         case 3:
695           code = 0x29;
696           blockl2++;
697           break;
698         case 4:
699           code = 0x89;
700           blockl2 = 1;
701           break;
702         }
703         break;
704       }
705       break;
706     }
707     i++;
708   }
709   if (i == 256) retval = 0;
710   else *mychar = i + 32;
711   return retval;
712 }     /* End of DecodeCharSix() */
713
714 int DecodeCharSeven(unsigned char *mychar) {
715   int i = 0;
716   int cletter = 1;
717   int blockl1 = 1;
718   int blockl2 = 1;
719   int retval = 1;
720   unsigned char code = 0xf4;    /* The code for a space */
721   while((i<256) && (code != *mychar)) {
722     switch (cletter) {
723     case 1:
724       code++;
725       cletter++;
726       break;
727     case 2:
728       code++;
729       cletter++;
730       break;
731     case 3:
732       code++;
733       cletter++;
734       break;
735     case 4:
736       code -= 7;
737       cletter++;
738       break;
739     case 5:
740       code++;
741       cletter++;
742       break;
743     case 6:
744       code++;
745       cletter++;
746       break;
747     case 7:
748       code++;
749       cletter++;
750       break;
751     case 8:
752       cletter = 1;
753       switch (blockl1) {
754       case 1:
755         code += 9;
756         blockl1++;
757         break;
758       case 2:
759         code -= 23;
760         blockl1++;
761         break;
762       case 3:
763         code += 9;
764         blockl1++;
765         break;
766       case 4:
767         blockl1 = 1;
768         switch (blockl2) {
769         case 1:
770           code = 0x94;
771           blockl2++;
772           break;
773         case 2:
774           code = 0xb4;
775           blockl2++;
776           break;
777         case 3:
778           code = 0x54;
779           blockl2++;
780           break;
781         case 4:
782           code = 0xf4;
783           blockl2 = 1;
784           break;
785         }
786         break;
787       }
788       break;
789     }
790     i++;
791   }
792   if (i == 256) retval = 0;
793   else *mychar = i + 32;
794   return retval;
795 }   /* End of DecodeCharSeven() */
796
797 int DecodeCharEight(unsigned char *mychar) {
798   int i = 0;
799   int cletter = 1;
800   int blockl1 = 1;
801   int blockl2 = 1;
802   int retval = 1;
803   unsigned char code = 0x4a;    /* The code for a space */
804   while((i<256) && (code != *mychar)) {
805      switch (cletter) {
806      case 1:
807        code++;
808        cletter++;
809        break;
810      case 2:
811        code -= 3;
812        cletter++;
813        break;
814      case 3:
815        code++;
816        cletter++;
817        break;
818      case 4:
819        code += 5;
820        cletter++;
821        break;
822      case 5:
823        code++;
824        cletter++;
825        break;
826      case 6:
827        code -= 3;
828        cletter++;
829        break;
830      case 7:
831        code++;
832        cletter++;
833        break;
834      case 8:
835        cletter = 1;
836        switch (blockl1) {
837        case 1:
838          code -= 11;
839          blockl1++;
840          break;
841        case 2:
842          code += 21;
843          blockl1++;
844          break;
845        case 3:
846          code -= 11;
847          blockl1++;
848          break;
849        case 4:
850          blockl1 = 1;
851          switch (blockl2) {
852          case 1:
853            code = 0x2a;
854            blockl2++;
855            break;
856          case 2:
857            code = 0x0a;
858            blockl2++;
859            break;
860          case 3:
861            code = 0xea;
862            blockl2++;
863            break;
864          case 4:
865            code = 0x4a;
866            blockl2 = 1;
867            break;
868          }
869          break;
870        }
871        break;
872      }
873      i++;
874   }
875   if (i == 256) retval = 0;
876   else *mychar = i + 32;
877   return retval;
878 }    /* End of DecodeCharEight() */
879
880 /* End of program */
881