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); } }
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)); } } } }
private void LoadMetaTable(PeHeaderReader pe, MemoryMappedViewAccessor mm) { long loc = pe.GetFileOffset(mHeader.MetaData.VirtualAddress + mMetaStreams["#~"].Offset); mm.Read<TableHeader>(loc, out mTableHeader); Console.WriteLine(); }