分享

Editing assemblies using ReflexIL

 Jcstone 2013-05-16

I have known ReflexIL for quite some time, so I thought I’ll write a line or two about this simple and yet power tool. This tool runs as a plug-in for Red Gate’s Reflector.

I’m not sure if I can cover all the features of this tool, but there are a couple that I really liked that we’ll just see those. In order to get it working, you unzip the contents of the file to some folder. In Reflector, under Tools->Add-Ins add the path to the Reflexil.Reflector.dll.

image

And, you’re set. To bring up the add-in, you just go Tools->ReflexIL.

image

I have a simple console application to calculate and display the area of a circle.

   1:  public const double Pi = 3.14;
   2:  public static void Main()
   3:  {
   4:      int radius = 10;
   5:   
   6:      double areaOfCircle = Pi*radius*radius;
   7:   
   8:      Console.WriteLine(areaOfCircle);
   9:  }

image

To let’s see what we can do with ReflexIL, I’ll add the .exe to Reflector.

image

So you see that there is no reference of the const member Pi in our code. Instead, the member Pi is replaced with it’s value at every reference. Why? See more here. Basically, since Pi is a compile time constant, its value is replaced at every location to optimize the code. What this also means, is that say if I got the const member Pi from a different assembly and if that was the only member I used from that assembly, I can physically delete that third party assembly from my bin directory and the application will just work fine. This is because the value is already replaced in the IL and no reference of that assembly exists in my code.

Now let’s go ahead and change that value to something else. I just right click on the instruction and choose Edit.

image

image

Here I have changed the value to 3. I click on update and right-click on the assembly to get the save option:

image

By default, it appends the file name with ‘.Patched’; you are free to change the name of the file. Now when I run the patched exe file, I , of course, get a ‘patched’ output!

image

That wasn’t hard now was it? But let’s do something a little more interesting.

The below snippet is bound to throw a null reference exception as the variable p is not instantiated before the GetInt method is called. The code compiles just fine however.

   1:  public static void Main()
   2:  {
   3:      try
   4:      {
   5:          Program p = null;
   6:          Console.WriteLine(p.GetInt());// In C#, NullReferenceException is thrown
   7:      }
   8:      catch (Exception exception)
   9:      {
  10:          Console.WriteLine(exception);
  11:      }
  12:  }
  13:   
  14:  public int GetInt()
  15:  {
  16:      return 10;
  17:  }

I again load the assembly in Reflector and see the instructions in ReflexIL. I’m specifically interested in the line that calls the GetInt method.

image

Now, all I do is to edit the line and change the OpCode from callvirt to call. Click on Update, save the assembly to a patched version.

image

image

Tadaa.. no exception. Here’s what happened.

I changed the OpCode to ‘call’ instead of ‘callvirt’. The call IL instruction assumes that the variable that refers to an object, in this case ‘p’, is not null. This is useful for say, static methods. The callvirt IL instruction however requires that the variable that refers to an object is never null. In other words, callvirt does a null check on that variable, but call does not. That’s the reason change the instruction to call made the exception just disappear. So things like this can be easily changed with a tool like ReflexIL.

ReflexIL also shows the meaning of the each of the instructions (you might not understand all of them at first, I know I didn’t). In the above screenshots you see the ‘Edit existing instruction’ window has a description field. This will help you understand CLR at a deeper level.

There are other things you can do with the tool like editing attributes, removing assembly strong name and updating referencing assemblies and removing, deleting or injecting entities

I recall the saying ‘With great power, comes great responsibility’ and have fun learning more of CLR stuff!

Published Sunday, September 02, 2012 5:49 PM by nmarun
Filed under: , , ,

Comments

# re: Editing assemblies using ReflexIL

Monday, September 03, 2012 7:58 PM by puma

I love the way you wrote this article. This is wonderful. I do hope you intend to write more of these types of articles. Thank you for this interesting content!

# re: Editing assemblies using ReflexIL

Monday, September 10, 2012 4:06 PM by Sean Mahan

Hi, great article. Have you seen DILE (Dotnet IL Editor). /.../dile It's also a great tool for learning what's going on with the IL and you don't have to have anything to do with Redgate to use it.

Thanks

# re: Editing assemblies using ReflexIL

Monday, September 17, 2012 8:38 AM by nmarun

@@Sean, I've definitely seen DILE. I did not get to play with it as much, but I did not find a way to edit the your IL and recompile (or may I din't look welll enough).

# re: Editing assemblies using ReflexIL

Tuesday, September 18, 2012 9:55 AM by uk dissertation help

Its great to see that people are sharing pretty gainful information with each other and now we can shift our selves to a new era.

# re: Editing assemblies using ReflexIL

Monday, December 17, 2012 10:53 AM by Sebastien LEBRETON (Reflexil author)

Thanks for this article.

I think the "killer" thing is the "replace all with code" feature.

You can check here:

http://www./Articles/20565/Assembly-Manipulation-and-C-VB-NET-Code-Injection

# re: Editing assemblies using ReflexIL

Monday, January 07, 2013 3:06 AM by sames

hi,

i am useing Reflexil 1.5 ver it shows error Reflexil is unable to save this aaaembly; unable to cast object of type 'system.Boolean'to type 'system.string'.

how to fix

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多