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