Recently I took a dive into the world of Microsoft Intermediate Language (MSIL). Why? I didn’t yet have the source code for an assembly I was referencing and I needed to remove a date validation constraint that was affecting the solution. This is how I resolved the situation:
- Disassembled the assembly into Microsoft Intermediate Language (IL) using the Microsoft IL Disassembler (ildasm.exe) located in “C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin”.
- Edited the MSIL file and updated the date validation code to pass validation.
- Assembled the IL back into an assembly using the Microsoft IL Assembler (ilasm.exe) located in “C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322”.
Pretty straight forward except for having to learn some MSIL. Oh, and there was also the effort required to identify the area of code in question. To cut that story short, I’ll simply say that I pinned down the boolean variable that was used to determine if today’s date was within or outside of the hard coded date range … and that variable is simply “named” variable “2”. I searched the MSIL file for all areas where variable “2” was updated and then came across the date validation logic that I had to amend.
Following is the MSIL code snippet containing the date validation check which I’ve amended to pass validation by “widening” the year values. This snippet is asking the question: Is the current date between Oct 3, 2009 and Aug 7, 2000? If so, then the “date invalid” flag is set to true, otherwise leave the “date invalid” flag as false.
- IL_0017: Get the current date and push it on to the stack.
- IL_001c: Push the value 0x7d9 (2009) on to the stack.
- IL_0021: Push the value 10 on to the stack.
- IL_0023: Push the value 3 on to the stack.
- IL_0024: Instantiate a DateTime instance for the date Oct 3, 2009. This will pop the year, month, and day values from the stack leaving the current date (from IL_017) at the top of the stack.
- IL_0029: Compare the current date to Oct 3, 2009 and place the result on the stack.
- IL_002e: Load the value 0 on to the stack.
- IL_002f: Compare the value 0 (from top of stack) to the DateTime::Compare result (second from top on the stack) and branch to IL_004a if greater than or equal. In other words, if “Now” is greater than or equal to Oct 3, 2009, branch to IL_004a where the date validation flag is set to true, meaning “failed validation”.
- IL_0031 to IL_0048: Compare “Now” to the date Aug 7, 2000 and branch to IL_004c if “Now” is greater than or equal to Aug 7, 2000. In other words, branch past the code that sets the date validation flag “invalid” (value of 1).
- IL_004a to IL_004b: Push the value 1 (true, in this case) on to the stack and store that value (stloc) in location 2 (“variable 2”). In order words set the “date is invalid” variable to true.