예제 #1
0
        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");
            }
        }
예제 #2
0
        static EncryptionVersion GetHeaderOffsetAndVersion(MyPEImage peImage, out uint headerOffset)
        {
            headerOffset = 0;

            var version = GetVersion(peImage, headerOffset);

            if (version != EncryptionVersion.Unknown)
            {
                return(version);
            }

            var section = peImage.FindSection(".rsrc");

            if (section != null)
            {
                version = GetHeaderOffsetAndVersion(section, peImage, out headerOffset);
                if (version != EncryptionVersion.Unknown)
                {
                    return(version);
                }
            }

            foreach (var section2 in peImage.Sections)
            {
                version = GetHeaderOffsetAndVersion(section2, peImage, out headerOffset);
                if (version != EncryptionVersion.Unknown)
                {
                    return(version);
                }
            }

            return(EncryptionVersion.Unknown);
        }
예제 #3
0
		static void patchDwords(MyPEImage peImage, IBinaryReader reader, int count) {
			for (int i = 0; i < count; i++) {
				uint rva = reader.ReadUInt32();
				uint data = reader.ReadUInt32();
				peImage.dotNetSafeWrite(rva, BitConverter.GetBytes(data));
			}
		}
예제 #4
0
		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;
			}
		}
예제 #5
0
		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;
			}
		}
예제 #6
0
        protected byte[] DecryptMethodsData_v16_r71742(MyPEImage peImage, uint encryptedHeaderOffset)
        {
            uint mdRva = peImage.OptionalHeader.CheckSum ^ (uint)key0;

            if ((RVA)mdRva != peImage.Cor20Header.Metadata.VirtualAddress)
            {
                throw new ApplicationException("Invalid metadata rva");
            }
            var reader = peImage.Reader;

            reader.Position = encryptedHeaderOffset;
            ulong checkSum = reader.ReadUInt64() ^ lkey0;

            reader.ReadInt32();                 // strong name RVA
            reader.ReadInt32();                 // strong name len
            var iv            = reader.ReadBytes(reader.ReadInt32() ^ (int)key2);
            var encrypted     = reader.ReadBytes(reader.ReadInt32() ^ (int)key3);
            var streamsBuffer = GetStreamsBuffer(peImage);

            if (checkSum != CalcChecksum(streamsBuffer))
            {
                throw new ApplicationException("Invalid checksum. File has been modified.");
            }
            var decrypted = Decrypt(encrypted, iv, streamsBuffer);

            if (BitConverter.ToInt16(decrypted, 0) != 0x6FD6)
            {
                throw new ApplicationException("Invalid magic");
            }
            return(decrypted);
        }
예제 #7
0
        public byte[] Unpack()
        {
            byte[]    data      = null;
            MyPEImage myPeImage = null;

            try {
                myPeImage = new MyPEImage(peImage);
                data      = Unpack2(myPeImage);
            }
            catch {
            }
            finally {
                if (myPeImage != null)
                {
                    myPeImage.Dispose();
                }
            }
            if (data != null)
            {
                return(data);
            }

            if (shouldUnpack)
            {
                Logger.w("Could not unpack file: {0}", peImage.FileName ?? "(unknown filename)");
            }
            return(null);
        }
예제 #8
0
		public bool Decrypt(MyPEImage peImage, ref DumpedMethods dumpedMethods) {
			dumpedMethods = new DumpedMethods();

			bool decrypted = false;

			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);

				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;
		}
예제 #9
0
        bool DecryptImage_v14_r58004(MyPEImage peImage, byte[] fileData)
        {
            var reader = new BinaryReader(new MemoryStream(methodsData));

            reader.ReadInt16();                 // sig
            var writer   = new BinaryWriter(new MemoryStream(fileData));
            int numInfos = reader.ReadInt32();

            for (int i = 0; i < numInfos; i++)
            {
                uint offs = reader.ReadUInt32() ^ key4;
                if (offs == 0)
                {
                    continue;
                }
                uint rva = reader.ReadUInt32() ^ key4;
                if (peImage.RvaToOffset(rva) != offs)
                {
                    throw new ApplicationException("Invalid offs & rva");
                }
                writer.BaseStream.Position = peImage.RvaToOffset(rva);
                writer.Write(reader.ReadBytes(reader.ReadInt32()));
            }

            return(true);
        }
예제 #10
0
        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);
        }
예제 #11
0
        bool DecryptImage_v16_r71742(MyPEImage peImage, byte[] fileData)
        {
            var reader = new BinaryReader(new MemoryStream(methodsData));

            reader.ReadInt16();                 // sig
            int numInfos = reader.ReadInt32();

            for (int i = 0; i < numInfos; i++)
            {
                uint offs = reader.ReadUInt32() ^ key4;
                if (offs == 0)
                {
                    continue;
                }
                uint rva = reader.ReadUInt32() ^ key5;
                if (peImage.RvaToOffset(rva) != offs)
                {
                    throw new ApplicationException("Invalid offs & rva");
                }
                int len = reader.ReadInt32();
                for (int j = 0; j < len; j++)
                {
                    fileData[offs + j] = reader.ReadByte();
                }
            }
            return(true);
        }
예제 #12
0
        public bool Decrypt(MyPEImage peImage, byte[] fileData)
        {
            if (initMethod == null)
            {
                return(false);
            }

            switch (version)
            {
            case ConfuserVersion.v14_r57884: return(Decrypt_v14_r57884(peImage, fileData));

            case ConfuserVersion.v14_r58004: return(Decrypt_v14_r58004(peImage, fileData));

            case ConfuserVersion.v14_r58564: return(Decrypt_v14_r58004(peImage, fileData));

            case ConfuserVersion.v14_r58852: return(Decrypt_v14_r58004(peImage, fileData));

            case ConfuserVersion.v15_r59014: return(Decrypt_v15_r59014(peImage, fileData));

            case ConfuserVersion.v16_r71742: return(Decrypt_v16_r71742(peImage, fileData));

            case ConfuserVersion.v17_r72989: return(Decrypt_v16_r71742(peImage, fileData));

            case ConfuserVersion.v17_r73605: return(Decrypt_v17_r73605(peImage, fileData));

            case ConfuserVersion.v18_r75288: return(Decrypt_v17_r73605(peImage, fileData));

            case ConfuserVersion.v19_r75725: return(Decrypt_v17_r73605(peImage, fileData));

            default: throw new ApplicationException("Unknown version");
            }
        }
예제 #13
0
		public DecrypterInfo(MainType mainType, byte[] fileData) {
			this.mainType = mainType;
			this.peImage = new MyPEImage(fileData);
			this.peHeader = new PeHeader(mainType, peImage);
			this.mcKey = new McKey(peImage, peHeader);
			this.fileData = fileData;
		}
예제 #14
0
        bool CheckMcKeyRva(MyPEImage peImage, uint newXorKey)
        {
            xorKey = newXorKey;
            uint rva = GetMcKeyRva();

            return((rva & 0xFFF) == 0 && peImage.FindSection((RVA)rva) != null);
        }
예제 #15
0
        bool FindNativeCode(byte[] moduleBytes)
        {
            var bytes = moduleBytes != null ? moduleBytes : DeobUtils.ReadModule(module);

            using (var peImage = new MyPEImage(bytes))
                return(foundSig = MethodsDecrypter.Detect(peImage));
        }
예제 #16
0
        static EncryptionVersion getHeaderOffsetAndVersion(MyPEImage peImage, out uint headerOffset)
        {
            headerOffset = 0;

            var version = getVersion(peImage, headerOffset);

            if (version != EncryptionVersion.Unknown)
            {
                return(version);
            }

            var section = peImage.findSection(".rsrc");

            if (section == null)
            {
                return(EncryptionVersion.Unknown);
            }

            headerOffset = section.PointerToRawData;
            uint end = section.PointerToRawData + section.SizeOfRawData - 0x1000 + 1;

            while (headerOffset < end)
            {
                version = getVersion(peImage, headerOffset);
                if (version != EncryptionVersion.Unknown)
                {
                    return(version);
                }
                headerOffset++;
            }

            return(EncryptionVersion.Unknown);
        }
예제 #17
0
        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);
        }
예제 #18
0
 public ProDecrypter(MyPEImage peImage, CodeHeader codeHeader)
     : base(peImage, codeHeader)
 {
     for (int i = 0; i < 4; i++)
     {
         key[i] = ReadUInt32_be(codeHeader.decryptionKey, i * 4);
     }
 }
예제 #19
0
 public DecrypterInfo(MainType mainType, byte[] fileData)
 {
     this.mainType = mainType;
     peImage       = new MyPEImage(fileData);
     peHeader      = new PeHeader(mainType, peImage);
     mcKey         = new McKey(peImage, peHeader);
     this.fileData = fileData;
 }
예제 #20
0
 void FreePEImage()
 {
     if (peImage != null)
     {
         peImage.Dispose();
     }
     peImage = null;
 }
예제 #21
0
            public DecrypterBase(MyPEImage peImage, CodeHeader codeHeader)
            {
                this.peImage    = peImage;
                this.codeHeader = codeHeader;
                var mdDir = peImage.Cor20Header.MetaData;

                endOfMetadata = peImage.RvaToOffset((uint)mdDir.VirtualAddress + mdDir.Size);
            }
예제 #22
0
 uint CheckOffset(MyPEImage peImage, uint offset)
 {
     if (offset >= peImage.Length)
     {
         throw new Exception();
     }
     return(offset);
 }
예제 #23
0
		public McKey(MyPEImage peImage, PeHeader peHeader) {
			this.peHeader = peHeader;
			try {
				this.data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x2000);
			}
			catch (IOException) {
				this.data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x1000);
			}
		}
예제 #24
0
 public void Dispose()
 {
     if (peImage != null)
     {
         peImage.Dispose();
     }
     peImage = null;
     reader  = null;
 }
예제 #25
0
 public void patch(byte[] peImageData)
 {
     using (var peImage = new MyPEImage(peImageData)) {
         foreach (var info in patchInfos) {
             for (int i = 0; i < info.offsets.Length; i++)
                 peImage.dotNetSafeWriteOffset((uint)info.offsets[i], BitConverter.GetBytes(info.values[i]));
         }
     }
 }
예제 #26
0
        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);
        }
예제 #27
0
        byte[] FindMethodsData(MyPEImage peImage, byte[] fileData)
        {
            var section = peImage.Sections[0];

            var reader = MemoryImageStream.Create(fileData);

            const int RVA_EXECUTIVE_OFFSET = 1 * 4;
            const int ENC_CODE_OFFSET      = 6 * 4;
            int       lastOffset           = Math.Min(fileData.Length, (int)(section.PointerToRawData + section.SizeOfRawData));

            for (int offset = GetStartOffset(peImage); offset < lastOffset;)
            {
                offset = FindSig(fileData, offset, lastOffset, initializeMethodEnd);
                if (offset < 0)
                {
                    return(null);
                }
                offset += initializeMethodEnd.Length;

                short retImm16 = BitConverter.ToInt16(fileData, offset);
                if (retImm16 != 0x0C && retImm16 != 0x10)
                {
                    continue;
                }
                offset += 2;
                if (offset + ENC_CODE_OFFSET + 4 > lastOffset)
                {
                    return(null);
                }

                // rva is 0 when the assembly has been embedded
                uint rva = BitConverter.ToUInt32(fileData, offset + RVA_EXECUTIVE_OFFSET);
                if (rva != 0 && mainType.Rvas.IndexOf(rva) < 0)
                {
                    continue;
                }

                int relOffs = BitConverter.ToInt32(fileData, offset + ENC_CODE_OFFSET);
                if (relOffs <= 0 || relOffs >= section.SizeOfRawData)
                {
                    continue;
                }
                reader.Position = section.PointerToRawData + relOffs;

                int size      = (int)reader.ReadCompressedUInt32();
                int endOffset = relOffs + size;
                if (endOffset < relOffs || endOffset > section.SizeOfRawData)
                {
                    continue;
                }

                return(reader.ReadBytes(size));
            }

            return(null);
        }
예제 #28
0
 static void ClearDllBit(byte[] peImageData)
 {
     using (var mainPeImage = new MyPEImage(peImageData)) {
         uint   characteristicsOffset = (uint)mainPeImage.PEImage.ImageNTHeaders.FileHeader.StartOffset + 18;
         ushort characteristics       = mainPeImage.OffsetReadUInt16(characteristicsOffset);
         characteristics &= 0xDFFF;
         characteristics |= 2;
         mainPeImage.OffsetWriteUInt16(characteristicsOffset, characteristics);
     }
 }
예제 #29
0
 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);
 }
예제 #30
0
파일: McKey.cs 프로젝트: haise0/de5dot
 public McKey(MyPEImage peImage, PeHeader peHeader)
 {
     try {
         data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x2000);
     }
     catch (Exception ex) when(ex is IOException || ex is ArgumentException)
     {
         data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x1000);
     }
 }
예제 #31
0
 public McKey(MyPEImage peImage, PeHeader peHeader)
 {
     //this.peHeader = peHeader;
     try {
         this.data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x2000);
     }
     catch (IOException) {
         this.data = peImage.ReadBytes(peHeader.GetMcKeyRva(), 0x1000);
     }
 }
예제 #32
0
        bool Decrypt_v17_r73605(MyPEImage peImage, byte[] fileData)
        {
            if (peImage.OptionalHeader.CheckSum == 0)
            {
                return(false);
            }

            methodsData = DecryptMethodsData_v17_r73404(peImage);
            return(DecryptImage_v16_r71742(peImage, fileData));
        }
예제 #33
0
        static uint GetOldCodeHeaderOffset(MyPEImage peImage)
        {
            var sect = GetLastOf(peImage, sections);

            if (sect == null || sect.VirtualSize < 0x100)
            {
                return(0);
            }
            return(peImage.RvaToOffset((uint)sect.VirtualAddress + sect.VirtualSize - 0x100));
        }
예제 #34
0
 public bool Patch(byte[] peData)
 {
     try {
         using (var peImage = new MyPEImage(peData))
             return(Patch2(peImage));
     }
     catch {
         Logger.w("Could not patch the file");
         return(false);
     }
 }
예제 #35
0
 public void Patch(byte[] peImageData)
 {
     using (var peImage = new MyPEImage(peImageData)) {
         foreach (var info in patchInfos)
         {
             for (int i = 0; i < info.offsets.Length; i++)
             {
                 peImage.DotNetSafeWriteOffset((uint)info.offsets[i], BitConverter.GetBytes(info.values[i]));
             }
         }
     }
 }
			public MethodInfos(ModuleDef module, MainType mainType, MyPEImage peImage, PeHeader peHeader, McKey mcKey) {
				this.module = module;
				this.mainType = mainType;
				this.peImage = peImage;
				this.peHeader = peHeader;
				this.mcKey = mcKey;

				structSize = GetStructSize(mcKey);

				uint methodInfosRva = peHeader.GetRva(0x0FF8, mcKey.ReadUInt32(0x005A));
				uint encryptedDataRva = peHeader.GetRva(0x0FF0, mcKey.ReadUInt32(0x0046));

				methodInfosOffset = peImage.RvaToOffset(methodInfosRva);
				encryptedDataOffset = peImage.RvaToOffset(encryptedDataRva);
			}
예제 #37
0
        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");
            }
        }
예제 #38
0
		public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
			if (count != 0)
				return false;
			fileData = ModuleBytes ?? DeobUtils.ReadModule(module);
			peImage = new MyPEImage(fileData);

			if (!options.DecryptMethods)
				return false;

			var tokenToNativeCode = new Dictionary<uint,byte[]>();
			if (!methodsDecrypter.Decrypt(peImage, DeobfuscatedFile, ref dumpedMethods, tokenToNativeCode, unpackedNativeFile))
				return false;

			newFileData = fileData;
			return true;
		}
		bool DecryptImage_v16_r71742(MyPEImage peImage, byte[] fileData) {
			var reader = new BinaryReader(new MemoryStream(methodsData));
			reader.ReadInt16();	// sig
			int numInfos = reader.ReadInt32();
			for (int i = 0; i < numInfos; i++) {
				uint offs = reader.ReadUInt32() ^ key4;
				if (offs == 0)
					continue;
				uint rva = reader.ReadUInt32() ^ key5;
				if (peImage.RvaToOffset(rva) != offs)
					throw new ApplicationException("Invalid offs & rva");
				int len = reader.ReadInt32();
				for (int j = 0; j < len; j++)
					fileData[offs + j] = reader.ReadByte();
			}
			return true;
		}
예제 #40
0
		public byte[] Unpack() {
			byte[] data = null;
			MyPEImage myPeImage = null;
			try {
				myPeImage = new MyPEImage(peImage);
				data = Unpack2(myPeImage);
			}
			catch {
			}
			finally {
				if (myPeImage != null)
					myPeImage.Dispose();
			}
			if (data != null)
				return data;

			if (shouldUnpack)
				Logger.w("Could not unpack file: {0}", peImage.FileName ?? "(unknown filename)");
			return null;
		}
예제 #41
0
		void FreePEImage() {
			if (peImage != null)
				peImage.Dispose();
			peImage = null;
		}
		byte[] DecryptMethodsData_v14_r57884(MyPEImage peImage, bool hasStrongNameInfo) {
			var reader = peImage.Reader;
			reader.Position = 0;
			var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.CheckSum ^ (int)key0);

			int csOffs = (int)peImage.OptionalHeader.StartOffset + 0x40;
			Array.Clear(md5SumData, csOffs, 4);
			var md5Sum = DeobUtils.Md5Sum(md5SumData);
			ulong checkSum = reader.ReadUInt64() ^ lkey0;
			if (hasStrongNameInfo) {
				int sn = reader.ReadInt32();
				int snLen = reader.ReadInt32();
				if (sn != 0) {
					if (peImage.RvaToOffset((uint)peImage.Cor20Header.StrongNameSignature.VirtualAddress) != sn ||
						peImage.Cor20Header.StrongNameSignature.Size != snLen)
						throw new ApplicationException("Invalid sn and snLen");
					Array.Clear(md5SumData, sn, snLen);
				}
			}
			if (checkSum != CalcChecksum(md5SumData))
				throw new ApplicationException("Invalid checksum. File has been modified.");
			var iv = reader.ReadBytes(reader.ReadInt32() ^ (int)key2);
			var encrypted = reader.ReadBytes(reader.ReadInt32() ^ (int)key3);
			var decrypted = Decrypt(encrypted, iv, md5SumData);
			if (BitConverter.ToInt16(decrypted, 0) != 0x6FD6)
				throw new ApplicationException("Invalid magic");
			return decrypted;
		}
예제 #43
0
		public bool Decrypt(MyPEImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref DumpedMethods dumpedMethods, Dictionary<uint, byte[]> tokenToNativeCode, bool unpackedNativeFile) {
			if (encryptedResource.Method == null)
				return false;

			encryptedResource.Initialize(simpleDeobfuscator);
			if (!encryptedResource.FoundResource)
				return false;
			var methodsData = encryptedResource.Decrypt();

			bool hooksJitter = FindDnrCompileMethod(encryptedResource.Method.DeclaringType) != null;

			xorKey = GetXorKey();
			XorEncrypt(methodsData);

			var methodsDataReader = MemoryImageStream.Create(methodsData);
			int patchCount = methodsDataReader.ReadInt32();
			int mode = methodsDataReader.ReadInt32();

			int tmp = methodsDataReader.ReadInt32();
			methodsDataReader.Position -= 4;
			if ((tmp & 0xFF000000) == 0x06000000) {
				// It's method token + rva. DNR 3.7.0.3 (and earlier?) - 3.9.0.1
				methodsDataReader.Position += 8L * patchCount;
				patchCount = methodsDataReader.ReadInt32();
				mode = methodsDataReader.ReadInt32();

				PatchDwords(peImage, methodsDataReader, patchCount);
				while (methodsDataReader.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+

				PatchDwords(peImage, methodsDataReader, patchCount);
				bool oldCode = !IsNewer45Decryption(encryptedResource.Method);
				while (methodsDataReader.Position < methodsData.Length - 1) {
					uint rva = methodsDataReader.ReadUInt32();
					int size;
					if (oldCode) {
						methodsDataReader.ReadUInt32();	// token, unknown, or index
						size = methodsDataReader.ReadInt32();
					}
					else
						size = methodsDataReader.ReadInt32() * 4;

					var newData = methodsDataReader.ReadBytes(size);
					if (unpackedNativeFile)
						peImage.DotNetSafeWriteOffset(rva, newData);
					else
						peImage.DotNetSafeWrite(rva, newData);
				}
			}
			else {
				// DNR 4.0+ (jitter is hooked)

				var methodDef = peImage.MetaData.TablesStream.MethodTable;
				var rvaToIndex = new Dictionary<uint, int>((int)methodDef.Rows);
				uint offset = (uint)methodDef.StartOffset;
				for (int i = 0; i < methodDef.Rows; i++) {
					uint rva = peImage.OffsetReadUInt32(offset);
					offset += methodDef.RowSize;
					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.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)) {
						Logger.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();
					peImage.ReadMethodTableRowTo(dm, MDToken.ToRID(methodToken));
					dm.code = methodData;

					var codeReader = peImage.Reader;
					codeReader.Position = peImage.RvaToOffset(dm.mdRVA);
					byte[] code;
					var mbHeader = MethodBodyParser.ParseMethodBody(codeReader, out code, out dm.extraSections);
					peImage.UpdateMethodHeaderInfo(dm, mbHeader);

					dumpedMethods.Add(dm);
				}
			}

			return true;
		}
		bool Decrypt_v16_r71742(MyPEImage peImage, byte[] fileData) {
			methodsData = DecryptMethodsData_v16_r71742(peImage, GetEncryptedHeaderOffset_v16_r71742(peImage.Sections));
			return DecryptImage_v16_r71742(peImage, fileData);
		}
		bool DecryptImage_v14_r58004(MyPEImage peImage, byte[] fileData) {
			var reader = new BinaryReader(new MemoryStream(methodsData));
			reader.ReadInt16();	// sig
			var writer = new BinaryWriter(new MemoryStream(fileData));
			int numInfos = reader.ReadInt32();
			for (int i = 0; i < numInfos; i++) {
				uint offs = reader.ReadUInt32() ^ key4;
				if (offs == 0)
					continue;
				uint rva = reader.ReadUInt32() ^ key4;
				if (peImage.RvaToOffset(rva) != offs)
					throw new ApplicationException("Invalid offs & rva");
				writer.BaseStream.Position = peImage.RvaToOffset(rva);
				writer.Write(reader.ReadBytes(reader.ReadInt32()));
			}

			return true;
		}
예제 #46
0
		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;
		}
		bool Decrypt_v17_r73605(MyPEImage peImage, byte[] fileData) {
			if (peImage.OptionalHeader.CheckSum == 0)
				return false;

			methodsData = DecryptMethodsData_v17_r73404(peImage);
			return DecryptImage_v16_r71742(peImage, fileData);
		}
예제 #48
0
		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 NativeImageUnpacker(IPEImage peImage)
 {
     this.peImage = new MyPEImage(peImage);
 }
예제 #50
0
		byte[] FindMethodsData(MyPEImage peImage, byte[] fileData) {
			var section = peImage.Sections[0];

			var reader = MemoryImageStream.Create(fileData);

			const int RVA_EXECUTIVE_OFFSET = 1 * 4;
			const int ENC_CODE_OFFSET = 6 * 4;
			int lastOffset = Math.Min(fileData.Length, (int)(section.PointerToRawData + section.SizeOfRawData));
			for (int offset = GetStartOffset(peImage); offset < lastOffset; ) {
				offset = FindSig(fileData, offset, lastOffset, initializeMethodEnd);
				if (offset < 0)
					return null;
				offset += initializeMethodEnd.Length;

				short retImm16 = BitConverter.ToInt16(fileData, offset);
				if (retImm16 != 0x0C && retImm16 != 0x10)
					continue;
				offset += 2;
				if (offset + ENC_CODE_OFFSET + 4 > lastOffset)
					return null;

				// rva is 0 when the assembly has been embedded
				uint rva = BitConverter.ToUInt32(fileData, offset + RVA_EXECUTIVE_OFFSET);
				if (rva != 0 && mainType.Rvas.IndexOf(rva) < 0)
					continue;

				int relOffs = BitConverter.ToInt32(fileData, offset + ENC_CODE_OFFSET);
				if (relOffs <= 0 || relOffs >= section.SizeOfRawData)
					continue;
				reader.Position = section.PointerToRawData + relOffs;

				int size = (int)reader.ReadCompressedUInt32();
				int endOffset = relOffs + size;
				if (endOffset < relOffs || endOffset > section.SizeOfRawData)
					continue;

				return reader.ReadBytes(size);
			}

			return null;
		}
예제 #51
0
		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;
		}
예제 #52
0
		int GetStartOffset(MyPEImage peImage) {
			int minOffset = int.MaxValue;
			foreach (var rva in mainType.Rvas) {
				int rvaOffs = (int)peImage.RvaToOffset((uint)rva);
				if (rvaOffs < minOffset)
					minOffset = rvaOffs;
			}
			return minOffset == int.MaxValue ? 0 : minOffset;
		}
예제 #53
0
        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;
        }
예제 #54
0
		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;
		}
		bool Decrypt_v15_r59014(MyPEImage peImage, byte[] fileData) {
			methodsData = DecryptMethodsData_v14_r57884(peImage, true);
			return DecryptImage_v14_r58004(peImage, fileData);
		}
예제 #56
0
		static void ClearDllBit(byte[] peImageData) {
			using (var mainPeImage = new MyPEImage(peImageData)) {
				uint characteristicsOffset = (uint)mainPeImage.PEImage.ImageNTHeaders.FileHeader.StartOffset + 18;
				ushort characteristics = mainPeImage.OffsetReadUInt16(characteristicsOffset);
				characteristics &= 0xDFFF;
				characteristics |= 2;
				mainPeImage.OffsetWriteUInt16(characteristicsOffset, characteristics);
			}
		}
예제 #57
0
		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;
		}
예제 #58
0
		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);
		}
예제 #59
0
		uint CheckOffset(MyPEImage peImage, uint offset) {
			if (offset >= peImage.Length)
				throw new Exception();
			return offset;
		}
예제 #60
0
		static void PatchDwords(MyPEImage peImage, IBinaryReader reader, int count) {
			for (int i = 0; i < count; i++) {
				uint rva = reader.ReadUInt32();
				uint data = reader.ReadUInt32();
				peImage.DotNetSafeWrite(rva, BitConverter.GetBytes(data));
			}
		}