-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.cpp
131 lines (115 loc) · 3.57 KB
/
main.cpp
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
131
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
#define MAGIC_START 0x128
#define MAGIC_LENGTH 257
#define HEADER_LENGTH (MAGIC_START + MAGIC_LENGTH)
#define MAGIC_BYTE 0x7B
#define DATA_START 0x22C
void usage(const char* argv[])
{
cout << "Usage: " << argv[0] << " e <encrypted_file> <decrypted_file> <output_file>" << endl;
cout << " " << argv[0] << " d <encrypted_file> <decrpyted_file>" << endl;
}
int main(int argc, const char* argv[])
{
bool decrypt = false;
if (argc < 4)
{
usage(argv);
return -1;
}
decrypt = strcmp(argv[1], "d") == 0;
cout << ((decrypt) ? "Decryption Mode." : "Re-encryption mode.") << endl;
if (!decrypt)
{
if (argc < 5)
{
usage(argv);
return -1;
}
}
const char* encrypted_file_name = argv[2];
const char* decrypted_file_name = argv[3];
const char* out_name = argv[(decrypt)? 3 : 4];
ifstream encrypted(encrypted_file_name, ifstream::binary);
ifstream decrypted;
ofstream out(out_name, ofstream::binary);
size_t length = 0;
if (decrypt)
{
encrypted.seekg(0, ios_base::end);
length = encrypted.tellg() - (size_t)DATA_START;
if (length < DATA_START)
{
cout << "ERROR: Encrypted file too short, only " << length << " bytes." << endl;
return -1;
}
else
{
cout << "Reading " << length << " bytes from " << encrypted_file_name << "." << endl;
}
}
else
{
// re-encrpyting
decrypted.open(decrypted_file_name, ifstream::binary);
decrypted.seekg(0, ios_base::end);
length = decrypted.tellg();
cout << "Reading " << length << " bytes from " << decrypted_file_name << "." << endl;
}
if (!decrypt)
{
// Seek to start to copy the header.
cout << "Writing header..." << endl;
encrypted.seekg(0, ios_base::beg);
char header[HEADER_LENGTH];
encrypted.read(header, HEADER_LENGTH);
out.write(header, HEADER_LENGTH);
for (size_t i = HEADER_LENGTH; i < DATA_START; ++i) {
out.put('\0');
}
cout << "Inserted " << DATA_START - HEADER_LENGTH << " padding bytes." << endl;
cout << "Done" << endl;
}
// Seek to magic to copy the magic.
cout << "Reading magic..." << endl;
char magic[MAGIC_LENGTH];
encrypted.seekg(MAGIC_START, ios_base::beg);
encrypted.read(magic, MAGIC_LENGTH);
cout << "Done" << endl;
// Read remainder of file (all at once... hopefully it's small).
cout << "Copying remaining data into memory..." << endl;
char *data = new char[length];
if (decrypt)
{
encrypted.seekg(DATA_START, ios_base::beg);
encrypted.read(data, length);
encrypted.close();
cout << "Copied " << length << " bytes from offset 0x" << hex << DATA_START << endl;
}
else
{
decrypted.seekg(0, ios_base::beg);
decrypted.read(data, length);
decrypted.close();
cout << "Copied " << length << " bytes from offset 0x0" << endl;
}
cout << "Done" << endl;
// Decrypt data.
cout << "Decrypting data..." << std::endl;
for (size_t i = 0; i < length; ++i)
{
data[i] = data[i] ^ magic[i%MAGIC_LENGTH] ^ MAGIC_BYTE;
}
cout << "Done" << endl;
// Write decrypted data to output file.
cout << "Writing decrypted data to disk..." << endl;
out.write(data, length);
out.close();
cout << "Done" << endl;
delete [] data;
data = NULL;
return 0;
}