void DecryptMethodsOld(MDTable methodDefTable, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); var decrypter = new Decrypter10(peImage, codeHeader.decryptionKey); for (uint rid = 1; rid <= methodDefTable.Rows; rid++) { var dm = new DumpedMethod(); var method = (MethodDef)module.ResolveMethod(rid); if (method == null || method.DeclaringType == module.GlobalType) { continue; } peImage.ReadMethodTableRowTo(dm, rid); if (dm.mdRVA == 0) { continue; } uint bodyOffset = peImage.RvaToOffset(dm.mdRVA); var mbHeader = decrypter.Decrypt(bodyOffset, out dm.code, out dm.extraSections); peImage.UpdateMethodHeaderInfo(dm, mbHeader); dumpedMethods.Add(dm); } }
DecryptResult decrypt2(ref DumpedMethods dumpedMethods) { uint codeHeaderOffset = initializeCodeHeader(); if (sigType == SigType.Unknown) { return(DecryptResult.NotEncrypted); } var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDefTable = metadataTables.getMetadataType(MetadataIndex.iMethodDef); foreach (var version in getCsHeaderVersions(codeHeaderOffset, methodDefTable)) { try { if (version == CsHeaderVersion.V10) { decryptMethodsOld(methodDefTable, ref dumpedMethods); } else { decryptMethods(codeHeaderOffset, methodDefTable, createCsHeader(version), ref dumpedMethods); } return(DecryptResult.Decrypted); } catch { } } return(DecryptResult.Error); }
void DecryptMethods(uint codeHeaderOffset, MDTable methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) { var methodInfos = csHeader.GetMethodInfos(codeHeaderOffset); csHeader.PatchMethodTable(methodDefTable, methodInfos); dumpedMethods = new DumpedMethods(); decrypter = csHeader.CreateDecrypter(); for (uint rid = 1; rid <= (uint)methodInfos.Count; rid++) { var methodInfo = methodInfos[(int)rid - 1]; if (methodInfo.codeOffs == 0) { continue; } var dm = new DumpedMethod(); peImage.ReadMethodTableRowTo(dm, rid); var mbHeader = decrypter.Decrypt(methodInfo, out dm.code, out dm.extraSections); peImage.UpdateMethodHeaderInfo(dm, mbHeader); dumpedMethods.Add(dm); } }
public bool decrypt(byte[] fileData, ref DumpedMethods dumpedMethods) { if (decrypter == null) { return(false); } var peImage = new PeImage(fileData); if (peImage.Sections.Length <= 0) { return(false); } var methodsData = findMethodsData(peImage, fileData); if (methodsData == null) { return(false); } decrypter.initialize(methodsData); dumpedMethods = createDumpedMethods(peImage, fileData, methodsData); if (dumpedMethods == null) { return(false); } return(true); }
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if ((decryptState & DecryptState.CanDecryptMethods) != 0) { if (DecryptModule(ref newFileData, ref dumpedMethods)) { ModuleBytes = newFileData; decryptState &= ~DecryptState.CanDecryptMethods; return(true); } } if (options.DecryptMainAsm && (decryptState & DecryptState.CanGetMainAssembly) != 0) { newFileData = GetMainAssemblyBytes(); if (newFileData != null) { ModuleBytes = newFileData; decryptState &= ~DecryptState.CanGetMainAssembly; decryptState |= DecryptState.CanDecryptMethods; return(true); } } return(false); }
public bool Decrypt(byte[] fileData, ref DumpedMethods dumpedMethods) { if (decrypter == null) { return(false); } using (var peImage = new MyPEImage(fileData)) { if (peImage.Sections.Count <= 0) { return(false); } var methodsData = FindMethodsData(peImage, fileData); if (methodsData == null) { return(false); } decrypter.Initialize(methodsData); dumpedMethods = CreateDumpedMethods(peImage, fileData, methodsData); if (dumpedMethods == null) { return(false); } } return(true); }
public DumpedMethods decryptMethods() { if (!canDecryptMethods()) { throw new ApplicationException("Can't decrypt methods since compileMethod() isn't hooked yet"); } installCompileMethod2(); var dumpedMethods = new DumpedMethods(); if (decryptMethodsInfo.methodsToDecrypt == null) { for (uint rid = 1; rid <= methodDefTable.Rows; rid++) { dumpedMethods.add(decryptMethod(0x06000000 + rid)); } } else { foreach (var token in decryptMethodsInfo.methodsToDecrypt) { dumpedMethods.add(decryptMethod(token)); } } return(dumpedMethods); }
public bool Decrypt(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { if (initMethod == null) { return(false); } switch (version) { case ConfuserVersion.v17_r73404: return(Decrypt_v17_r73404(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v17_r73430: return(Decrypt_v17_r73404(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v17_r73477: return(Decrypt_v17_r73477(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v17_r73479: return(Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v17_r74021: return(Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v18_r75257: return(Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v18_r75288: return(Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v18_r75291: return(Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v18_r75402: return(Decrypt_v18_r75402(peImage, fileData, ref dumpedMethods)); case ConfuserVersion.v19_r75725: return(Decrypt_v18_r75402(peImage, fileData, ref dumpedMethods)); default: throw new ApplicationException("Unknown version"); } }
DecryptResult Decrypt2(ref DumpedMethods dumpedMethods) { uint codeHeaderOffset = InitializeCodeHeader(); if (sigType == SigType.Unknown) { return(DecryptResult.NotEncrypted); } var methodDefTable = peImage.MetaData.TablesStream.MethodTable; foreach (var version in GetCsHeaderVersions(codeHeaderOffset, methodDefTable)) { try { if (version == CsHeaderVersion.V10) { DecryptMethodsOld(methodDefTable, ref dumpedMethods); } else { DecryptMethods(codeHeaderOffset, methodDefTable, CreateCsHeader(version), ref dumpedMethods); } return(DecryptResult.Decrypted); } catch { } } return(DecryptResult.Error); }
DumpedMethodsRestorer CreateDumpedMethodsRestorer(DumpedMethods dumpedMethods) { if (dumpedMethods == null || dumpedMethods.Count == 0) { return(null); } return(new DumpedMethodsRestorer(dumpedMethods)); }
DumpedMethods CreateDumpedMethods(MyPEImage peImage, byte[] fileData, byte[] methodsData) { var dumpedMethods = new DumpedMethods(); var methodsDataReader = MemoryImageStream.Create(methodsData); var fileDataReader = MemoryImageStream.Create(fileData); var methodDef = peImage.MetaData.TablesStream.MethodTable; for (uint rid = 1; rid <= methodDef.Rows; rid++) { var dm = new DumpedMethod(); peImage.ReadMethodTableRowTo(dm, rid); if (dm.mdRVA == 0) { continue; } uint bodyOffset = peImage.RvaToOffset(dm.mdRVA); byte b = peImage.OffsetReadByte(bodyOffset); uint codeOffset; if ((b & 3) == 2) { if (b != 2) { continue; // not zero byte code size } dm.mhFlags = 2; dm.mhMaxStack = 8; dm.mhLocalVarSigTok = 0; codeOffset = bodyOffset + 1; } else { if (peImage.OffsetReadUInt32(bodyOffset + 4) != 0) { continue; // not zero byte code size } dm.mhFlags = peImage.OffsetReadUInt16(bodyOffset); dm.mhMaxStack = peImage.OffsetReadUInt16(bodyOffset + 2); dm.mhLocalVarSigTok = peImage.OffsetReadUInt32(bodyOffset + 8); codeOffset = bodyOffset + (uint)(dm.mhFlags >> 12) * 4; } fileDataReader.Position = codeOffset; if (!decrypter.Decrypt(fileDataReader, dm)) { continue; } dumpedMethods.Add(dm); } return(dumpedMethods); }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !assemblyDecrypter.EncryptedDetected) { return(false); } newFileData = assemblyDecrypter.decrypt(); return(newFileData != null); }
void reloadModule(byte[] newModuleData, DumpedMethods dumpedMethods) { Log.v("Reloading decrypted assembly (original filename: {0})", Filename); simpleDeobfuscatorFlags.Clear(); module = assemblyModule.reload(newModuleData, dumpedMethods); deob = deob.moduleReloaded(module); initializeDeobfuscator(); deob.DeobfuscatedFile = this; updateDynamicStringInliner(); }
bool Decrypt_v18_r75402(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { if (peImage.OptionalHeader.CheckSum == 0) { return(false); } methodsData = DecryptMethodsData_v17_r73404(peImage); dumpedMethods = Decrypt_v18_r75402(peImage, fileData); return(dumpedMethods != null); }
void ReloadModule(byte[] newModuleData, DumpedMethods dumpedMethods) { Logger.v("Reloading decrypted assembly (original filename: {0})", Filename); simpleDeobfuscatorFlags.Clear(); using (var oldModule = module) { module = assemblyModule.Reload(newModuleData, CreateDumpedMethodsRestorer(dumpedMethods), deob as IStringDecrypter); deob = deob.ModuleReloaded(module); } InitializeDeobfuscator(); deob.DeobfuscatedFile = this; UpdateDynamicStringInliner(); }
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || version == Version.Unknown) { return(false); } byte[] fileData = ModuleBytes ?? DeobUtils.ReadModule(Module); byte[] decompressed; using (var peImage = new MyPEImage(fileData)) { var section = peImage.Sections[peImage.Sections.Count - 1]; var offset = section.PointerToRawData; offset += 16; byte[] compressed; int compressedLen; switch (version) { case Version.V0x: compressedLen = fileData.Length - (int)offset; compressed = peImage.OffsetReadBytes(offset, compressedLen); decompressed = Lzmat.DecompressOld(compressed); if (decompressed == null) { throw new ApplicationException("LZMAT decompression failed"); } break; case Version.V1x_217: case Version.V218: if (peImage.PEImage.ImageNTHeaders.FileHeader.Machine == Machine.AMD64 && version == Version.V218) { offset = section.PointerToRawData + section.VirtualSize; } int decompressedLen = (int)peImage.OffsetReadUInt32(offset); compressedLen = fileData.Length - (int)offset - 4; compressed = peImage.OffsetReadBytes(offset + 4, compressedLen); decompressed = new byte[decompressedLen]; uint decompressedLen2; if (Lzmat.Decompress(decompressed, out decompressedLen2, compressed) != LzmatStatus.OK) { throw new ApplicationException("LZMAT decompression failed"); } break; default: throw new ApplicationException("Unknown MPRESS version"); } } newFileData = decompressed; return(true); }
public bool Decrypt(ref DumpedMethods dumpedMethods) { dumpedMethods = DecryptMethods(); if (dumpedMethods == null) { return(false); } DecryptResources(); DecryptStrings(); return(true); }
public bool decrypt(PeImage peImage, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); bool decrypted = false; var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); uint methodDefOffset = methodDef.fileOffset; for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); if (bodyRva == 0) continue; uint bodyOffset = peImage.rvaToOffset(bodyRva); var dm = new DumpedMethod(); dm.token = (uint)(0x06000001 + i); byte[] code, extraSections; peImage.Reader.BaseStream.Position = bodyOffset; var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections); if (code.Length < 6 || code[0] != 0x2A || code[1] != 0x2A) continue; dm.code = code; dm.extraSections = extraSections; int seed = BitConverter.ToInt32(code, 2); Array.Copy(newCodeHeader, code, newCodeHeader.Length); if (seed == 0) decrypt(code); else decrypt(code, seed); dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); dm.mhFlags = mbHeader.flags; dm.mhMaxStack = mbHeader.maxStack; dm.mhCodeSize = (uint)dm.code.Length; dm.mhLocalVarSigTok = mbHeader.localVarSigTok; dumpedMethods.add(dm); decrypted = true; } return decrypted; }
public void deobfuscate() { Log.n("Cleaning {0}", options.Filename); initAssemblyClient(); byte[] fileData = null; DumpedMethods dumpedMethods = null; if (deob.getDecryptedModule(ref fileData, ref dumpedMethods)) { reloadModule(fileData, dumpedMethods); } deob.deobfuscateBegin(); deobfuscateMethods(); deob.deobfuscateEnd(); }
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !NeedsPatching()) { return(false); } var fileData = ModuleBytes ?? DeobUtils.ReadModule(module); if (!decrypterType.Patch(fileData)) { return(false); } newFileData = fileData; return(true); }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !methodsDecrypter.Detected) { return(false); } var fileData = DeobUtils.readModule(module); if (!methodsDecrypter.decrypt(fileData, ref dumpedMethods)) { return(false); } newFileData = fileData; return(true); }
public bool decrypt(MyPEImage peImage, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); bool decrypted = false; var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable; for (uint rid = 1; rid <= methodDef.Rows; rid++) { var dm = new DumpedMethod(); peImage.readMethodTableRowTo(dm, rid); if (dm.mdRVA == 0) { continue; } uint bodyOffset = peImage.rvaToOffset(dm.mdRVA); peImage.Reader.Position = bodyOffset; var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out dm.code, out dm.extraSections); peImage.updateMethodHeaderInfo(dm, mbHeader); if (dm.code.Length < 6 || dm.code[0] != 0x2A || dm.code[1] != 0x2A) { continue; } int seed = BitConverter.ToInt32(dm.code, 2); Array.Copy(newCodeHeader, dm.code, newCodeHeader.Length); if (seed == 0) { decrypt(dm.code); } else { decrypt(dm.code, seed); } dumpedMethods.add(dm); decrypted = true; } return(decrypted); }
bool DecryptModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!methodsDecrypter.Detected) { return(false); } byte[] fileData = ModuleBytes ?? DeobUtils.ReadModule(module); using (var peImage = new MyPEImage(fileData)) { if (!methodsDecrypter.Decrypt(peImage, ref dumpedMethods)) { return(false); } } newFileData = fileData; return(true); }
public bool decrypt(byte[] fileData, ref DumpedMethods dumpedMethods) { peImage = new PeImage(fileData); peHeader = new PeHeader(mainType, peImage); mcKey = new McKey(peImage, peHeader); this.fileData = fileData; dumpedMethods = decryptMethods(); if (dumpedMethods == null) { return(false); } decryptResources(); decryptStrings(); return(true); }
public override bool getDecryptedModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!needsPatching()) { return(false); } var fileData = ModuleBytes ?? DeobUtils.readModule(module); var peImage = new PeImage(fileData); if (!decrypterType.patch(peImage)) { return(false); } newFileData = fileData; return(true); }
public override bool getDecryptedModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!mainType.Detected) { return(false); } var fileDecrypter = new FileDecrypter(mainType); var fileData = DeobUtils.readModule(module); if (!fileDecrypter.decrypt(fileData, ref dumpedMethods)) { return(false); } newFileData = fileData; return(true); }
public override bool getDecryptedModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!options.DecryptMethods) { return(false); } byte[] fileData = DeobUtils.readModule(module); var peImage = new PeImage(fileData); if (!new MethodsDecrypter().decrypt(peImage, module.FullyQualifiedName, cliSecureRtType, ref dumpedMethods)) { Log.v("Methods aren't encrypted or invalid signature"); return(false); } newFileData = fileData; return(true); }
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !options.DecryptMethods) { return(false); } byte[] fileData = ModuleBytes ?? DeobUtils.ReadModule(Module); using (var peImage = new MyPEImage(fileData)) { if (!new MethodsDecrypter().Decrypt(peImage, Module, cliSecureRtType, ref dumpedMethods)) { Logger.v("Methods aren't encrypted or invalid signature"); return(false); } } newFileData = fileData; return(true); }
public void Deobfuscate() { Logger.n("Cleaning {0}", options.Filename); InitAssemblyClient(); for (int i = 0; ; i++) { byte[] fileData = null; DumpedMethods dumpedMethods = null; if (!deob.GetDecryptedModule(i, ref fileData, ref dumpedMethods)) { break; } ReloadModule(fileData, dumpedMethods); } deob.DeobfuscateBegin(); DeobfuscateMethods(); deob.DeobfuscateEnd(); }
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !mainType.Detected) { return(false); } var fileData = DeobUtils.ReadModule(module); decrypterInfo = new DecrypterInfo(mainType, fileData); var methodsDecrypter = new MethodsDecrypter(module, decrypterInfo); if (!methodsDecrypter.Decrypt(ref dumpedMethods)) { return(false); } newFileData = fileData; return(true); }
DumpedMethods Decrypt_v17_r73404(MyPEImage peImage, byte[] fileData) { var dumpedMethods = new DumpedMethods(); var methodDef = peImage.Metadata.TablesStream.MethodTable; for (uint rid = 1; rid <= methodDef.Rows; rid++) { var dm = new DumpedMethod(); peImage.ReadMethodTableRowTo(dm, rid); if (dm.mdRVA == 0) { continue; } uint bodyOffset = peImage.RvaToOffset(dm.mdRVA); if (!IsEncryptedMethod(fileData, (int)bodyOffset)) { continue; } int key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6); int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key; int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key; var codeData = DecryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len); var reader = ByteArrayDataReaderFactory.CreateReader(codeData); var mbHeader = MethodBodyParser.ParseMethodBody(ref reader, out dm.code, out dm.extraSections); if (reader.Position != reader.Length) { throw new ApplicationException("Invalid method data"); } peImage.UpdateMethodHeaderInfo(dm, mbHeader); dumpedMethods.Add(dm); } return(dumpedMethods); }
public bool decrypt(PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref DumpedMethods dumpedMethods, Dictionary<uint, byte[]> tokenToNativeCode) { if (encryptedResource.Method == null) return false; encryptedResource.init(simpleDeobfuscator); if (!encryptedResource.FoundResource) return false; var methodsData = encryptedResource.decrypt(); bool hooksJitter = findDnrCompileMethod(encryptedResource.Method.DeclaringType) != null; xorKey = getXorKey(); xorEncrypt(methodsData); var methodsDataReader = new BinaryReader(new MemoryStream(methodsData)); int patchCount = methodsDataReader.ReadInt32(); int mode = methodsDataReader.ReadInt32(); int tmp = methodsDataReader.ReadInt32(); methodsDataReader.BaseStream.Position -= 4; if ((tmp & 0xFF000000) == 0x06000000) { // It's method token + rva. DNR 3.7.0.3 (and earlier?) - 3.9.0.1 methodsDataReader.BaseStream.Position += 8L * patchCount; patchCount = methodsDataReader.ReadInt32(); mode = methodsDataReader.ReadInt32(); patchDwords(peImage, methodsDataReader, patchCount); while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) { uint token = methodsDataReader.ReadUInt32(); int numDwords = methodsDataReader.ReadInt32(); patchDwords(peImage, methodsDataReader, numDwords / 2); } } else if (!hooksJitter || mode == 1) { // DNR 3.9.8.0, 4.0, 4.1, 4.2, 4.3, 4.4 patchDwords(peImage, methodsDataReader, patchCount); while (methodsDataReader.BaseStream.Position < methodsData.Length - 1) { uint rva = methodsDataReader.ReadUInt32(); uint token = methodsDataReader.ReadUInt32(); // token, unknown, or index int size = methodsDataReader.ReadInt32(); if (size > 0) peImage.dotNetSafeWrite(rva, methodsDataReader.ReadBytes(size)); } } else { // DNR 4.0 - 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 DumpedMethods(); 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; } uint methodToken = 0x06000001 + (uint)methodIndex; if (isNativeCode) { totalEncryptedNativeMethods++; if (tokenToNativeCode != null) tokenToNativeCode[methodToken] = methodData; // Convert return true / false methods. The others are converted to // throw 0xDEADCODE. if (DeobUtils.isCode(nativeLdci4, methodData)) { uint val = BitConverter.ToUInt32(methodData, 4); // ldc.i4 XXXXXXXXh / ret methodData = new byte[] { 0x20, 0, 0, 0, 0, 0x2A }; methodData[1] = (byte)val; methodData[2] = (byte)(val >> 8); methodData[3] = (byte)(val >> 16); methodData[4] = (byte)(val >> 24); } else if (DeobUtils.isCode(nativeLdci4_0, methodData)) { // ldc.i4.0 / ret methodData = new byte[] { 0x16, 0x2A }; } else { tokenToNativeMethod[methodToken] = methodData; // ldc.i4 0xDEADCODE / conv.u4 / throw methodData = new byte[] { 0x20, 0xDE, 0xC0, 0xAD, 0xDE, 0x6D, 0x7A }; } } var dm = new DumpedMethod(); dm.token = methodToken; 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.add(dm); } } return true; }
public bool decrypt(PeImage peImage, Mono.Cecil.ModuleDefinition module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) { this.peImage = peImage; this.csRtType = csRtType; this.module = module; switch (decrypt2(ref dumpedMethods)) { case DecryptResult.Decrypted: return true; case DecryptResult.NotEncrypted: return false; case DecryptResult.Error: Log.w("Using dynamic method decryption"); byte[] moduleCctorBytes = getModuleCctorBytes(csRtType); dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module.FullyQualifiedName, moduleCctorBytes); return true; default: throw new ApplicationException("Invalid DecryptResult"); } }
public bool decrypt(byte[] fileData, ref DumpedMethods dumpedMethods) { if (decrypter == null) return false; var peImage = new PeImage(fileData); if (peImage.Sections.Length <= 0) return false; var methodsData = findMethodsData(peImage, fileData); if (methodsData == null) return false; decrypter.initialize(methodsData); dumpedMethods = createDumpedMethods(peImage, fileData, methodsData); if (dumpedMethods == null) return false; return true; }
void reloadModule(byte[] newModuleData, DumpedMethods dumpedMethods) { Log.v("Reloading decrypted assembly (original filename: {0})", Filename); simpleDeobfuscatorFlags.Clear(); module = assemblyModule.reload(newModuleData, dumpedMethods); allMethods = getAllMethods(); deob = deob.moduleReloaded(module); initializeDeobfuscator(); deob.DeobfuscatedFile = this; updateDynamicStringInliner(); }
public override bool getDecryptedModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!needsPatching()) return false; var fileData = ModuleBytes ?? DeobUtils.readModule(module); var peImage = new PeImage(fileData); if (!decrypterType.patch(peImage)) return false; newFileData = fileData; return true; }
public override bool getDecryptedModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!methodsDecrypter.Detected) return false; var fileData = DeobUtils.readModule(module); if (!methodsDecrypter.decrypt(fileData, ref dumpedMethods)) return false; newFileData = fileData; return true; }
void decryptMethods(uint codeHeaderOffset, MetadataType methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) { var methodInfos = csHeader.getMethodInfos(codeHeaderOffset); csHeader.patchMethodDefTable(methodDefTable, methodInfos); dumpedMethods = new DumpedMethods(); uint offset = methodDefTable.fileOffset; decrypter = csHeader.createDecrypter(); for (int i = 0; i < methodInfos.Count; i++, offset += methodDefTable.totalSize) { var methodInfo = methodInfos[i]; if (methodInfo.codeOffs == 0) continue; var dm = new DumpedMethod(); dm.token = 0x06000001 + (uint)i; dm.mdImplFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[2].offset); dm.mdName = peImage.offsetRead(offset + (uint)methodDefTable.fields[3].offset, methodDefTable.fields[3].size); dm.mdSignature = peImage.offsetRead(offset + (uint)methodDefTable.fields[4].offset, methodDefTable.fields[4].size); dm.mdParamList = peImage.offsetRead(offset + (uint)methodDefTable.fields[5].offset, methodDefTable.fields[5].size); var mbHeader = decrypter.decrypt(methodInfo, out dm.code, out dm.extraSections); dm.mhFlags = mbHeader.flags; dm.mhMaxStack = mbHeader.maxStack; dm.mhCodeSize = (uint)dm.code.Length; dm.mhLocalVarSigTok = mbHeader.localVarSigTok; dumpedMethods.add(dm); } }
DecryptResult decrypt2(ref DumpedMethods dumpedMethods) { uint codeHeaderOffset = initializeCodeHeader(); if (sigType == SigType.Unknown) return DecryptResult.NotEncrypted; var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDefTable = metadataTables.getMetadataType(MetadataIndex.iMethodDef); foreach (var version in getCsHeaderVersions(codeHeaderOffset, methodDefTable)) { try { if (version == CsHeaderVersion.V10) decryptMethodsOld(methodDefTable, ref dumpedMethods); else decryptMethods(codeHeaderOffset, methodDefTable, createCsHeader(version), ref dumpedMethods); return DecryptResult.Decrypted; } catch { } } return DecryptResult.Error; }
bool decryptModule(ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (!methodsDecrypter.Detected) return false; byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module); var peImage = new PeImage(fileData); if (!methodsDecrypter.decrypt(peImage, ref dumpedMethods)) return false; newFileData = fileData; return true; }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if ((decryptState & DecryptState.CanDecryptMethods) != 0) { if (decryptModule(ref newFileData, ref dumpedMethods)) { ModuleBytes = newFileData; decryptState &= ~DecryptState.CanDecryptMethods; return true; } } if (options.DecryptMainAsm && (decryptState & DecryptState.CanGetMainAssembly) != 0) { newFileData = getMainAssemblyBytes(); if (newFileData != null) { ModuleBytes = newFileData; decryptState &= ~DecryptState.CanGetMainAssembly; decryptState |= DecryptState.CanDecryptMethods; return true; } } return false; }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !options.DecryptMethods) return false; byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module); var peImage = new PeImage(fileData); if (!new MethodsDecrypter().decrypt(peImage, module, cliSecureRtType, ref dumpedMethods)) { Log.v("Methods aren't encrypted or invalid signature"); return false; } newFileData = fileData; return true; }
void decryptMethodsOld(MetadataType methodDefTable, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); uint offset = methodDefTable.fileOffset; var decrypter = new Decrypter10(peImage, codeHeader.decryptionKey); for (int i = 0; i < methodDefTable.rows; i++, offset += methodDefTable.totalSize) { var dm = new DumpedMethod(); dm.token = 0x06000001 + (uint)i; var method = (Mono.Cecil.MethodDefinition)module.LookupToken((int)dm.token); if (method == null || method.DeclaringType == DotNetUtils.getModuleType(module)) continue; uint rva = peImage.offsetReadUInt32(offset + (uint)methodDefTable.fields[0].offset); if (rva == 0) continue; uint bodyOffset = peImage.rvaToOffset(rva); dm.mdImplFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[2].offset); dm.mdName = peImage.offsetRead(offset + (uint)methodDefTable.fields[3].offset, methodDefTable.fields[3].size); dm.mdSignature = peImage.offsetRead(offset + (uint)methodDefTable.fields[4].offset, methodDefTable.fields[4].size); dm.mdParamList = peImage.offsetRead(offset + (uint)methodDefTable.fields[5].offset, methodDefTable.fields[5].size); var mbHeader = decrypter.decrypt(bodyOffset, out dm.code, out dm.extraSections); dm.mhFlags = mbHeader.flags; dm.mhMaxStack = mbHeader.maxStack; dm.mhCodeSize = (uint)dm.code.Length; dm.mhLocalVarSigTok = mbHeader.localVarSigTok; dumpedMethods.add(dm); } }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0) return false; fileData = ModuleBytes ?? DeobUtils.readModule(module); peImage = new PeImage(fileData); if (!options.DecryptMethods) return false; var tokenToNativeCode = new Dictionary<uint,byte[]>(); if (!methodsDecrypter.decrypt(peImage, DeobfuscatedFile, ref dumpedMethods, tokenToNativeCode)) return false; if (options.DumpNativeMethods) { using (var fileStream = new FileStream(module.FullyQualifiedName + ".native", FileMode.Create, FileAccess.Write, FileShare.Read)) { var sortedTokens = new List<uint>(tokenToNativeCode.Keys); sortedTokens.Sort(); var writer = new BinaryWriter(fileStream); var nops = new byte[] { 0x90, 0x90, 0x90, 0x90 }; foreach (var token in sortedTokens) { writer.Write((byte)0xB8); writer.Write(token); writer.Write(tokenToNativeCode[token]); writer.Write(nops); } } } newFileData = fileData; return true; }
DumpedMethods createDumpedMethods(PeImage peImage, byte[] fileData, byte[] methodsData) { var dumpedMethods = new DumpedMethods(); var methodsDataReader = new BinaryReader(new MemoryStream(methodsData)); var fileDataReader = new BinaryReader(new MemoryStream(fileData)); var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); uint methodDefOffset = methodDef.fileOffset; for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); if (bodyRva == 0) continue; uint bodyOffset = peImage.rvaToOffset(bodyRva); var dm = new DumpedMethod(); dm.token = (uint)(0x06000001 + i); dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); byte b = peImage.offsetReadByte(bodyOffset); uint codeOffset; if ((b & 3) == 2) { if (b != 2) continue; // not zero byte code size dm.mhFlags = 2; dm.mhMaxStack = 8; dm.mhLocalVarSigTok = 0; codeOffset = bodyOffset + 1; } else { if (peImage.offsetReadUInt32(bodyOffset + 4) != 0) continue; // not zero byte code size dm.mhFlags = peImage.offsetReadUInt16(bodyOffset); dm.mhMaxStack = peImage.offsetReadUInt16(bodyOffset + 2); dm.mhLocalVarSigTok = peImage.offsetReadUInt32(bodyOffset + 8); codeOffset = bodyOffset + (uint)(dm.mhFlags >> 12) * 4; } fileDataReader.BaseStream.Position = codeOffset; if (!decrypter.decrypt(fileDataReader, dm)) continue; dumpedMethods.add(dm); } return dumpedMethods; }
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { if (count != 0 || !assemblyDecrypter.EncryptedDetected) return false; newFileData = assemblyDecrypter.decrypt(); return newFileData != null; }