/// <summary> /// Creates a CIL method body from a raw CIL method body. /// </summary> /// <param name="method">The method that owns the method body.</param> /// <param name="rawBody">The raw method body.</param> /// <param name="operandResolver">The object instance to use for resolving operands of an instruction in the /// method body.</param> /// <returns>The method body.</returns> public static CilMethodBody FromRawMethodBody(MethodDefinition method, CilRawMethodBody rawBody, ICilOperandResolver operandResolver = null) { var result = new CilMethodBody(method); if (operandResolver is null) operandResolver = result; // Read raw instructions. var reader = new ByteArrayReader(rawBody.Code); var disassembler = new CilDisassembler(reader); result.Instructions.AddRange(disassembler.ReadAllInstructions()); // Read out extra metadata. if (rawBody is CilRawFatMethodBody fatBody) { result.MaxStack = fatBody.MaxStack; result.InitializeLocals = fatBody.InitLocals; ReadLocalVariables(method.Module, result, fatBody); ReadExceptionHandlers(fatBody, result); } else { result.MaxStack = 8; result.InitializeLocals = false; } // Resolve operands. foreach (var instruction in result.Instructions) instruction.Operand = ResolveOperand(result, instruction, operandResolver) ?? instruction.Operand; return result; }
private static FieldRvaRow FindFieldRvaRow(TablesStream tablesStream, MetadataToken cctorToken, MetadataToken fieldToken) { var reader = tablesStream .GetTable <MethodDefinitionRow>(TableIndex.Method) .GetByRid(cctorToken.Rid) .Body.CreateReader(); var body = CilRawMethodBody.FromReader(ThrowErrorListener.Instance, reader); var disassembler = new CilDisassembler(new ByteArrayReader(body.Code)); var initialValueFieldToken = MetadataToken.Zero; var instructions = disassembler.ReadAllInstructions(); for (int i = 0; i < instructions.Count; i++) { if (instructions[i].OpCode.Code == CilCode.Ldtoken && instructions[i + 2].OpCode.Code == CilCode.Stsfld && (MetadataToken)instructions[i + 2].Operand == fieldToken) { initialValueFieldToken = (MetadataToken)instructions[i].Operand; break; } } Assert.NotEqual(MetadataToken.Zero, initialValueFieldToken); Assert.True(tablesStream .GetTable <FieldRvaRow>(TableIndex.FieldRva) .TryGetRowByKey(1, initialValueFieldToken.Rid, out var fieldRvaRow)); return(fieldRvaRow); }
/// <inheritdoc /> public MethodBody ReadMethodBody(MethodDefinition owner, MethodDefinitionRow row) { try { if (row.Body.CanRead) { if (owner.IsIL) { var rawBody = CilRawMethodBody.FromReader(row.Body.CreateReader()); return(CilMethodBody.FromRawMethodBody(owner, rawBody)); } else { // TODO: handle native method bodies. } } else if (row.Body.IsBounded && row.Body.GetSegment() is CilRawMethodBody rawMethodBody) { return(CilMethodBody.FromRawMethodBody(owner, rawMethodBody)); } } catch when(!ThrowOnInvalidMethodBody) { return(null); } return(null); }
/// <summary> /// Adds a CIL method body to the buffer. /// </summary> /// <param name="body">The method body to add.</param> public void AddCilBody(CilRawMethodBody body) { if (body.IsFat) { _fatBodies.Add(body, 4); } else { _tinyBodies.Add(body); } }
public void DetectTinyMethodBody() { var peImage = PEImage.FromBytes(Properties.Resources.HelloWorld); var tablesStream = peImage.DotNetDirectory.Metadata.GetStream <TablesStream>(); var methodTable = tablesStream.GetTable <MethodDefinitionRow>(); var methodBody = CilRawMethodBody.FromReader(methodTable[0].Body.CreateReader()); Assert.False(methodBody.IsFat); Assert.Equal(new byte[] { 0x72, 0x01, 0x00, 0x00, 0x70, // ldstr "Hello, world!" 0x28, 0x0B, 0x00, 0x00, 0x0A, // call void [mscorlib] System.Console::WriteLine(string) 0x2A // ret }, methodBody.Code); }
/// <inheritdoc /> public virtual FileSegment ReadMethodBody( MetadataRow <FileSegment, MethodImplAttributes, MethodAttributes, uint, uint, uint> row, IBinaryStreamReader reader) { try { return(row.Column2.HasFlag(MethodImplAttributes.Native) ? new DataSegment(new byte[0]) { StartOffset = reader.Position } // TODO: add support for native methods? : (FileSegment)CilRawMethodBody.FromReader(reader)); } catch when(!ThrowOnInvalidMethodBody) { // Ignore when flag is set. return(new DataSegment { StartOffset = reader.Position }); } }
public override void Execute(Context context, IEnumerable <MetadataMember> targets) { var MethodsTables = context.Module.DotNetDirectory.Metadata .GetStream <TablesStream>() .GetTable <MethodDefinitionRow>(); // Methods Rows in .Net Binary that Get Access to Rawbytes of Methods without reflection Usage. foreach (var VirualizedMethod in CawkVM.CawkKey.VirtualizatedMethods) { try { #region Decryption byte[] RawBytes = CawkVM.CawkKey.Data.Skip(VirualizedMethod.Position).Take(VirualizedMethod.Size).ToArray(); byte[] HashKey = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(VirualizedMethod.Parent.Name)); var ReaderRef = MethodsTables.GetByRid(VirualizedMethod.Parent.MetadataToken.Rid).Body as PESegmentReference?; var Reader = ReaderRef.Value.CreateReader(); byte[] RawBody = ((DataSegment)CilRawMethodBody.FromReader(null, ref Reader).Code).Data; Utilities.BDerive(RawBytes, RawBytes.Length, RawBody, RawBody.Length); #endregion var Disassembler = new Disassembler(VirualizedMethod.Parent, Utilities.Decrypt(HashKey, RawBytes)); VirualizedMethod.Parent.CilMethodBody = Disassembler.BeginRead(); context.Logger.InfoFormat("Done Restoring {0} Instruction.", VirualizedMethod.Parent.CilMethodBody.Instructions.Count); } catch (Exception) /* It will not but maybe ¯\_(ツ)_/¯ */ { context.Logger.WarnFormat("Method {0} Failed Devirtualizaing.", VirualizedMethod.Parent.Name); } } var Resources = new List <string>() { "Eddy^CZ", "Eddy^CZ_", "RT", "X64", "X86" }; foreach (var Resource in context.Module.Resources.Where(x => Resources.Contains(x.Name)).ToArray()) { context.Module.Resources.Remove(Resource); } }
protected override MetadataRow <FileSegment, MethodImplAttributes, MethodAttributes, uint, uint, uint> ReadRow(ReadingContext context, MetadataToken token) { var reader = context.Reader; uint rva = reader.ReadUInt32(); var implAttributes = (MethodImplAttributes)reader.ReadUInt16(); FileSegment body = null; if (rva != 0) { long fileOffset = context.Assembly.RvaToFileOffset(rva); if (implAttributes.HasFlag(MethodImplAttributes.IL)) { body = CilRawMethodBody.FromReader(context.Reader.CreateSubReader(fileOffset)); } else { // TODO: handler for native method bodies. body = new DataSegment(new byte[0]) { StartOffset = fileOffset }; } } return(new MetadataRow <FileSegment, MethodImplAttributes, MethodAttributes, uint, uint, uint>(token) { Column1 = body, Column2 = implAttributes, // ImplAttrbibutes Column3 = (MethodAttributes)reader.ReadUInt16(), // Attributes Column4 = reader.ReadIndex(TableStream.StringIndexSize), // Name Column5 = reader.ReadIndex(TableStream.BlobIndexSize), // Signature Column6 = reader.ReadIndex(TableStream.GetTable(MetadataTokenType.Param).IndexSize) // ParamList }); }