-
Notifications
You must be signed in to change notification settings - Fork 2
/
PurgeEvasionUtils.c
164 lines (136 loc) · 5.19 KB
/
PurgeEvasionUtils.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**
* PurgeEvasionUtils.h
* Data cipher based on purge encryption
* and evasion in mode pseudo-rand generator.
* Data hash based on evasion
* Author Kucheruavyu Ilya ([email protected])
* 06/02/2015 Ukraine Kharkiv
* _ _ _ _
* | | (_|_) |
* | | _____ _ _| |__ __ _
* | |/ / _ \| | | '_ \ / _` |
* | < (_) | | | |_) | (_| |
* |_|\_\___/| |_|_.__/ \__,_|
* _/ |
* |__/
**/
#include "PurgeEvasionUtils.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#pragma GCC push_options
#pragma GCC optimize ("O0")
#ifndef nil
#define nil ((void*)0)
#endif
#ifndef forAll
#define forAll(iterator, count) for(iterator = 0; iterator < (count); ++iterator)
#endif
void evasionHashData(const void *text, uint64_t size, uint64_t *outputHash) {
uint64_t iterator;
uint64_t hashTemp[8] = {};
uint8_t half = evasionBytesCount / 2;
uint64_t hashCount = size / half;
uint64_t addition = size % half;
forAll(iterator, hashCount) {
memcpy((uint8_t*) &hashTemp[0] + half, text + iterator * half, half);
evasionRand(hashTemp);
}
if(addition) {
memcpy((uint8_t*) hashTemp + half, text + hashCount * half, addition);
memset((uint8_t*) hashTemp + half + addition, 0, half - addition);
evasionRand(hashTemp);
}
// final
memcpy(outputHash, hashTemp, evasionBytesCount);
}
void* encryptPurgeEvasion(const void *text, uint64_t size, uint64_t key[8], uint64_t *cryptedSize) { // key changed and data not
uint64_t iterator;
uint8_t *textTemp = nil;
uint64_t totalSize = size + sizeof(uint64_t);
uint64_t cipherCount = totalSize / purgeBytesCount;
uint64_t addition = totalSize % purgeBytesCount;
uint64_t hash[8];
uint8_t keyTemp[purgeBytesCount];
if(addition != 0) {
totalSize += purgeBytesCount - addition;
++cipherCount;
}
textTemp = malloc(totalSize);
if(textTemp != nil) {
*cryptedSize = 0;
memcpy(textTemp, &size, sizeof(uint64_t)); // add size in front
memcpy(textTemp + sizeof(uint64_t), text, size); // copy other text
if (addition != 0) { // add some zeros if needed
memset(textTemp + size + sizeof(uint64_t), 0, purgeBytesCount - addition);
}
evasionHashData(textTemp + sizeof(uint64_t), totalSize - sizeof(uint64_t), (uint64_t *)hash); // hash data with padding
forAll(iterator, cipherCount) { // pure crypt with key
evasionRand(key);
memcpy(keyTemp, key, purgeBytesCount);
purgeEncrypt((uint64_t *) (textTemp + iterator * purgeBytesCount), (uint64_t*) keyTemp);
memset(keyTemp, 0, purgeBytesCount);
}
// crypt hash by last key
evasionRand(key);
memcpy(keyTemp, key, purgeBytesCount);
purgeEncrypt(hash, (uint64_t *) keyTemp);
memset(keyTemp, 0, purgeBytesCount);
// append hash
textTemp = realloc(textTemp, totalSize + evasionBytesCount);
if(textTemp != nil) {
memcpy(textTemp + totalSize, hash, evasionBytesCount); // append hash
*cryptedSize = totalSize; // store
*cryptedSize += evasionBytesCount;
}
}
return textTemp;
}
void* decryptPurgeEvasion(const void *text, uint64_t size, uint64_t key[8], uint64_t *encryptedSize) { // key changed and data not
uint64_t iterator;
uint8_t *textTemp = nil,
*plainText = nil;
uint64_t cipherCount = (size - evasionBytesCount) / purgeBytesCount;
uint64_t sizeOfText;
uint8_t keyTemp[purgeBytesCount];
uint64_t hash[8];
uint8_t *hashPtr = nil;
if(size % purgeBytesCount) {
perror("decryptPurgeEvasion. Bad data size. Must be multiple of 64. Data size in bytes\n");
return nil;
}
textTemp = malloc(size);
if(textTemp != nil) {
*encryptedSize = 0;
memcpy(textTemp, text, size);
hashPtr = (textTemp + size - evasionBytesCount);
forAll(iterator, cipherCount) {
evasionRand(key);
memcpy(keyTemp, key, purgeBytesCount);
purgeDecrypt((uint64_t *) (textTemp + iterator * purgeBytesCount), (uint64_t *) keyTemp);
memset(keyTemp, 0, purgeBytesCount);
}
// decrypt hash by last key
evasionRand(key);
memcpy(keyTemp, key, purgeBytesCount);
purgeDecrypt((uint64_t *) hashPtr, (uint64_t *) keyTemp);
memset(keyTemp, 0, purgeBytesCount);
// get hash of decrypted
evasionHashData(textTemp + sizeof(uint64_t), size - evasionBytesCount - sizeof(uint64_t), (uint64_t *)hash);
// check hash
if(memcmp(hash, hashPtr, evasionBytesCount) == 0) {
// get size
memcpy((uint8_t*) &sizeOfText, textTemp, sizeof(uint64_t));
plainText = malloc(sizeOfText);
if(plainText != nil) {
memcpy(plainText, textTemp + sizeof(uint64_t), sizeOfText);
*encryptedSize = sizeOfText; // store
}
} else {
perror("decryptPurgeEvasion. Hashes isn't equal. Can't decrypt data, must be bad key\n");
}
free(textTemp);
}
return plainText;
}
#pragma GCC pop_options