Editing assemblies using ReflexIL

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!

2 Comments

  • @@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).

  • 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

Comments have been disabled for this content.