Detect DNR version
This commit is contained in:
parent
efe98949b1
commit
2ede24598d
|
@ -60,6 +60,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
|
|
||||||
class Deobfuscator : DeobfuscatorBase {
|
class Deobfuscator : DeobfuscatorBase {
|
||||||
Options options;
|
Options options;
|
||||||
|
string obfuscatorName = ".NET Reactor";
|
||||||
|
|
||||||
PE.PeImage peImage;
|
PE.PeImage peImage;
|
||||||
byte[] fileData;
|
byte[] fileData;
|
||||||
|
@ -78,7 +79,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name {
|
public override string Name {
|
||||||
get { return ".NET Reactor"; }
|
get { return obfuscatorName; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Deobfuscator(Options options)
|
public Deobfuscator(Options options)
|
||||||
|
@ -113,9 +114,79 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
methodsDecrypter = new MethodsDecrypter(module);
|
methodsDecrypter = new MethodsDecrypter(module);
|
||||||
methodsDecrypter.find();
|
methodsDecrypter.find();
|
||||||
stringDecrypter = new StringDecrypter(module);
|
stringDecrypter = new StringDecrypter(module);
|
||||||
stringDecrypter.find();
|
stringDecrypter.find(DeobfuscatedFile);
|
||||||
booleanDecrypter = new BooleanDecrypter(module);
|
booleanDecrypter = new BooleanDecrypter(module);
|
||||||
booleanDecrypter.find();
|
booleanDecrypter.find();
|
||||||
|
obfuscatorName = detectVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
string detectVersion() {
|
||||||
|
/*
|
||||||
|
Methods decrypter locals (not showing its own types):
|
||||||
|
3.7.0.3:
|
||||||
|
"System.Byte[]"
|
||||||
|
"System.Int32"
|
||||||
|
"System.Int32[]"
|
||||||
|
"System.IntPtr"
|
||||||
|
"System.IO.BinaryReader"
|
||||||
|
"System.IO.MemoryStream"
|
||||||
|
"System.Object"
|
||||||
|
"System.Reflection.Assembly"
|
||||||
|
"System.Security.Cryptography.CryptoStream"
|
||||||
|
"System.Security.Cryptography.ICryptoTransform"
|
||||||
|
"System.Security.Cryptography.RijndaelManaged"
|
||||||
|
"System.String"
|
||||||
|
|
||||||
|
3.9.8.0:
|
||||||
|
- "System.Int32[]"
|
||||||
|
+ "System.Diagnostics.StackFrame"
|
||||||
|
|
||||||
|
4.3.1.0 (jitter):
|
||||||
|
- "System.Diagnostics.StackFrame"
|
||||||
|
- "System.Object"
|
||||||
|
+ "System.Boolean"
|
||||||
|
+ "System.Byte&"
|
||||||
|
+ "System.Collections.IEnumerator"
|
||||||
|
+ "System.Delegate"
|
||||||
|
+ "System.Diagnostics.Process"
|
||||||
|
+ "System.Diagnostics.ProcessModule"
|
||||||
|
+ "System.Diagnostics.ProcessModuleCollection"
|
||||||
|
+ "System.IDisposable"
|
||||||
|
+ "System.Int64"
|
||||||
|
+ "System.UInt32"
|
||||||
|
+ "System.UInt64"
|
||||||
|
*/
|
||||||
|
|
||||||
|
LocalTypes localTypes;
|
||||||
|
int minVer = -1;
|
||||||
|
foreach (var info in stringDecrypter.DecrypterInfos) {
|
||||||
|
if (info.key == null)
|
||||||
|
continue;
|
||||||
|
localTypes = new LocalTypes(info.method);
|
||||||
|
if (!localTypes.exists("System.IntPtr"))
|
||||||
|
return ".NET Reactor <= 3.7";
|
||||||
|
minVer = 3800;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (methodsDecrypter.MethodsDecrypterMethod == null) {
|
||||||
|
if (minVer >= 3800)
|
||||||
|
return ".NET Reactor >= 3.8";
|
||||||
|
return ".NET Reactor";
|
||||||
|
}
|
||||||
|
localTypes = new LocalTypes(methodsDecrypter.MethodsDecrypterMethod);
|
||||||
|
|
||||||
|
if (localTypes.exists("System.Int32[]")) {
|
||||||
|
if (minVer >= 3800)
|
||||||
|
return ".NET Reactor 3.8.4.1 - 3.9.0.1";
|
||||||
|
return ".NET Reactor <= 3.9.0.1";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localTypes.exists("System.Diagnostics.StackFrame"))
|
||||||
|
return ".NET Reactor 3.9.8.0 - 4.2";
|
||||||
|
if (!localTypes.exists("System.Byte&"))
|
||||||
|
return ".NET Reactor 4.0-4.2";
|
||||||
|
return ".NET Reactor 4.3-4.4";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool getDecryptedModule(ref byte[] newFileData, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
|
public override bool getDecryptedModule(ref byte[] newFileData, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
|
||||||
|
|
|
@ -101,9 +101,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
var methodsData = encryptedResource.decrypt();
|
var methodsData = encryptedResource.decrypt();
|
||||||
|
|
||||||
ArrayFinder arrayFinder = new ArrayFinder(encryptedResource.ResourceDecrypterMethod);
|
ArrayFinder arrayFinder = new ArrayFinder(encryptedResource.ResourceDecrypterMethod);
|
||||||
bool hasJitter = arrayFinder.exists(new byte[] { (byte)'g', (byte)'e', (byte)'t', (byte)'J', (byte)'i', (byte)'t' });
|
bool hooksJitter = arrayFinder.exists(new byte[] { (byte)'g', (byte)'e', (byte)'t', (byte)'J', (byte)'i', (byte)'t' });
|
||||||
|
|
||||||
if (useXorKey) {
|
if (useXorKey) {
|
||||||
|
// DNR 4.3, 4.4
|
||||||
var stream = new MemoryStream(methodsData);
|
var stream = new MemoryStream(methodsData);
|
||||||
var reader = new BinaryReader(stream);
|
var reader = new BinaryReader(stream);
|
||||||
var writer = new BinaryWriter(stream);
|
var writer = new BinaryWriter(stream);
|
||||||
|
@ -135,7 +136,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
patchDwords(peImage, methodsDataReader, numDwords / 2);
|
patchDwords(peImage, methodsDataReader, numDwords / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!hasJitter || mode == 1) {
|
else if (!hooksJitter || mode == 1) {
|
||||||
// DNR 3.9.8.0, 4.0, 4.1, 4.2, 4.3, 4.4
|
// DNR 3.9.8.0, 4.0, 4.1, 4.2, 4.3, 4.4
|
||||||
patchDwords(peImage, methodsDataReader, patchCount);
|
patchDwords(peImage, methodsDataReader, patchCount);
|
||||||
while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) {
|
while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) {
|
||||||
|
@ -147,7 +148,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// DNR 4.4 (jitter is hooked)
|
// DNR (4.0-4.2?), 4.3, 4.4 (jitter is hooked)
|
||||||
|
|
||||||
var metadataTables = peImage.Cor20Header.createMetadataTables();
|
var metadataTables = peImage.Cor20Header.createMetadataTables();
|
||||||
var methodDef = metadataTables.getMetadataType(PE.MetadataIndex.iMethodDef);
|
var methodDef = metadataTables.getMetadataType(PE.MetadataIndex.iMethodDef);
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void find() {
|
public void find(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
var additionalTypes = new string[] {
|
var additionalTypes = new string[] {
|
||||||
"System.String",
|
"System.String",
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,12 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
|
|
||||||
stringsResource = resource;
|
stringsResource = resource;
|
||||||
encryptedResource.ResourceDecrypterMethod = method;
|
encryptedResource.ResourceDecrypterMethod = method;
|
||||||
decrypterInfos.Add(new DecrypterInfo(method, null, null));
|
|
||||||
|
var info = new DecrypterInfo(method, null, null);
|
||||||
|
simpleDeobfuscator.deobfuscate(info.method);
|
||||||
|
findKeyIv(info.method, out info.key, out info.iv);
|
||||||
|
|
||||||
|
decrypterInfos.Add(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,12 +154,9 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
this.peImage = peImage;
|
this.peImage = peImage;
|
||||||
this.fileData = fileData;
|
this.fileData = fileData;
|
||||||
|
|
||||||
foreach (var info in decrypterInfos) {
|
|
||||||
simpleDeobfuscator.deobfuscate(info.method);
|
|
||||||
findKeyIv(info.method, out info.key, out info.iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptedResource.init(simpleDeobfuscator);
|
encryptedResource.init(simpleDeobfuscator);
|
||||||
|
if (encryptedResource.EncryptedDataResource != null)
|
||||||
|
Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(encryptedResource.EncryptedDataResource.Name));
|
||||||
decryptedData = encryptedResource.decrypt();
|
decryptedData = encryptedResource.decrypt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user