Decrypt methods sent to the JITter
This commit is contained in:
parent
c4d6ba9ae9
commit
0a8d772c22
|
@ -20,6 +20,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.deobfuscators.dotNET_Reactor {
|
namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
|
@ -117,7 +118,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
booleanDecrypter.find();
|
booleanDecrypter.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] getDecryptedModule() {
|
public override bool getDecryptedModule(ref byte[] newFileData, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
|
||||||
using (var fileStream = new FileStream(module.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
|
using (var fileStream = new FileStream(module.FullyQualifiedName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
|
||||||
fileData = new byte[(int)fileStream.Length];
|
fileData = new byte[(int)fileStream.Length];
|
||||||
fileStream.Read(fileData, 0, fileData.Length);
|
fileStream.Read(fileData, 0, fileData.Length);
|
||||||
|
@ -125,12 +126,13 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
peImage = new PE.PeImage(fileData);
|
peImage = new PE.PeImage(fileData);
|
||||||
|
|
||||||
if (!options.DecryptMethods)
|
if (!options.DecryptMethods)
|
||||||
return null;
|
return false;
|
||||||
|
|
||||||
if (!methodsDecrypter.decrypt(peImage, DeobfuscatedFile))
|
if (!methodsDecrypter.decrypt(peImage, DeobfuscatedFile, ref dumpedMethods))
|
||||||
return null;
|
return false;
|
||||||
|
|
||||||
return fileData;
|
newFileData = fileData;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IDeobfuscator moduleReloaded(ModuleDefinition module) {
|
public override IDeobfuscator moduleReloaded(ModuleDefinition module) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.deobfuscators.dotNET_Reactor {
|
namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
|
@ -91,7 +92,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
encryptedResource.ResourceDecrypterMethod = (MethodDefinition)callCounter.most();
|
encryptedResource.ResourceDecrypterMethod = (MethodDefinition)callCounter.most();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool decrypt(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator) {
|
public bool decrypt(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
|
||||||
if (encryptedResource.ResourceDecrypterMethod == null)
|
if (encryptedResource.ResourceDecrypterMethod == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -119,8 +120,8 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
int tmp = methodsDataReader.ReadInt32();
|
int tmp = methodsDataReader.ReadInt32();
|
||||||
methodsDataReader.BaseStream.Position -= 4;
|
methodsDataReader.BaseStream.Position -= 4;
|
||||||
if ((tmp & 0xFF000000) == 0x06000000) {
|
if ((tmp & 0xFF000000) == 0x06000000) {
|
||||||
// It's method token + rva. DNR 3.7.0.3 - 3.9.0.1
|
// It's method token + rva. DNR 3.7.0.3 (and earlier?) - 3.9.0.1
|
||||||
methodsDataReader.BaseStream.Position += 8 * patchCount;
|
methodsDataReader.BaseStream.Position += 8L * patchCount;
|
||||||
patchCount = methodsDataReader.ReadInt32();
|
patchCount = methodsDataReader.ReadInt32();
|
||||||
mode = methodsDataReader.ReadInt32();
|
mode = methodsDataReader.ReadInt32();
|
||||||
|
|
||||||
|
@ -131,17 +132,87 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
||||||
patchDwords(peImage, methodsDataReader, numDwords / 2);
|
patchDwords(peImage, methodsDataReader, numDwords / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (!useXorKey || mode == 1) {
|
||||||
// DNR 3.9.8.0, 4.0, 4.1, 4.2
|
// 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) {
|
||||||
uint rva = methodsDataReader.ReadUInt32();
|
uint rva = methodsDataReader.ReadUInt32();
|
||||||
uint token = methodsDataReader.ReadUInt32();
|
uint token = methodsDataReader.ReadUInt32(); // token, unknown, or index
|
||||||
int size = methodsDataReader.ReadInt32();
|
int size = methodsDataReader.ReadInt32();
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
peImage.dotNetSafeWrite(rva, methodsDataReader.ReadBytes(size));
|
peImage.dotNetSafeWrite(rva, methodsDataReader.ReadBytes(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// DNR 4.4 (jitter is hooked)
|
||||||
|
|
||||||
|
var metadataTables = peImage.Cor20Header.createMetadataTables();
|
||||||
|
var methodDef = metadataTables.getMetadataType(PE.MetadataIndex.iMethodDef);
|
||||||
|
var rvaToIndex = new Dictionary<uint, int>((int)methodDef.rows);
|
||||||
|
uint offset = methodDef.fileOffset;
|
||||||
|
for (int i = 0; i < methodDef.rows; i++) {
|
||||||
|
uint rva = peImage.offsetReadUInt32(offset);
|
||||||
|
offset += methodDef.totalSize;
|
||||||
|
if (rva == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((peImage.readByte(rva) & 3) == 2)
|
||||||
|
rva++;
|
||||||
|
else
|
||||||
|
rva += (uint)(4 * (peImage.readByte(rva + 1) >> 4));
|
||||||
|
rvaToIndex[rva] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
patchDwords(peImage, methodsDataReader, patchCount);
|
||||||
|
int count = methodsDataReader.ReadInt32();
|
||||||
|
dumpedMethods = new Dictionary<uint, DumpedMethod>();
|
||||||
|
while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) {
|
||||||
|
uint rva = methodsDataReader.ReadUInt32();
|
||||||
|
uint index = methodsDataReader.ReadUInt32();
|
||||||
|
bool isNativeCode = index >= 0x70000000;
|
||||||
|
int size = methodsDataReader.ReadInt32();
|
||||||
|
var methodData = methodsDataReader.ReadBytes(size);
|
||||||
|
|
||||||
|
int methodIndex;
|
||||||
|
if (!rvaToIndex.TryGetValue(rva, out methodIndex)) {
|
||||||
|
Log.w("Could not find method having code RVA {0:X8}", rva);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNativeCode) {
|
||||||
|
//TODO: Convert to CIL code
|
||||||
|
Log.w("Found native code. Ignoring it for now... Assembly won't run. token: {0:X8}", 0x06000001 + methodIndex);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var dm = new DumpedMethod();
|
||||||
|
dm.token = (uint)(0x06000001 + methodIndex);
|
||||||
|
dm.code = methodData;
|
||||||
|
|
||||||
|
offset = methodDef.fileOffset + (uint)(methodIndex * methodDef.totalSize);
|
||||||
|
rva = peImage.offsetReadUInt32(offset);
|
||||||
|
dm.mdImplFlags = peImage.offsetReadUInt16(offset + (uint)methodDef.fields[1].offset);
|
||||||
|
dm.mdFlags = peImage.offsetReadUInt16(offset + (uint)methodDef.fields[2].offset);
|
||||||
|
dm.mdName = peImage.offsetRead(offset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size);
|
||||||
|
dm.mdSignature = peImage.offsetRead(offset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size);
|
||||||
|
dm.mdParamList = peImage.offsetRead(offset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size);
|
||||||
|
|
||||||
|
if ((peImage.readByte(rva) & 3) == 2) {
|
||||||
|
dm.mhFlags = 2;
|
||||||
|
dm.mhMaxStack = 8;
|
||||||
|
dm.mhCodeSize = (uint)dm.code.Length;
|
||||||
|
dm.mhLocalVarSigTok = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dm.mhFlags = peImage.readUInt16(rva);
|
||||||
|
dm.mhMaxStack = peImage.readUInt16(rva + 2);
|
||||||
|
dm.mhCodeSize = (uint)dm.code.Length;
|
||||||
|
dm.mhLocalVarSigTok = peImage.readUInt32(rva + 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpedMethods[dm.token] = dm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user