예제 #1
0
        private void LoadHeaderAndStreams(PeHeaderReader pe, MemoryMappedViewAccessor mm)
        {
            var clrDataDir = pe.DataDirectories[PeHeaderReader.Image_Directory_Entry_Type.COM_DESCRIPTOR];
            if (Marshal.SizeOf(typeof(IMAGE_COR20_HEADER)) != clrDataDir.Size)
                throw new Exception("Size wrong.");

            mm.Read<IMAGE_COR20_HEADER>(pe.GetFileOffset(clrDataDir.VirtualAddress), out mHeader);
            if (mHeader.cb != clrDataDir.Size)
                throw new Exception("Size wrong.");

            var metaLoc = pe.GetFileOffset(mHeader.MetaData.VirtualAddress);
            mm.Read<MetaDataHeaderPart1>(metaLoc, out mMetaHeader);
            var versionBytes = new byte[mMetaHeader.VersionLength];

            metaLoc += Marshal.SizeOf(typeof(MetaDataHeaderPart1));
            mm.ReadArray<byte>(metaLoc, versionBytes, 0, versionBytes.Length);
            int versionSize = 0;
            while (versionSize < versionBytes.Length && versionBytes[versionSize] != 0)
                versionSize++;
            mVersionName = Encoding.ASCII.GetString(versionBytes, 0, versionSize);

            metaLoc += mMetaHeader.VersionLength;
            mMetaDataFlags = mm.ReadUInt16(metaLoc);
            metaLoc += 2;
            uint numberOfMetaStreams = mm.ReadUInt16(metaLoc);
            metaLoc += 2;

            for (int i = 0; i < numberOfMetaStreams; i++)
            {
                MetaDataStream mds;
                mm.Read<MetaDataStream>(metaLoc, out mds);
                metaLoc += Marshal.SizeOf(typeof(MetaDataStream));
                byte b;
                StringBuilder sb = new StringBuilder();
                while ((b = mm.ReadByte(metaLoc++)) != 0)
                {
                    sb.Append((char)b);
                }
                metaLoc += 3;
                metaLoc &= ~3;
                mMetaStreams.Add(sb.ToString(), mds);
            }
        }
예제 #2
0
        private static void Process(PeHeaderReader pe, AssemblyDefinition asm, MemoryMappedFile mappedFile)
        {
            foreach (var m in asm.MainModule.Types.SelectMany(t => t.Methods))
            {
                if (!m.HasBody)
                    continue;
                var body = m.Body;
                //Console.WriteLine("{0,-40}{1:x}{2,10:x}{3,10:x}", m.Name, m.RVA, body.LengthOnDisk, body.IndexAfterCode);

                if (RequiresFatHeader(body))
                {
                    flags.Write(body.Flags);
                    maxStack.Write((UInt16)body.MaxStackSize);
                    codeSize.Write(body.CodeSize);
                    localVar.Write(body.LocalVarToken.ToUInt32());
                }
                else
                {
                    flags.Write((byte)(0x2 | (body.CodeSize << 2)));
                }

                foreach (var instr in body.Instructions)
                {
                    if (instr.OpCode.Size == 1)
                        opcodes.Write(instr.OpCode.Op2);
                    else
                    {
                        opcodes.Write(instr.OpCode.Op1);
                        opcodes.Write(instr.OpCode.Op2);
                    }

                    var operand = instr.Operand;
                    switch (instr.OpCode.OperandType)
                    {
                        case OperandType.InlineSwitch:
                            {
                                var targets = (Instruction[])operand;
                                switches.Write(targets.Length);
                                for (int i = 0; i < targets.Length; i++)
                                    switches.Write(GetTargetOffset(body, targets[i]));
                                break;
                            }
                        case OperandType.ShortInlineBrTarget:
                            {
                                var target = (Instruction)operand;
                                sbyteBranch.Write((sbyte)GetTargetOffset(body, target));
                                break;
                            }
                        case OperandType.InlineBrTarget:
                            {
                                var target = (Instruction)operand;
                                intBranch.Write(GetTargetOffset(body, target));
                                break;
                            }
                        case OperandType.ShortInlineVar:
                            varIndex.Write((byte)((VariableDefinition)operand).Index);
                            break;
                        case OperandType.ShortInlineArg:
                            varIndex.Write((byte)GetParameterIndex(body, (ParameterDefinition)operand));
                            break;
                        case OperandType.InlineVar:
                            varIndex.Write((short)((VariableDefinition)operand).Index);
                            break;
                        case OperandType.InlineArg:
                            varIndex.Write((short)GetParameterIndex(body, (ParameterDefinition)operand));
                            break;
                        case OperandType.InlineSig:
                            sigToken.Write(((CallSite)operand).MetadataToken.ToUInt32());
                            break;
                        case OperandType.ShortInlineI:
                            if (instr.OpCode == OpCodes.Ldc_I4_S)
                                inlineInt.Write((sbyte)operand);
                            else
                                inlineInt.Write((byte)operand);
                            break;
                        case OperandType.InlineI:
                            inlineInt.Write((int)operand);
                            break;
                        case OperandType.InlineI8:
                            inlineInt.Write((long)operand);
                            break;
                        case OperandType.ShortInlineR:
                            inlieFloat.Write((float)operand);
                            break;
                        case OperandType.InlineR:
                            inlieFloat.Write((double)operand);
                            break;
                        case OperandType.InlineString:
                            strTokens.Write(instr.StringOperandToken.ToUInt32());
                            break;
                        case OperandType.InlineType:
                        case OperandType.InlineField:
                        case OperandType.InlineMethod:
                        case OperandType.InlineTok:
                            otherTokens.Write(((IMetadataTokenProvider)operand).MetadataToken.ToUInt32());
                            break;
                        case OperandType.InlineNone:
                            break;
                        default:
                            throw new ArgumentException();
                    }
                    //write some code
                }

                using (var mm = mappedFile.CreateViewAccessor(pe.GetFileOffset(m.RVA), body.LengthOnDisk, MemoryMappedFileAccess.Read))
                {
                    for (int i = body.IndexAfterCode; i < body.LengthOnDisk; i++)
                    {
                        exceptionStuff.Write(mm.ReadByte(i));
                    }

                    //do a full copy of the method
                    for (int i = 0; i < body.LengthOnDisk; i++)
                    {
                        fullMethods.Write(mm.ReadByte(i));
                    }
                }
            }
        }
예제 #3
0
 private void LoadMetaTable(PeHeaderReader pe, MemoryMappedViewAccessor mm)
 {
     long loc = pe.GetFileOffset(mHeader.MetaData.VirtualAddress + mMetaStreams["#~"].Offset);
     mm.Read<TableHeader>(loc, out mTableHeader);
     Console.WriteLine();
 }