示例#1
0
        DumpedMethods Decrypt(MyPEImage peImage, byte[] fileData, DecryptMethodData decrypter)
        {
            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;
                int    methodDataOffset = mdOffs + 2;
                uint[] methodData;
                byte[] codeData;
                decrypter.Decrypt(methodsData, methodDataOffset, (uint)key, len, out methodData, out codeData);

                dm.mhFlags = 0x03;
                int maxStack = (int)methodData[methodDataIndexes.maxStack];
                dm.mhMaxStack       = (ushort)maxStack;
                dm.mhLocalVarSigTok = methodData[methodDataIndexes.localVarSigTok];
                if (dm.mhLocalVarSigTok != 0 && dm.mhLocalVarSigTok >> 24 != 0x11)
                {
                    throw new ApplicationException("Invalid local var sig token");
                }
                int  numExceptions = (int)methodData[methodDataIndexes.ehs];
                uint options       = methodData[methodDataIndexes.options];
                int  codeSize      = (int)methodData[methodDataIndexes.codeSize];

                var codeDataReader = MemoryImageStream.Create(codeData);
                if (decrypter.IsCodeFollowedByExtraSections(options))
                {
                    dm.code          = codeDataReader.ReadBytes(codeSize);
                    dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
                }
                else
                {
                    dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
                    dm.code          = codeDataReader.ReadBytes(codeSize);
                }
                if (codeDataReader.Position != codeDataReader.Length)
                {
                    throw new ApplicationException("Invalid method data");
                }
                if (dm.extraSections != null)
                {
                    dm.mhFlags |= 8;
                }
                dm.mhCodeSize = (uint)dm.code.Length;

                // Figure out if the original method was tiny or not.
                bool isTiny = dm.code.Length <= 0x3F &&
                              dm.mhLocalVarSigTok == 0 &&
                              dm.extraSections == null &&
                              dm.mhMaxStack == 8;
                if (isTiny)
                {
                    dm.mhFlags |= 0x10;                         // Set 'init locals'
                }
                dm.mhFlags |= (ushort)(options & 0x10);         // copy 'init locals' bit

                dumpedMethods.Add(dm);
            }

            return(dumpedMethods);
        }
		DumpedMethods Decrypt(MyPEImage peImage, byte[] fileData, DecryptMethodData decrypter) {
			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;
				int methodDataOffset = mdOffs + 2;
				uint[] methodData;
				byte[] codeData;
				decrypter.Decrypt(methodsData, methodDataOffset, (uint)key, len, out methodData, out codeData);

				dm.mhFlags = 0x03;
				int maxStack = (int)methodData[methodDataIndexes.maxStack];
				dm.mhMaxStack = (ushort)maxStack;
				dm.mhLocalVarSigTok = methodData[methodDataIndexes.localVarSigTok];
				if (dm.mhLocalVarSigTok != 0 && (dm.mhLocalVarSigTok >> 24) != 0x11)
					throw new ApplicationException("Invalid local var sig token");
				int numExceptions = (int)methodData[methodDataIndexes.ehs];
				uint options = methodData[methodDataIndexes.options];
				int codeSize = (int)methodData[methodDataIndexes.codeSize];

				var codeDataReader = MemoryImageStream.Create(codeData);
				if (decrypter.IsCodeFollowedByExtraSections(options)) {
					dm.code = codeDataReader.ReadBytes(codeSize);
					dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
				}
				else {
					dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
					dm.code = codeDataReader.ReadBytes(codeSize);
				}
				if (codeDataReader.Position != codeDataReader.Length)
					throw new ApplicationException("Invalid method data");
				if (dm.extraSections != null)
					dm.mhFlags |= 8;
				dm.mhCodeSize = (uint)dm.code.Length;

				// Figure out if the original method was tiny or not.
				bool isTiny = dm.code.Length <= 0x3F &&
							dm.mhLocalVarSigTok == 0 &&
							dm.extraSections == null &&
							dm.mhMaxStack == 8;
				if (isTiny)
					dm.mhFlags |= 0x10;	// Set 'init locals'
				dm.mhFlags |= (ushort)(options & 0x10);	// copy 'init locals' bit

				dumpedMethods.Add(dm);
			}

			return dumpedMethods;
		}