2011-12-01 01:28:48 +08:00
|
|
|
|
/*
|
2012-01-10 06:02:47 +08:00
|
|
|
|
Copyright (C) 2011-2012 de4dot@gmail.com
|
2011-12-01 01:28:48 +08:00
|
|
|
|
|
|
|
|
|
This file is part of de4dot.
|
|
|
|
|
|
|
|
|
|
de4dot is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
de4dot is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
|
2011-12-22 01:55:36 +08:00
|
|
|
|
namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
|
2011-12-01 01:28:48 +08:00
|
|
|
|
class NativeFileDecrypter {
|
|
|
|
|
byte[] key;
|
|
|
|
|
byte kb = 0;
|
|
|
|
|
byte[,] transform = new byte[256, 256];
|
|
|
|
|
|
|
|
|
|
public NativeFileDecrypter(byte[] keyData) {
|
|
|
|
|
var keyInit = new byte[] {
|
|
|
|
|
0x78, 0x61, 0x32, keyData[0], keyData[2],
|
|
|
|
|
0x62, keyData[3], keyData[0], keyData[1], keyData[1],
|
|
|
|
|
0x66, keyData[1], keyData[5], 0x33, keyData[2],
|
|
|
|
|
keyData[4], 0x74, 0x32, keyData[3], keyData[2],
|
|
|
|
|
};
|
|
|
|
|
key = new byte[32];
|
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
|
|
|
key[i] = (byte)(i + keyInit[i % keyInit.Length] * keyInit[((i + 0x0B) | 0x1F) % keyInit.Length]);
|
|
|
|
|
kb += key[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var transformTemp = new ushort[256, 256];
|
|
|
|
|
for (int i = 0; i < 256; i++)
|
|
|
|
|
for (int j = 0; j < 256; j++)
|
|
|
|
|
transformTemp[i, j] = 0x400;
|
|
|
|
|
int counter = 0x0B;
|
|
|
|
|
byte newByte = 0;
|
|
|
|
|
int ki = 0;
|
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
|
|
|
while (true) {
|
|
|
|
|
for (int j = key.Length - 1; j >= ki; j--)
|
|
|
|
|
newByte += (byte)(key[j] + counter);
|
|
|
|
|
bool done = true;
|
|
|
|
|
ki = (ki + 1) % key.Length;
|
|
|
|
|
for (int k = 0; k <= i; k++) {
|
|
|
|
|
if (newByte == transformTemp[k, 0]) {
|
|
|
|
|
done = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (done)
|
|
|
|
|
break;
|
|
|
|
|
counter++;
|
|
|
|
|
}
|
|
|
|
|
transformTemp[i, 0] = newByte;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
counter = ki = 0;
|
|
|
|
|
for (int i = 1; i < 256; i++) {
|
|
|
|
|
ki++;
|
|
|
|
|
int i1;
|
|
|
|
|
do {
|
|
|
|
|
counter++;
|
|
|
|
|
i1 = 1 + (this.key[(i + 37 + counter) % key.Length] + counter + kb) % 255;
|
|
|
|
|
} while (transformTemp[0, i1] != 0x400);
|
|
|
|
|
for (int i0 = 0; i0 < 256; i0++)
|
|
|
|
|
transformTemp[i0, i1] = transformTemp[(i0 + ki) % 256, 0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
|
|
|
for (int j = 0; j < 256; j++)
|
|
|
|
|
transform[(byte)transformTemp[i, j], j] = (byte)i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void decrypt(byte[] data, int offset, int count) {
|
|
|
|
|
for (int i = 0; i < count; i += 1024, offset += 1024) {
|
|
|
|
|
int blockLen = Math.Min(1024, count - i);
|
|
|
|
|
|
|
|
|
|
if (blockLen == 1) {
|
|
|
|
|
data[offset] = transform[data[offset], kb];
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < blockLen - 1; j++)
|
|
|
|
|
data[offset + j] = transform[data[offset + j], data[offset + j + 1]];
|
|
|
|
|
data[offset + blockLen - 1] = transform[data[offset + blockLen - 1], kb ^ 0x55];
|
|
|
|
|
|
|
|
|
|
for (int j = blockLen - 1; j > 0; j--)
|
|
|
|
|
data[offset + j] = transform[data[offset + j], data[offset + j - 1]];
|
|
|
|
|
data[offset] = transform[data[offset], kb];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|