byte[] Unpack2(MyPEImage peImage) { shouldUnpack = false; uint headerOffset = (uint)peImage.Length - 12; uint offsetEncryptedAssembly = CheckOffset(peImage, peImage.OffsetReadUInt32(headerOffset)); uint ezencryptionLibLength = peImage.OffsetReadUInt32(headerOffset + 4); uint iniFileLength = peImage.OffsetReadUInt32(headerOffset + 8); uint offsetClrVersionNumber = checked (offsetEncryptedAssembly - 12); uint iniFileOffset = checked (headerOffset - iniFileLength); uint ezencryptionLibOffset = checked (iniFileOffset - ezencryptionLibLength); uint clrVerMajor = peImage.OffsetReadUInt32(offsetClrVersionNumber); uint clrVerMinor = peImage.OffsetReadUInt32(offsetClrVersionNumber + 4); uint clrVerBuild = peImage.OffsetReadUInt32(offsetClrVersionNumber + 8); if (clrVerMajor <= 0 || clrVerMajor >= 20 || clrVerMinor >= 20 || clrVerBuild >= 1000000) { return(null); } var settings = new IniFile(Decompress2(peImage.OffsetReadBytes(iniFileOffset, (int)iniFileLength))); sizes = GetSizes(settings["General_App_Satellite_Assemblies_Sizes"]); if (sizes == null || sizes.Length <= 1) { return(null); } shouldUnpack = true; if (sizes[0] != offsetEncryptedAssembly) { return(null); } filenames = settings["General_App_Satellite_Assemblies"].Split('|'); if (sizes.Length - 1 != filenames.Length) { return(null); } byte[] ezencryptionLibData = Decompress1(peImage.OffsetReadBytes(ezencryptionLibOffset, (int)ezencryptionLibLength)); var ezencryptionLibModule = ModuleDefMD.Load(ezencryptionLibData); var decrypter = new ApplicationModeDecrypter(ezencryptionLibModule); if (!decrypter.Detected) { return(null); } var mainAssembly = UnpackEmbeddedFile(peImage, 0, decrypter); decrypter.MemoryPatcher.Patch(mainAssembly.data); for (int i = 1; i < filenames.Length; i++) { satelliteAssemblies.Add(UnpackEmbeddedFile(peImage, i, decrypter)); } ClearDllBit(mainAssembly.data); return(mainAssembly.data); }
void ReadCodeHeader(uint offset) { codeHeader.signature = peImage.OffsetReadBytes(offset, 16); codeHeader.decryptionKey = peImage.OffsetReadBytes(offset + 0x10, 16); codeHeader.totalCodeSize = peImage.OffsetReadUInt32(offset + 0x20); codeHeader.numMethods = peImage.OffsetReadUInt32(offset + 0x24); codeHeader.methodDefTableOffset = peImage.OffsetReadUInt32(offset + 0x28); codeHeader.methodDefElemSize = peImage.OffsetReadUInt32(offset + 0x2C); }
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 PeHeader(MainType mainType, MyPEImage peImage) { version = GetHeaderOffsetAndVersion(peImage, out uint headerOffset); headerData = peImage.OffsetReadBytes(headerOffset, 0x1000); // MC uses 4-byte xorKey, 2 Hex for 1 Byte GuessXorKey(false, peImage, 4); switch (version) { case EncryptionVersion.V1: case EncryptionVersion.V2: case EncryptionVersion.V3: case EncryptionVersion.V4: case EncryptionVersion.V5: default: xorKey = 0x7ABF931; break; case EncryptionVersion.V6: xorKey = 0x7ABA931; break; case EncryptionVersion.V7: xorKey = 0x8ABA931; break; case EncryptionVersion.V8: if (CheckMcKeyRva(peImage, 0x99BA9A13)) break; if (CheckMcKeyRva(peImage, 0x18ABA931)) break; if (CheckMcKeyRva(peImage, 0x18ABA933)) break; break; } }
public PeHeader(MainType mainType, MyPEImage peImage) { uint headerOffset; version = GetHeaderOffsetAndVersion(peImage, out headerOffset); headerData = peImage.OffsetReadBytes(headerOffset, 0x1000); switch (version) { case EncryptionVersion.V1: case EncryptionVersion.V2: case EncryptionVersion.V3: case EncryptionVersion.V4: case EncryptionVersion.V5: default: xorKey = 0x7ABF931; break; case EncryptionVersion.V6: xorKey = 0x7ABA931; break; case EncryptionVersion.V7: xorKey = 0x8ABA931; break; case EncryptionVersion.V8: if (CheckMcKeyRva(peImage, 0x99BA9A13)) break; if (CheckMcKeyRva(peImage, 0x18ABA931)) break; if (CheckMcKeyRva(peImage, 0x18ABA933)) break; break; } }
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) { byte[] data = peImage.OffsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize); for (int i = 0; i < data.Length; i++) { byte b = data[i]; b ^= codeHeader.decryptionKey[(methodInfo.codeOffs - codeHeaderSize + i) % 16]; b ^= codeHeader.decryptionKey[(methodInfo.codeOffs - codeHeaderSize + i + 7) % 16]; data[i] = b; } return(GetCodeBytes(data, out code, out extraSections)); }
byte[] GetKeyData() { isNet1x = false; for (int i = 0; i < baseOffsets.Length; i++) { var code = peImage.OffsetReadBytes(baseOffsets[i], decryptMethodPattern.Length); if (DeobUtils.IsCode(decryptMethodPattern, code)) { return(GetKeyData(baseOffsets[i])); } } var net1xCode = peImage.OffsetReadBytes(0x207E0, startMethodNet1xPattern.Length); if (DeobUtils.IsCode(startMethodNet1xPattern, net1xCode)) { isNet1x = true; return(new byte[6] { 0x34, 0x38, 0x63, 0x65, 0x7A, 0x35 }); } return(null); }
public static bool Detect(MyPEImage peImage) { try { uint codeHeaderOffset = GetCodeHeaderOffset(peImage); if (IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16))) { return(true); } } catch { } try { uint codeHeaderOffset = GetOldCodeHeaderOffset(peImage); if (codeHeaderOffset != 0 && IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16))) { return(true); } } catch { } return(false); }
UnpackedFile UnpackEmbeddedFile(MyPEImage peImage, int index, ApplicationModeDecrypter decrypter) { uint offset = 0; for (int i = 0; i < index + 1; i++) { offset += sizes[i]; } string filename = Win32Path.GetFileName(filenames[index]); var data = peImage.OffsetReadBytes(offset, (int)sizes[index + 1]); data = DeobUtils.AesDecrypt(data, decrypter.AssemblyKey, decrypter.AssemblyIv); data = Decompress(data); return(new UnpackedFile(filename, data)); }
public PeHeader(MainType mainType, MyPEImage peImage) { uint headerOffset; version = GetHeaderOffsetAndVersion(peImage, out headerOffset); headerData = peImage.OffsetReadBytes(headerOffset, 0x1000); switch (version) { case EncryptionVersion.V1: case EncryptionVersion.V2: case EncryptionVersion.V3: case EncryptionVersion.V4: case EncryptionVersion.V5: default: xorKey = 0x7ABF931; break; case EncryptionVersion.V6: xorKey = 0x7ABA931; break; case EncryptionVersion.V7: xorKey = 0x8ABA931; break; case EncryptionVersion.V8: if (CheckMcKeyRva(peImage, 0x99BA9A13)) { break; } if (CheckMcKeyRva(peImage, 0x18ABA931)) { break; } if (CheckMcKeyRva(peImage, 0x18ABA933)) { break; } break; } }
byte[] ReadData(uint offset, int size) => peImage.OffsetReadBytes(encryptedDataOffset + offset, size);
UnpackedFile UnpackEmbeddedFile(MyPEImage peImage, int index, ApplicationModeDecrypter decrypter) { uint offset = 0; for (int i = 0; i < index + 1; i++) offset += sizes[i]; string filename = Win32Path.GetFileName(filenames[index]); var data = peImage.OffsetReadBytes(offset, (int)sizes[index + 1]); data = DeobUtils.AesDecrypt(data, decrypter.AssemblyKey, decrypter.AssemblyIv); data = Decompress(data); return new UnpackedFile(filename, data); }
byte[] Unpack2(MyPEImage peImage) { shouldUnpack = false; uint headerOffset = (uint)peImage.Length - 12; uint offsetEncryptedAssembly = CheckOffset(peImage, peImage.OffsetReadUInt32(headerOffset)); uint ezencryptionLibLength = peImage.OffsetReadUInt32(headerOffset + 4); uint iniFileLength = peImage.OffsetReadUInt32(headerOffset + 8); uint offsetClrVersionNumber = checked(offsetEncryptedAssembly - 12); uint iniFileOffset = checked(headerOffset - iniFileLength); uint ezencryptionLibOffset = checked(iniFileOffset - ezencryptionLibLength); uint clrVerMajor = peImage.OffsetReadUInt32(offsetClrVersionNumber); uint clrVerMinor = peImage.OffsetReadUInt32(offsetClrVersionNumber + 4); uint clrVerBuild = peImage.OffsetReadUInt32(offsetClrVersionNumber + 8); if (clrVerMajor <= 0 || clrVerMajor >= 20 || clrVerMinor >= 20 || clrVerBuild >= 1000000) return null; var settings = new IniFile(Decompress2(peImage.OffsetReadBytes(iniFileOffset, (int)iniFileLength))); sizes = GetSizes(settings["General_App_Satellite_Assemblies_Sizes"]); if (sizes == null || sizes.Length <= 1) return null; shouldUnpack = true; if (sizes[0] != offsetEncryptedAssembly) return null; filenames = settings["General_App_Satellite_Assemblies"].Split('|'); if (sizes.Length - 1 != filenames.Length) return null; byte[] ezencryptionLibData = Decompress1(peImage.OffsetReadBytes(ezencryptionLibOffset, (int)ezencryptionLibLength)); var ezencryptionLibModule = ModuleDefMD.Load(ezencryptionLibData); var decrypter = new ApplicationModeDecrypter(ezencryptionLibModule); if (!decrypter.Detected) return null; var mainAssembly = UnpackEmbeddedFile(peImage, 0, decrypter); decrypter.MemoryPatcher.Patch(mainAssembly.data); for (int i = 1; i < filenames.Length; i++) satelliteAssemblies.Add(UnpackEmbeddedFile(peImage, i, decrypter)); ClearDllBit(mainAssembly.data); return mainAssembly.data; }
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; }
byte[] ReadData(uint offset, int size) { return(peImage.OffsetReadBytes(encryptedDataOffset + offset, size)); }
public static bool Detect(MyPEImage peImage) { try { uint codeHeaderOffset = GetCodeHeaderOffset(peImage); if (IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16))) return true; } catch { } try { uint codeHeaderOffset = GetOldCodeHeaderOffset(peImage); if (codeHeaderOffset != 0 && IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16))) return true; } catch { } return false; }