Introduction
Exception filters have been part of ECMA-335 specification since the very beginning. I'm guessing, they were added because Visual Basic used them extensively and therefore Visual Basic.NET had to support them as well. They look something like this:
Try
'Try statements.
Catch cle As ClassLoadException When cle.IsRecoverable()
'Catch statements.
End Try
Until now C# supported try/catch but did not have support for filters. That's going to change in C# 6.0/VS2015.
How does it work
In early versions of VS2015 the syntax was "catch-if", as you can see in the initial announcement. In the latest VS2015 CTP builds, they changed syntax to "catch-when", and there's a good reason for it.
So, how does it work and what does it mean for reversers?
It's a compiler-level feature
As I mentioned before, .NET Framework has supported exception filters since the very beginning. So, this feature works even in .NET 2.0 - if you decide to target .NET 2.0 Framework in VS2015 project settings. Not that you really want to do that..
It's very useful for debugging
catch-when is implemented as an IL exception filter. So, when an exception is thrown, exception filters are processed before the stack is unwound. This means that filter method has created an error report that included the current stack trace, it would show the frame in which the exception occurred. Sounds complicated? It isn't.
Let's implement exception filtering in the "old" way:
private void button2_Click(object sender, EventArgs e)
{
try
{
ThisCanThrow();
}
catch (Exception ex)
{
if (filter(ex))
textBox1.AppendText("Interesting exception");
else
throw(ex);
}
}
and this is how the stack looks when we get to filter(ex):
You can't see much here. All the context is gone, you must rely on exception stack trace and message. That's what we've always done, right? 🙂
If we write it in a "new" way, the code looks like this:
private void button1_Click(object sender, EventArgs e)
{
try
{
ThisCanThrow();
}
catch (Exception ex) when (filter(ex))
{
textBox1.AppendText("Interesting exception");
}
}
and stack trace will give us full context of exception:
Much better, isn't it? You can see which method threw the exception, on which line, you have access to local variables and everything else. Yummy! 🙂
Decompiler support for exception filters is crappy
They say, a picture is worth thousand words.. In a very simple example, Reflector gets the code structure right, just filter conditions are missing:
ILSpy handles it slightly worse, filters are messed up and unreadable. Filter code is gone, too:
And the latest JustDecompile just throws an exception:
Have fun with it!
Here is a small keygen-me for you to play with: https://www.mediafire.com/?k5b9vy0p9dfgb97
The difficulty is 2/10, you should be able to solve it in 30 minutes or so. The entire protection is designed to show you try-catch-when feature, so avoid patching - you can't learn anything by nopping-out few instructions. 😉