{"id":3560,"date":"2012-05-31T17:11:00","date_gmt":"2012-05-31T17:11:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/postsharp-obfuscation-and-il\/"},"modified":"2016-07-28T10:50:49","modified_gmt":"2016-07-28T10:50:49","slug":"postsharp-obfuscation-and-il","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/postsharp-obfuscation-and-il\/","title":{"rendered":"PostSharp, Obfuscation, and IL"},"content":{"rendered":"<p><a href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect-oriented_programming\">Aspect-oriented programming (AOP)<\/a> is a relatively new programming paradigm. Originating at Xerox PARC in 1994, the paradigm was first made available for general-purpose development as an extension to Java in 2001. From there, it has quickly been adapted for use in all the common languages used today. In the .NET world, one of the primary AOP toolkits is PostSharp.<\/p>\n<h4>Attributes and AOP<\/h4>\n<p>Normally, attributes in .NET are entirely a metadata construct. Apart from a few special attributes in the .NET framework, they have no effect whatsoever on how a class or method executes within the CLR. Only by using reflection at runtime can you access any attributes declared on a type or type member.<\/p>\n<p>PostSharp changes this. By declaring a custom attribute that derives from <code>PostSharp.Aspects.Aspect<\/code>, applying it to types and type members, and running the resulting assembly through the PostSharp postprocessor, you can essentially declare &#8216;clever&#8217; attributes that change the behaviour of whatever the aspect has been applied to at runtime.<\/p>\n<p>A simple example of this is logging. By declaring a <code>TraceAttribute<\/code> that derives from <code>OnMethodBoundaryAspect<\/code>, you can automatically log when a method has been executed:<\/p>\n<pre>public class TraceAttribute : PostSharp.Aspects.OnMethodBoundaryAspect\n{\n    public override void OnEntry(MethodExecutionArgs args)\n    {\n        MethodBase method = args.Method;\n        System.Diagnostics.Trace.WriteLine(\n            String.Format( \n                \"Entering {0}.{1}.\",\n                method.DeclaringType.FullName,\n                method.Name));\n    }\n    \n    public override void OnExit(MethodExecutionArgs args)\n    {\n        MethodBase method = args.Method;\n        System.Diagnostics.Trace.WriteLine(\n            String.Format( \n                \"Leaving {0}.{1}.\",\n                method.DeclaringType.FullName,\n                method.Name));\n    }\n}\n\n[Trace]\npublic void MethodToLog() { ... }<\/pre>\n<p>Now, whenever <code>MethodToLog<\/code> is executed, the aspect will automatically log entry and exit, without having to add the logging code to <code>MethodToLog<\/code> itself.<\/p>\n<h4>PostSharp Performance<\/h4>\n<p>Now this does introduce a performance overhead &#8211; as you can see, the aspect allows access to the <code>MethodBase<\/code> of the method the aspect has been applied to. If you were limited to C#, you would be forced to retrieve each <code>MethodBase<\/code> instance using <code>Type.GetMethod()<\/code>, matching on the method name and signature. This is slow. Fortunately, PostSharp is not limited to C#. It can use any instruction available in IL. And in IL, you can do some very neat things.<\/p>\n<h4>Ldtoken<\/h4>\n<p>C# allows you to get the <code>Type<\/code> object corresponding to a specific type name using the <code>typeof<\/code> operator:  <\/p>\n<pre>Type t = typeof(Random);<\/pre>\n<p>The C# compiler compiles this operator to the following IL:<\/p>\n<pre>ldtoken [mscorlib]System.Random\ncall class [mscorlib]System.Type\n    [mscorlib]System.Type::GetTypeFromHandle(\n        valuetype [mscorlib]System.RuntimeTypeHandle)<\/pre>\n<p>The <code>ldtoken<\/code> instruction obtains a special handle to a type called a <code>RuntimeTypeHandle<\/code>, and from that, the <code>Type<\/code> object can be obtained using <code>GetTypeFromHandle<\/code>. These are both relatively fast operations &#8211; no string lookup is required, only direct assembly and CLR constructs are used.<\/p>\n<p>However, a little-known feature is that <code>ldtoken<\/code> is not just limited to types; it can also get information on methods and fields, encapsulated in a <code>RuntimeMethodHandle<\/code> or <code>RuntimeFieldHandle<\/code>:  <\/p>\n<pre>\/\/ get a MethodBase for String.EndsWith(string)\nldtoken method instance bool [mscorlib]System.String::EndsWith(string)\ncall class [mscorlib]System.Reflection.MethodBase\n    [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(\n        valuetype [mscorlib]System.RuntimeMethodHandle)\n\n\/\/ get a FieldInfo for the String.Empty field\nldtoken field string [mscorlib]System.String::Empty\ncall class [mscorlib]System.Reflection.FieldInfo\n    [mscorlib]System.Reflection.FieldInfo::GetFieldFromHandle(\n        valuetype [mscorlib]System.RuntimeFieldHandle)<\/pre>\n<p>These usages of <code>ldtoken<\/code> aren&#8217;t usable from C# or VB, and aren&#8217;t likely to be added anytime soon (Eric Lippert&#8217;s done a <a href=\"http:\/\/blogs.msdn.com\/b\/ericlippert\/archive\/2009\/05\/21\/in-foof-we-trust-a-dialogue.aspx\">blog post<\/a> on the possibility of adding <code>infoof<\/code>, <code>methodof<\/code> or <code>fieldof<\/code> operators to C#). However, PostSharp deals directly with IL, and so can use <code>ldtoken<\/code> to get <code>MethodBase<\/code> objects quickly and cheaply, without having to resort to string lookups.<\/p>\n<h4>The kicker<\/h4>\n<p>However, there are problems. Because <code>ldtoken<\/code> for methods or fields isn&#8217;t accessible from C# or VB, it hasn&#8217;t been as well-tested  as <code>ldtoken<\/code> for types. This has resulted in various obscure bugs in most versions of the CLR when dealing with <code>ldtoken<\/code> and methods, and specifically, generic methods and methods of generic types. This means that PostSharp was behaving incorrectly, or just plain crashing, when aspects were applied to methods that were generic in some way.<\/p>\n<p>So, PostSharp has to work around this. Without using the metadata tokens directly, the only way to get the <code>MethodBase<\/code> of generic methods is to use reflection: <code>Type.GetMethod()<\/code>, passing in the method name as a string along with information on the signature.<\/p>\n<p>Now, this works fine. It&#8217;s slower than using <code>ldtoken<\/code> directly, but it works, and this only has to be done for generic methods. Unfortunately, this poses problems when the assembly is obfuscated.<\/p>\n<h4>PostSharp and Obfuscation<\/h4>\n<p>When using <code>ldtoken<\/code>, obfuscators don&#8217;t affect how PostSharp operates. Because the <code>ldtoken<\/code> instruction directly references the type, method or field within the assembly, it is unaffected if the name of the object is changed by an obfuscator. However, the indirect loading used for generic methods was breaking, because that uses the name of the method when the assembly is put through the PostSharp postprocessor to lookup the <code>MethodBase<\/code> at runtime. If the name then changes, PostSharp can&#8217;t find it anymore, and the assembly breaks.<\/p>\n<p>So, PostSharp needs to know about any changes an obfuscator does to an assembly. The way PostSharp does this is by adding another layer of indirection. When PostSharp obfuscation support is enabled, it includes an extra &#8216;name table&#8217; resource in the assembly, consisting of a series of method &amp; type names. When PostSharp needs to lookup a method using reflection, instead of encoding the method name directly, it looks up the method name at a fixed offset inside that name table:<\/p>\n<pre>MethodBase genericMethod = typeof(ContainingClass).GetMethod(GetNameAtIndex(22));\n\nPostSharp.NameTable resource:\n...\n20: get_Prop1\n21: set_Prop1\n22: DoFoo\n23: GetWibble<\/pre>\n<p>When the assembly is later processed by an obfuscator, the obfuscator can replace all the method and type names within the name table with their new name. That way, the reflection lookups performed by PostSharp will now use the new names, and everything will work as expected:<\/p>\n<pre>MethodBase genericMethod = typeof(#kGy).GetMethod(GetNameAtIndex(22));\n\nPostSharp.NameTable resource:\n...\n20: #kkA\n21: #zAb\n22: #EF5a\n23: #2tg<\/pre>\n<p>As you can see, this requires direct support by an obfuscator in order to perform these rewrites. Dotfuscator supports it, and now, starting with SmartAssembly 6.6.4, <a href=\"http:\/\/www.red-gate.com\/products\/dotnet-development\/smartassembly\/\">SmartAssembly<\/a> does too.<\/p>\n<p>So, a relatively simple solution to a tricky problem, with some CLR bugs thrown in for good measure. You don&#8217;t see those every day!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aspect-oriented programming (AOP) is a relatively new programming paradigm. Originating at Xerox PARC in 1994, the paradigm was first made available for general-purpose development as an extension to Java in 2001. From there, it has quickly been adapted for use in all the common languages used today. In the .NET world, one of the primary&#8230;&hellip;<\/p>\n","protected":false},"author":186659,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-3560","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3560","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/186659"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3560"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3560\/revisions"}],"predecessor-version":[{"id":42165,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3560\/revisions\/42165"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3560"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}