fb539d1b |
1 | /* |
2 | * Stand-alone tool to access the Puzzles obfuscation algorithm. |
3 | * |
4 | * To deobfuscate, use "obfusc -d": |
5 | * |
6 | * obfusc -d reads binary data from stdin, writes to stdout |
7 | * obfusc -d <hex string> works on the given hex string instead of stdin |
8 | * obfusc -d -h writes a hex string instead of binary to stdout |
9 | * |
10 | * To obfuscate, "obfusc -e": |
11 | * |
12 | * obfusc -e reads binary from stdin, writes hex to stdout |
13 | * obfusc -e <hex string> works on the given hex string instead of stdin |
14 | * obfusc -e -b writes binary instead of text to stdout |
15 | * |
16 | * The default output format is hex for -e and binary for -d |
17 | * because that's the way obfuscation is generally used in |
18 | * Puzzles. Either of -b and -h can always be specified to set it |
19 | * explicitly. |
20 | * |
21 | * Data read from standard input is assumed always to be binary; |
22 | * data provided on the command line is taken to be hex. |
23 | */ |
24 | |
25 | #include <stdio.h> |
26 | #include <stdlib.h> |
27 | #include <stdarg.h> |
28 | #include <string.h> |
29 | #include <errno.h> |
30 | |
31 | #include "puzzles.h" |
32 | |
33 | int main(int argc, char **argv) |
34 | { |
35 | enum { BINARY, DEFAULT, HEX } outputmode = DEFAULT; |
36 | char *inhex = NULL; |
37 | unsigned char *data; |
38 | int datalen; |
39 | int decode = -1; |
40 | int doing_opts = TRUE; |
41 | |
42 | while (--argc > 0) { |
43 | char *p = *++argv; |
44 | |
45 | if (doing_opts && *p == '-') { |
46 | if (!strcmp(p, "--")) { |
47 | doing_opts = 0; |
48 | continue; |
49 | } |
50 | p++; |
51 | while (*p) { |
52 | switch (*p) { |
53 | case 'e': |
54 | decode = 0; |
55 | break; |
56 | case 'd': |
57 | decode = 1; |
58 | break; |
59 | case 'b': |
60 | outputmode = BINARY; |
61 | break; |
62 | case 'h': |
63 | outputmode = HEX; |
64 | break; |
65 | default: |
66 | fprintf(stderr, "obfusc: unrecognised option '-%c'\n", |
67 | *p); |
68 | return 1; |
69 | } |
70 | p++; |
71 | } |
72 | } else { |
73 | if (!inhex) { |
74 | inhex = p; |
75 | } else { |
76 | fprintf(stderr, "obfusc: expected at most one argument\n"); |
77 | return 1; |
78 | } |
79 | } |
80 | } |
81 | |
82 | if (decode < 0) { |
83 | fprintf(stderr, "usage: obfusc < -e | -d > [ -b | -h ] [hex data]\n"); |
84 | return 0; |
85 | } |
86 | |
87 | if (outputmode == DEFAULT) |
88 | outputmode = (decode ? BINARY : HEX); |
89 | |
90 | if (inhex) { |
91 | datalen = strlen(inhex) / 2; |
92 | data = hex2bin(inhex, datalen); |
93 | } else { |
94 | int datasize = 4096; |
95 | datalen = 0; |
96 | data = snewn(datasize, unsigned char); |
97 | while (1) { |
98 | int ret = fread(data + datalen, 1, datasize - datalen, stdin); |
99 | if (ret < 0) { |
100 | fprintf(stderr, "obfusc: read: %s\n", strerror(errno)); |
101 | return 1; |
102 | } else if (ret == 0) { |
103 | break; |
104 | } else { |
105 | datalen += ret; |
106 | if (datasize - datalen < 4096) { |
107 | datasize = datalen * 5 / 4 + 4096; |
108 | data = sresize(data, datasize, unsigned char); |
109 | } |
110 | } |
111 | } |
112 | } |
113 | |
114 | obfuscate_bitmap(data, datalen * 8, decode); |
115 | |
116 | if (outputmode == BINARY) { |
29797015 |
117 | int ret = fwrite(data, 1, datalen, stdout); |
118 | if (ret < 0) { |
119 | fprintf(stderr, "obfusc: write: %s\n", strerror(errno)); |
120 | return 1; |
121 | } |
fb539d1b |
122 | } else { |
123 | int i; |
124 | for (i = 0; i < datalen; i++) |
125 | printf("%02x", data[i]); |
126 | printf("\n"); |
127 | } |
128 | |
129 | return 0; |
130 | } |