home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
adobeenc.zoo
/
encrypt.shar
/
chars.c
next >
Wrap
C/C++ Source or Header
|
1990-10-27
|
5KB
|
246 lines
/*
* chars.c -- decrypt an Adobe font file of encrypted CharStrings
*
* Chris B. Sears
*/
#include <stdio.h>
#include <strings.h>
#define TRUE 1
#define FALSE 0
int lenIV = 4; /* CharString salt length */
typedef struct {
char *command;
int value;
} Command;
Command commands[] = {
{ "notdefined_c0", 0 },
{ "hstem", 1 },
{ "notdefined_c2", 2 },
{ "vstem", 3 },
{ "vmoveto", 4 },
{ "chars_rlineto", 5 },
{ "hlineto", 6 },
{ "vlineto", 7 },
{ "rrcurveto", 8 },
{ "chars_closepath",9 },
{ "callsubr", 10 },
{ "return", 11 },
{ "escape", 12 },
{ "hsbw", 13 },
{ "endchar", 14 },
{ "notdefined_c15", 15 },
{ "notdefined_c16", 16 },
{ "notdefined_c17", 17 },
{ "notdefined_c18", 18 },
{ "notdefined_c19", 19 },
{ "notdefined_c20", 20 },
{ "chars_rmoveto", 21 },
{ "hmoveto", 22 },
{ "notdefined_c23", 23 },
{ "notdefined_c24", 24 },
{ "notdefined_c25", 25 },
{ "notdefined_c26", 26 },
{ "notdefined_c27", 27 },
{ "notdefined_c28", 28 },
{ "notdefined_c29", 29 },
{ "vhcurveto", 30 },
{ "hvcurveto", 31 }
};
Command escapes[] = {
{ "dotsection", 0 },
{ "vstem3", 1 },
{ "hstem3", 2 },
{ "notdefined_e3", 3 },
{ "notdefined_e4", 4 },
{ "notdefined_e5", 5 },
{ "seac", 6 },
{ "sbw", 7 },
{ "notdefined_e8", 8 },
{ "notdefined_e9", 9 },
{ "notdefined_e10", 10 },
{ "notdefined_e11", 11 },
{ "chars_div", 12 },
{ "notdefined_e13", 13 },
{ "notdefined_e14", 14 },
{ "notdefined_e15", 15 },
{ "callothersubr", 16 },
{ "chars_pop", 17 },
{ "notdefined_e18", 18 },
{ "notdefined_e19", 19 },
{ "notdefined_e20", 20 },
{ "notdefined_e21", 21 },
{ "notdefined_e22", 22 },
{ "notdefined_e23", 23 },
{ "notdefined_e24", 24 },
{ "notdefined_e25", 25 },
{ "notdefined_e26", 26 },
{ "notdefined_e27", 27 },
{ "notdefined_e28", 28 },
{ "notdefined_e29", 29 },
{ "notdefined_e30", 30 },
{ "notdefined_e31", 31 },
{ "notdefined_e32", 32 },
{ "setcurrentpoint",33 }
};
#define MAX_ESCAPE 33
#define CR 4330
#define CC1 52845
#define CC2 22719
unsigned short int cr, cc1, cc2;
unsigned char
DeCrypt(cipher)
unsigned char cipher;
{
unsigned char plain;
plain = (cipher ^ (cr >> 8));
cr = (cipher + cr) * cc1 + cc2;
return plain;
}
void
main(argc, argv)
int argc;
char **argv;
{
FILE *in, *out;
unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
int in_size, line_pos, i, count;
long value;
if (argc != 3) {
fprintf(stderr, "Usage: %s input output\n", argv[0]);
exit(0);
}
if ((in = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
exit(0);
}
out = fopen(argv[2], "w");
setbuf(out, NULL);
/*
* TODO: rewrite this so as not to use a seek and to use stdin.
*/
for (;;) {
line_pos = ftell(in);
if (fgets(in_buff, BUFSIZ, in) == NULL)
break;
in_size = strlen(in_buff) - 1;
if (strncmp("/lenIV", in_buff, 6) == 0)
lenIV = atoi(in_buff + 7);
if ((rd_pos = (unsigned char *) strstr(in_buff, " RD ")) == NULL) {
fputs(in_buff, out);
continue;
}
/*
* We found an encrypted CharString.
* Back up and determine the number of encrypted characters.
* These have the form: dup 105 9 RD 9bytesofdata noaccess put
*/
for (count_pos = rd_pos - 1;
(count_pos >= in_buff) && (*count_pos != ' ');
count_pos--)
;
if (*count_pos == ' ') /* This can be at the beginning of a line */
count_pos++;
/*
* Write out the beginning of the string without the RD stuff.
*/
fwrite(in_buff, count_pos - in_buff, 1, out);
fprintf(out, "{");
count = atoi(count_pos);
/*
* Seek to and read the binary data.
*/
fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
fread(in_buff, BUFSIZ, 1, in);
/*
* We must restart the decryption machinery for each CharString.
*/
cr = CR;
cc1 = CC1;
cc2 = CC2;
/*
* Skip over the salt.
*/
for (i = 0; i < lenIV; i++)
byte = DeCrypt(in_buff[i]);
/*
* Translate the buffer.
*/
for (; i < count;) {
byte = DeCrypt(in_buff[i++]);
if (byte == 11) { /* return */
fprintf(out, " %s", commands[byte].command);
break;
} else if (byte == 12) { /* escape */
byte = DeCrypt(in_buff[i++]);
if (byte > MAX_ESCAPE)
fprintf(out, " not_defined_e%d", byte);
else
fprintf(out, " %s", escapes[byte].command);
continue;
} else if (byte < 32)
fprintf(out, " %s", commands[byte].command);
if (byte >= 32) {
if (byte <= 246)
fprintf(out, " %d", byte - 139);
else if ((byte >= 247) && (byte <= 250))
fprintf(out, " %d",
(byte - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
else if ((byte >= 251) && (byte <= 254))
fprintf(out, " %d",
-(byte - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
else if (byte == 255) {
value = DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
fprintf(out, " %d", value);
}
}
}
fprintf(out, " }");
/*
* Seek just past the CharString bytes and continue.
*/
fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
}
fclose(in);
fclose(out);
exit(0);
}