Coder Social home page Coder Social logo

mono.reflection's People

Contributors

hazzik avatar jbevain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mono.reflection's Issues

Executing result of GetInstructions

Hi.
I am using this library for generating opcodes from a CIL byte[] alongside with the Harmony project.
My concept is to recompile a changed source code on the fly, get a method from the new assembly and then its instructions and replace the new instructions with the old one.

So I have been using the library for getting the new instructions. All works very well until the library encounter a branch instruction in the new code.

Inside the MethodBodyReader.ResolveBranches you have this

switch (instruction.OpCode.OperandType) {
				case OperandType.ShortInlineBrTarget:
				case OperandType.InlineBrTarget:
					instruction.Operand = GetInstruction (instructions, (int) instruction.Operand);
					break;

Which throws exception when harmony is using the opcodes to patch the method.

Given that the operand of branches needs to be an offset to the instruction to branch to, I changed the code to this

var targetInstruction = GetInstruction(instructions, (int)instruction.Operand);
int byteOffset = targetInstruction.Offset - instruction.Offset - 1;
int targetOffset = instructions.IndexOf(targetInstruction);
int instructionOffset = targetOffset - index - 1;
instruction.Operand = (sbyte)(instructionOffset);// //GetInstruction(instructions, (int)instruction.Operand);

But I still get exception anyway. Any pointers from you please...

DLL produced causes LoaderException during AssemblyLoad in vNext

I load an assembly as follows:
AssemblyDefinition asm2 = MetadataMapper.MapAssembly(AppDomain.CurrentDomain.GetAssemblies().Where(x => x.FullName == "Ats.OpenOne.Web.Controllers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").First());

That part works fine. Next, I write the DLL out to a file, as follows:
asm2.Write(@"C:\Source\Workspace\Ats.OpenOne\artifacts\bin" + projectNames[10] + @"\Debug\dnx451" + projectNames[10] + "_.dll");

When I attempt to load the assembly into memory, I get a LoaderException upon hitting this code:
Assembly onDiskAssembly2 = Assembly.LoadFile(@"C:\Source\Workspace\Ats.OpenOne\artifacts\bin" + projectNames[10] + @"\Debug\dnx451" + projectNames[10] + "_.dll");

I've researched into this and the main difference I see is MetadataSystem is null, but is populated when I load a DLL written by Mono Cecil from disk.

.NET Standard support

In case someone comes here looking to see if this library can support .NET Standard and .NET Core, I've attached the compatibility report from apiport.exe. No support possible until .NET Standard 2.0 it seems.

ApiPortAnalysis.xlsx

@hazzik in case you look at this for DelegateDecompiler

bug in short branch target calculation

MethodBodyReader.cs:

case OperandType.ShortInlineBrTarget:
instruction.Operand = (sbyte) (((sbyte) il.ReadByte ()) + il.position);

this calcs an absolute offset within the ilstream but truncates the result to
an sbyte. In case the branch target is > 255 this will be wrong!

Either return the relative offset as sbyte or the absolute position within the stream as int/long

Some instructions for noobs

It will be good if in readme or somewhere there was more detailed examples for noobs like me, because I can't find a way to read the method body.

maximum i've found an example (after spent much time in google), was this example:

foreach( var x in Mono.Reflection.Disassembler.GetInstructions( MethodBase.GetMethod("method-name-here")   )){
	 PrintInstruction(x);	
}

however, I cant understand what is the PrintInstruction at all or how to get method by it's name? (the above code is incorrect)?

  1. i just want to output the result (string) in console.
  2. I wished also example how to read as string from bytes[] returned by ... MethodBase.GetMethod("method-name-here").GetMethodBody().GetILAsByteArray()

Operation is not valid due to the current state of the object. on .GetBackingfield()

Hey there,

I am playing a little with Mono.Reflection in a .Net 3.5 project to get a Property's BackingField and its attributes. However, the propertyInfo.GetBackingField() method throws an InvalidOperationException... :-/

Sample Code:

var propertyInfos = myObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

foreach (var propertyInfo in propertyInfos)
{
var backingField = propertyInfo.GetBackingField();
// >> throws System.InvalidOperationException
}

More details:

Source: "Mono.Reflection"
Message: "Operation is not valid due to the current state of the object."

StackTrace:
at Mono.Reflection.BackingFieldResolver.GetBackingField(MethodInfo method, ILPattern pattern)
at Mono.Reflection.BackingFieldResolver.GetBackingField(PropertyInfo self)

TargetSite: "System.Reflection.FieldInfo GetBackingField(System.Reflection.MethodInfo, Mono.Reflection.ILPattern)"

Any ideas why this is happening?

-J

Non-standard IL code can crash the library

Normally the this parameter is ldarg.0 . If you write "by hand" the IL code, it isn't illegal to use ldarg 0 or ldarg_s 0 (where 0 in this case is the operand). This will break the Mono.Reflection at this line:

    ParameterInfo GetParameter (int index)
    {
        return parameters [method.IsStatic ? index : index - 1];
    }

in the MethodBodyReader.cs, because index will be 0, 0 - 1 == -1, parameters[-1] = IndexOutOfRangeException

How to work with Async method

There is async stuff everywhere and GetInstructions of an async method only return the async setup (for what I understand) and then, there are MoveNext method with logic in there...
Is there any plan to support that?
Do you have suggestion about how to navigate through this stuff?

Thanks

Can we use DelegateDecomiler when we obfuscate the code?

We are using 'Dotfuscator' to obfuscate the dlls. We started using DelegateDecompiler for supporting some functionality when using entity framework. The issue is that after obfuscation, the EF method call fails. We tried to Exclude the classes used in the EF calls from obfuscation but still the issue is there.

The following is the error we are getting

System.AggregateException: One or more errors occurred. ---> System.ArgumentException: metadataToken
Parameter name: Token 0x5d07727e is not a valid MemberInfo token in the scope of module RBS.Advisor.BusinessEntities.dll.
at System.Reflection.RuntimeModule.ResolveMember(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at Mono.Reflection.MethodBodyReader.ReadOperand(Instruction instruction)
at Mono.Reflection.MethodBodyReader.ReadInstructions()
at Mono.Reflection.MethodBodyReader.GetInstructions(MethodBase method)
at Mono.Reflection.Disassembler.GetInstructions(MethodBase self)
at DelegateDecompiler.MethodBodyDecompiler.Decompile()
at DelegateDecompiler.DecompileExtensions.<>c__DisplayClass2_0.b__0(MethodInfo m)
at DelegateDecompiler.Cache2.GetOrAdd(TKey key, Func2 func)
at DelegateDecompiler.DecompileExtensions.Decompile(MethodInfo method)
at DelegateDecompiler.DecompileExpressionVisitor.Decompile(MethodInfo method, Expression instance, IList1 arguments) at DelegateDecompiler.DecompileExpressionVisitor.VisitMember(MemberExpression node) at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node) at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node) at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection1 nodes, Func2 elementVisitor) at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node) at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node)
at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node) at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes) at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node) at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node) at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at DelegateDecompiler.DecompiledQueryProvider.CreateQuery[TElement](Expression expression) at System.Linq.Queryable.Select[TSource,TResult](IQueryable1 source, Expression1 selector) at RBS.Advisor.AppServices.Households.HouseholdAppService.GetAuditEntries(Int32 householdId) at RBS.Advisor.Presentation.Modules.HouseholdModule.HouseholdView.AuditEntryController.<>c__DisplayClass8_0.<LoadData>b__0() at System.Threading.Tasks.Task.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of inner exception stack trace --- ---> (Inner Exception #0) System.ArgumentException: metadataToken Parameter name: Token 0x5d07727e is not a valid MemberInfo token in the scope of module RBS.Advisor.BusinessEntities.dll. at System.Reflection.RuntimeModule.ResolveMember(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) at Mono.Reflection.MethodBodyReader.ReadOperand(Instruction instruction) at Mono.Reflection.MethodBodyReader.ReadInstructions() at Mono.Reflection.MethodBodyReader.GetInstructions(MethodBase method) at Mono.Reflection.Disassembler.GetInstructions(MethodBase self) at DelegateDecompiler.MethodBodyDecompiler.Decompile() at DelegateDecompiler.DecompileExtensions.<>c__DisplayClass2_0.<Decompile>b__0(MethodInfo m) at DelegateDecompiler.Cache2.GetOrAdd(TKey key, Func2 func) at DelegateDecompiler.DecompileExtensions.Decompile(MethodInfo method) at DelegateDecompiler.DecompileExpressionVisitor.Decompile(MethodInfo method, Expression instance, IList1 arguments)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMember(MemberExpression node)
at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection1 nodes, Func2 elementVisitor)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node) at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at DelegateDecompiler.DecompileExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at DelegateDecompiler.DecompiledQueryProvider.CreateQuery[TElement](Expression expression)
at System.Linq.Queryable.Select[TSource,TResult](IQueryable1 source, Expression1 selector)
at RBS.Advisor.AppServices.Households.HouseholdAppService.GetAuditEntries(Int32 householdId)
at RBS.Advisor.Presentation.Modules.HouseholdModule.HouseholdView.AuditEntryController.<>c__DisplayClass8_0.b__0()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()<---
One or more errors occurred. Source:

When I posted this at hazzik/DelegateDecompiler#103

I have been adviced to post it here.

Thanks

Detect call to overriden method

Hi,

Thanks for your work!
I used your code in a try to program a custom tool detecting the "dead" code in our platform, however i have an issue in order to detect overriden method calls. For example :

class mother{
     public void Final() {}

     public virtual void Virtual() {}
}
class child : mother{
     public override voif Virtual() { base.Virtual(); .... }
}
class example{
     public static method() {
           var c = new child();
           c.Final();    // Instruction.Operand == mother.Final(), that is correct
           c.Virtual(); // Instruction.Operand == mother.Virtual() instead of child.Virtual()
     }
}

I expect this is really what is encoded in IL (call to mother.Virtual()) but i would need to be able to "know" that operand actually targets child.Virtual();

Any suggestion ?

Thanks in advance
JR

GetBackingField() extension method fails when being run by code coverage report

This is a very strange issue for sure, but I wanted to reach out and see if you had any ideas.

I am using the GetBackingField extension in a project that can store collections of objects using Excel xlsx files and materialize the same classes from saved xlsx files. One of the design goals was to avoid forcing consumers to declare public setters in order to load from xlsx files. I found your library extremely helpful in resolving the backing fields for Automatic Properties.

I wanted to get an idea of what work was left to do from a test writing perspective so I tried to run the "Code Coverage" report in Visual Studio. During the test runs kicked off by the report, none of my calls to GetBackingField() succeed. They all work as expected in other scenarios though - including using the library and running the tests manually (Live Unit Testing seems to get stuck and never discover the tests which I suspect is related to the coverage report). The error that gets logged during the report generation is:

System.ArgumentException: Value does not fall within the expected range.
at Mono.Reflection.BackingFieldResolver.GetBackingField(MethodInfo method, ILPattern pattern)
at Mono.Reflection.BackingFieldResolver.GetBackingField(PropertyInfo self)

If you have any ideas, I'd very much appreciate it. I can live without the code coverage report though. At this point I'm more curious about why there is divergence.

My project is a .NET Standard Class Library and my testing project is .NET Core 3.1.

"Operation could destabilize the runtime." when using IL to create a DynamicMethod

Maybe I completely misunderstand some basics, but I thought it would be possible to do the following:

 Action<string> myAction = s =>
{
    Console.WriteLine("Hello " + s);
};
IList<Instruction> instructions = myAction.GetMethodInfo().GetInstructions();
DynamicMethod dynamicCallback = new DynamicMethod("myAction", typeof(void), new Type[] { typeof(string) }, true);
ILGenerator il = dynamicCallback.GetILGenerator();
foreach (Instruction instruction in instructions)
{
    il.Emit(instruction.OpCode);
}
dynamicCallback.Invoke(null, new object[] { "World" });

But doing so will end up with a TargetInvocationException with the message: "Operation could destabilize the runtime.".

According to my understanding the il code generated with your extension library should be valid to be used to create a DynamicMethod, isn't it? So I suppose there is an issue with the generated IL code. Please forgive me when I wrong and I misunderstood some basics about IL generation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.