示例#1
0
            public MethodBodyHeader Decrypt(uint bodyOffset, out byte[] code, out byte[] extraSections)
            {
                peImage.Reader.Position = bodyOffset;
                var mbHeader = MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections);

                blowfish.Decrypt(code);
                return(mbHeader);
            }
        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);
        }
        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);
        }
示例#4
0
            public virtual bool Decrypt(IBinaryReader fileDataReader, DumpedMethod dm)
            {
                if (fileDataReader.ReadByte() != 0x2A)
                {
                    return(false);                      // Not a RET
                }
                methodsDataReader.Position = fileDataReader.ReadCompressedUInt32();

                dm.mhCodeSize = methodsDataReader.ReadCompressedUInt32();
                dm.code       = methodsDataReader.ReadBytes((int)dm.mhCodeSize);
                if ((dm.mhFlags & 8) != 0)
                {
                    dm.extraSections = MethodBodyParser.ReadExtraSections(methodsDataReader);
                }

                if (!DecryptCode(dm))
                {
                    return(false);
                }

                return(true);
            }
示例#5
0
        DumpedMethods DecryptMethods()
        {
            var dumpedMethods = new DumpedMethods();

            var peImage     = decrypterInfo.peImage;
            var methodInfos = new MethodInfos(module, decrypterInfo.mainType, peImage, decrypterInfo.peHeader, decrypterInfo.mcKey);

            methodInfos.InitializeInfos();

            var methodDef = peImage.Metadata.TablesStream.MethodTable;

            for (uint rid = 1; rid <= methodDef.Rows; rid++)
            {
                var dm = new DumpedMethod();
                peImage.ReadMethodTableRowTo(dm, rid);

                var info = methodInfos.Lookup(dm.mdRVA);
                if (info == null)
                {
                    continue;
                }

                ushort magic = peImage.ReadUInt16(dm.mdRVA);
                if (magic != 0xFFF3)
                {
                    continue;
                }

                var bodyReader = ByteArrayDataReaderFactory.CreateReader(info.body);
                var mbHeader   = MethodBodyParser.ParseMethodBody(ref bodyReader, out dm.code, out dm.extraSections);
                peImage.UpdateMethodHeaderInfo(dm, mbHeader);

                dumpedMethods.Add(dm);
            }

            return(dumpedMethods);
        }
示例#6
0
            public virtual bool decrypt(BinaryReader fileDataReader, DumpedMethod dm)
            {
                if (fileDataReader.ReadByte() != 0x2A)
                {
                    return(false);                      // Not a RET
                }
                int methodsDataOffset = DeobUtils.readVariableLengthInt32(fileDataReader);

                methodsDataReader.BaseStream.Position = methodsDataOffset;

                dm.mhCodeSize = (uint)DeobUtils.readVariableLengthInt32(methodsDataReader);
                dm.code       = methodsDataReader.ReadBytes((int)dm.mhCodeSize);
                if ((dm.mhFlags & 8) != 0)
                {
                    dm.extraSections = MethodBodyParser.readExtraSections(methodsDataReader);
                }

                if (!decryptCode(dm))
                {
                    return(false);
                }

                return(true);
            }
示例#7
0
        DumpedMethods decryptMethods()
        {
            var dumpedMethods = new DumpedMethods();

            var peImage     = decrypterInfo.peImage;
            var methodInfos = new MethodInfos(decrypterInfo.mainType, peImage, decrypterInfo.peHeader, decrypterInfo.mcKey);

            methodInfos.initializeInfos();

            var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;

            for (uint rid = 1; rid <= methodDef.Rows; rid++)
            {
                var dm = new DumpedMethod();
                peImage.readMethodTableRowTo(dm, rid);

                var info = methodInfos.lookup(dm.mdRVA);
                if (info == null)
                {
                    continue;
                }

                ushort magic = peImage.readUInt16(dm.mdRVA);
                if (magic != 0xFFF3)
                {
                    continue;
                }

                var mbHeader = MethodBodyParser.parseMethodBody(MemoryImageStream.Create(info.body), out dm.code, out dm.extraSections);
                peImage.updateMethodHeaderInfo(dm, mbHeader);

                dumpedMethods.add(dm);
            }

            return(dumpedMethods);
        }
示例#8
0
            bool InitializeInfos2(IDecrypter decrypter)
            {
                int numMethods = ReadInt32(0) ^ ReadInt32(4);

                if (numMethods < 0)
                {
                    throw new ApplicationException("Invalid number of encrypted methods");
                }

                xorKey = (uint)numMethods;
                int numEncryptedDataInfos = ((int)structSize - 0xC) / ENCRYPTED_DATA_INFO_SIZE;
                var encryptedDataInfos    = new byte[numEncryptedDataInfos][];

                uint offset = 8;

                infos.Clear();
                for (int i = 0; i < numMethods; i++, offset += structSize)
                {
                    uint methodBodyRva = ReadEncryptedUInt32(offset);
                    uint totalSize     = ReadEncryptedUInt32(offset + 4);
                    /*uint methodInstructionRva =*/ ReadEncryptedUInt32(offset + 8);

                    // Read the method body header and method body (instrs + exception handlers).
                    // The method body header is always in the first one. The instrs + ex handlers
                    // are always in the last 4, and evenly divided (each byte[] is totalLen / 4).
                    // The 2nd one is for the exceptions (or padding), but it may be null.
                    uint offset2  = offset + 0xC;
                    int  exOffset = 0;
                    for (int j = 0; j < encryptedDataInfos.Length; j++, offset2 += ENCRYPTED_DATA_INFO_SIZE)
                    {
                        // readByte(offset2); <-- index
                        int  encryptionType = ReadEncryptedInt16(offset2 + 1);
                        uint dataOffset     = ReadEncryptedUInt32(offset2 + 3);
                        uint encryptedSize  = ReadEncryptedUInt32(offset2 + 7);
                        uint realSize       = ReadEncryptedUInt32(offset2 + 11);
                        if (j >= 3 && dataOffset == xorKey && encryptedSize == xorKey)
                        {
                            encryptedDataInfos[j] = null;
                            continue;
                        }
                        if (j == 1)
                        {
                            exOffset = ReadEncryptedInt32(offset2 + 15);
                        }
                        if (j == 1 && exOffset == 0)
                        {
                            encryptedDataInfos[j] = null;
                        }
                        else
                        {
                            encryptedDataInfos[j] = Decrypt(decrypter, encryptionType, dataOffset, encryptedSize, realSize);
                        }
                    }

                    var decryptedData = new byte[totalSize];
                    int copyOffset    = 0;
                    copyOffset = CopyData(decryptedData, encryptedDataInfos[0], copyOffset);
                    for (int j = 2; j < encryptedDataInfos.Length; j++)
                    {
                        copyOffset = CopyData(decryptedData, encryptedDataInfos[j], copyOffset);
                    }
                    CopyData(decryptedData, encryptedDataInfos[1], exOffset);                     // Exceptions or padding

                    if (!MethodBodyParser.Verify(decryptedData))
                    {
                        throw new InvalidMethodBody();
                    }

                    var info = new DecryptedMethodInfo(methodBodyRva, decryptedData);
                    infos[info.bodyRva] = info;
                }

                return(true);
            }
示例#9
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);
        }
示例#10
0
 public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections)
 {
     peImage.Reader.Position = endOfMetadata + methodInfo.codeOffs;
     return(MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections));
 }
示例#11
0
 public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections)
 {
     peImage.Reader.Position = peImage.RvaToOffset(methodInfo.codeOffs);
     return(MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections));
 }
示例#12
0
 protected MethodBodyHeader GetCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections)
 {
     return(MethodBodyParser.ParseMethodBody(MemoryImageStream.Create(methodBody), out code, out extraSections));
 }
示例#13
0
            protected MethodBodyHeader GetCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections)
            {
                var reader = ByteArrayDataReaderFactory.CreateReader(methodBody);

                return(MethodBodyParser.ParseMethodBody(ref reader, out code, out extraSections));
            }
示例#14
0
        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);
        }
示例#15
0
 protected MethodBodyHeader getCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections)
 {
     return(MethodBodyParser.parseMethodBody(new BinaryReader(new MemoryStream(methodBody)), out code, out extraSections));
 }