-
Notifications
You must be signed in to change notification settings - Fork 534
/
XORSelection.1sc
226 lines (205 loc) · 6.68 KB
/
XORSelection.1sc
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
//------------------------------------------------
//--- 010 Editor Script File
//
// File: XORSelection.1sc
// Authors: Didier Stevens
// Version: 6.0
// Purpose: Xors the current selection with a set of bytes,
// which causes the bytes to be encoded so they
// cannot be read by a human. Run the Xor again on
// the encoded selection to decode the data.
// Category: Binary
// History:
// 6.0 2020-11-04 D Stevens: added option c
// 5.0 2020-05-07 D Stevens: added options
// 4.0 2018-03-25 D Stevens: refactoring to handle keys with null bytes and hex keys with whitespace
// 3.1 2016-02-10 SweetScape Software: Updated header for repository submission.
// 3.0 2014-12-11 D Stevens: Added hex processing; refactoring
// 1.0 2009-05-26 D Stevens: start
//
// Source code put in public domain by Didier Stevens, no Copyright
// https://DidierStevens.com
// Use at your own risk
//------------------------------------------------
#define TITLE "XORSelection"
unsigned int uiOptionsReverse = 0;
unsigned int uiOptionsLiteral = 0;
int iOptionsShift = 0;
unsigned int uiOptionsChangeKeyWithValueBeforeXOR = 0;
unsigned int uiOptionsChangeKeyWithValueAfterXOR = 0;
int HexDigitToInt(int digit)
{
if (digit >= '0' && digit <= '9')
return digit - '0';
if (digit >= 'a' && digit <= 'f')
return digit - 'a' + 10;
if (digit >= 'A' && digit <= 'F')
return digit - 'A' + 10;
return -1;
}
string RemoveWhitespace(string sInput)
{
int iIter;
string sResult = "";
for (iIter = 0; iIter < Strlen(sInput); iIter++)
if (sInput[iIter] != ' ' && sInput[iIter] != '\n' && sInput[iIter] != '\r' && sInput[iIter] != '\t')
sResult = sResult + sInput[iIter];
return sResult;
}
unsigned int CalculateKeyIndex(int iIter, int iKeyLength)
{
if (1 == uiOptionsReverse)
return iKeyLength - 1 - (iIter + iOptionsShift) % iKeyLength;
else
return (iIter + iOptionsShift) % iKeyLength;
}
unsigned int ParseOptions(string sInput)
{
string sOption;
unsigned int uiReturn = 0;
uiOptionsReverse = 0;
uiOptionsLiteral = 0;
iOptionsShift = 0;
uiOptionsChangeKeyWithValueBeforeXOR = 0;
uiOptionsChangeKeyWithValueAfterXOR = 0;
while (sInput != "")
{
sOption = SubStr(sInput, 0, 1);
sInput = SubStr(sInput, 1);
if ("r" == sOption)
uiOptionsReverse = 1;
else if ("l" == sOption)
uiOptionsLiteral = 1;
else if ("s" == sOption)
{
int iSign = 1;
if ('-' == sInput[0])
{
sInput = SubStr(sInput, 1);
iSign = -1;
}
iOptionsShift = 0;
while (sInput[0] >= '0' && sInput[0] <= '9')
{
iOptionsShift = iOptionsShift * 10 + sInput[0] - '0';
sInput = SubStr(sInput, 1);
}
iOptionsShift = iOptionsShift * iSign;
}
else if ("c" == sOption)
{
if ('b' == sInput[0])
uiOptionsChangeKeyWithValueBeforeXOR = 1;
else if ('a' == sInput[0])
uiOptionsChangeKeyWithValueAfterXOR = 1;
else
uiReturn = 1;
sInput = SubStr(sInput, 1);
}
else
uiReturn = 1;
}
return uiReturn;
}
void Main(void)
{
int iIter, iStart, iSize, iKeyLength;
string sKey;
string sOptions;
uchar ucRead;
// Check that a file is open
if(FileCount() == 0)
{
MessageBox(idOk, TITLE, "XORSelection can only be executed when a file is loaded.");
return;
}
// Initializes the variables
iSize = GetSelSize();
iStart = GetSelStart();
// Check that bytes were selected
if(iSize == 0)
{
iSize = FileSize();
iStart = 0;
}
sOptions = "";
sKey = InputString(TITLE, "Input XOR key (start with 0x for hex), or leave empty for options", "");
if (sKey == "")
{
sOptions = InputString(TITLE, "Options (h for help)", "");
if (sOptions == "")
{
return;
}
else if (sOptions == "h")
{
MessageBox(idOk, TITLE, "r: reverse key\nl: literal key\ns: shift value (signed integer)\ncb: change key with value before XOR\nca: change key with value after XOR");
return;
}
if (ParseOptions(sOptions))
{
MessageBox(idOk, TITLE, "Please enter valid options.");
return;
}
sKey = InputString(TITLE, "Input the key (start with 0x for hex)", "");
if (sKey == "")
{
MessageBox(idOk, TITLE, "Please enter a valid key.");
return;
}
}
if (SubStr(sKey, 0, 2) == "0x" && 0 == uiOptionsLiteral)
{
string sHex = RemoveWhitespace(SubStr(sKey, 2));
int iIter2;
int iHexDigit1;
int iHexDigit2;
if (Strlen(sHex) % 2 != 0)
{
MessageBox(idOk, TITLE, "Please enter a valid hex value (uneven digits).");
return;
}
iKeyLength = Strlen(sHex) / 2;
if (iKeyLength == 0)
{
MessageBox(idOk, TITLE, "Please enter a valid hex value (no digits).");
return;
}
uchar aucKey[iKeyLength];
for (iIter2 = 0; iIter2 < Strlen(sHex); iIter2 += 2)
{
iHexDigit1 = HexDigitToInt(sHex[iIter2]);
if (iHexDigit1 == -1)
{
MessageBox(idOk, TITLE, "Please enter a valid hex value: digit %c is not hexadecimal.", sHex[iIter2]);
return;
}
iHexDigit2 = HexDigitToInt(sHex[iIter2 + 1]);
if (iHexDigit2 == -1)
{
MessageBox(idOk, TITLE, "Please enter a valid hex value: digit %c is not hexadecimal.", sHex[iIter2 + 1]);
return;
}
aucKey[iIter2 / 2] = iHexDigit1 * 0x10 + iHexDigit2;
}
}
else
{
string aucKey = sKey;
iKeyLength = Strlen(sKey);
}
if (iOptionsShift < 0)
iOptionsShift = (iOptionsShift % iKeyLength) + iKeyLength;
// Modify the selection
for (iIter = 0; iIter < iSize; iIter++)
{
// Modify the current byte
ucRead = ReadUByte(iStart + iIter);
WriteUByte(iStart + iIter, ucRead ^ aucKey[CalculateKeyIndex(iIter, iKeyLength)]);
if (1 == uiOptionsChangeKeyWithValueBeforeXOR)
aucKey[CalculateKeyIndex(iIter, iKeyLength)] = ucRead;
if (1 == uiOptionsChangeKeyWithValueAfterXOR)
aucKey[CalculateKeyIndex(iIter, iKeyLength)] = ucRead ^ aucKey[CalculateKeyIndex(iIter, iKeyLength)];
}
}
Main();