Update string decrypter

This commit is contained in:
de4dot 2012-12-14 09:22:36 +01:00
parent bbbdf0b0ff
commit bbb715c93c

View File

@ -158,7 +158,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
ushort[] encryptedData; ushort[] encryptedData;
short[] key; short[] key;
int keyShift; int keyShift;
bool isTrial; DecryptType decryptType;
// This'll do for now. Code should be added to detect the constants in the code.
enum DecryptType {
Type1,
Type2,
Type3,
}
class ArrayInfo { class ArrayInfo {
public int sizeInElems; public int sizeInElems;
@ -238,7 +245,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
encryptedData = new ushort[arrayInfo.initField.InitialValue.Length / 2]; encryptedData = new ushort[arrayInfo.initField.InitialValue.Length / 2];
Buffer.BlockCopy(arrayInfo.initField.InitialValue, 0, encryptedData, 0, arrayInfo.initField.InitialValue.Length); Buffer.BlockCopy(arrayInfo.initField.InitialValue, 0, encryptedData, 0, arrayInfo.initField.InitialValue.Length);
isTrial = !DeobUtils.hasInteger(Method, 0xFFF0); decryptType = getDecryptType(Method);
keyShift = findKeyShift(cctor); keyShift = findKeyShift(cctor);
key = findKey(); key = findKey();
if (key == null || key.Length == 0) if (key == null || key.Length == 0)
@ -247,6 +254,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
return true; return true;
} }
static DecryptType getDecryptType(MethodDef method) {
if (DeobUtils.hasInteger(method, 0xFFF0))
return DecryptType.Type2;
if (DeobUtils.hasInteger(method, 0xFFC0))
return DecryptType.Type3;
return DecryptType.Type1; // trial
}
int findKeyShift(MethodDef method) { int findKeyShift(MethodDef method) {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 3; i++) { for (int i = 0; i < instrs.Count - 3; i++) {
@ -342,9 +357,19 @@ namespace de4dot.code.deobfuscators.DeepSea {
} }
public string decrypt(object[] args) { public string decrypt(object[] args) {
if (isTrial) switch (decryptType) {
case DecryptType.Type1:
return decryptTrial((int)args[arg1], (int)args[arg2]); return decryptTrial((int)args[arg1], (int)args[arg2]);
return decryptRetail((int)args[arg1], (int)args[arg2]);
case DecryptType.Type2:
return decryptRetail2((int)args[arg1], (int)args[arg2]);
case DecryptType.Type3:
return decryptRetail3((int)args[arg1], (int)args[arg2]);
default:
throw new ApplicationException("Unknown type");
}
} }
string decryptTrial(int magic2, int magic3) { string decryptTrial(int magic2, int magic3) {
@ -359,13 +384,21 @@ namespace de4dot.code.deobfuscators.DeepSea {
return sb.ToString(); return sb.ToString();
} }
string decryptRetail(int magic2, int magic3) { string decryptRetail2(int magic2, int magic3) {
return decryptRetail(magic2, magic3, 2, 1, 0, 8, 0);
}
string decryptRetail3(int magic2, int magic3) {
return decryptRetail(magic2, magic3, 0, 2, 1, 0x20, 17);
}
string decryptRetail(int magic2, int magic3, int keyCharOffs, int cachedIndexOffs, int flagsOffset, int flag, int keyDispl) {
int offset = magic ^ magic2 ^ magic3; int offset = magic ^ magic2 ^ magic3;
var keyChar = encryptedData[offset + 2]; var keyChar = encryptedData[offset + keyCharOffs];
int cachedIndex = encryptedData[offset + 1] ^ keyChar; int cachedIndex = encryptedData[offset + cachedIndexOffs] ^ keyChar;
int flags = encryptedData[offset] ^ keyChar; int flags = encryptedData[offset + flagsOffset] ^ keyChar;
int numChars = (flags >> 1) & ~7 | (flags & 7); int numChars = ((flags >> 1) & ~(flag - 1)) | (flags & (flag - 1));
if ((flags & 8) != 0) { if ((flags & flag) != 0) {
numChars <<= 15; numChars <<= 15;
numChars |= encryptedData[offset + 3] ^ keyChar; numChars |= encryptedData[offset + 3] ^ keyChar;
offset++; offset++;
@ -373,7 +406,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
offset += 3; offset += 3;
var sb = new StringBuilder(numChars); var sb = new StringBuilder(numChars);
for (int i = 0; i < numChars; i++) for (int i = 0; i < numChars; i++)
sb.Append((char)(keyChar ^ encryptedData[offset + numChars - i - 1] ^ key[(i + 1 + offset) % key.Length])); sb.Append((char)(keyChar ^ encryptedData[offset + numChars - i - 1] ^ key[(i + 1 + keyDispl + offset) % key.Length]));
return sb.ToString(); return sb.ToString();
} }