NOP ATHROW hack defeated !

Rémi Forax <[email protected]>
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <[email protected]>
Charles Nutter (a JRuby guy) was able to generate a code that defeat
the infamous NOP ... ATHROW hack.

see http://asm.ow2.org/doc/developer-guide.html#deadcode
for the background.

Basically, when a code is dead, not reachable, ASM replaces the 
offending code by
NOP ... ATHROW and generate a dedicated stackmap: [] [java/lang/Throwable].
But if the unreachable code is in a try/catch, we create a path where no 
local variable
are available anymore. So the split verifier will reject the bytecode if
a local variable is used in the exception handler of the try/catch.

The program below generates a bytecode which is rejected by the split 
verifier.
[forax@localhost asm4-test]$ java deadcode
Exception in thread "main" java.lang.VerifyError: Stack map does not 
match the one at exception handler 7 in method 
deadcode.foo(Ljava/lang/Object;)V at offset 3
     at java.lang.Class.getDeclaredMethods0(Native Method)
     at java.lang.Class.privateGetDeclaredMethods(Class.java:2440)
     at java.lang.Class.getMethod0(Class.java:2683)
     at java.lang.Class.getMethod(Class.java:1618)
     at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484)
     at 
sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476)


Eric, do you see a solution for that ?

Rémi

----------------------------------------------------------------------------------------------------------------

import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.ATHROW;
import static org.objectweb.asm.Opcodes.GOTO;
import static org.objectweb.asm.Opcodes.ISTORE;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.objectweb.asm.Opcodes.V1_7;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.CheckClassAdapter;


public class DeadCode2 {
    public static void main(String[] args) throws IOException {
      ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
      writer.visit(V1_7, ACC_PUBLIC, "deadcode", null, 
"java/lang/Object", null);
      MethodVisitor mv = writer.visitMethod(ACC_PUBLIC|ACC_STATIC, 
"foo", "(Ljava/lang/Object;)V", null, null);
      mv.visitCode();

      Label L0, L1, L3;
      L0 = new Label(); L1 = new Label(); L3 = new Label();

      mv.visitTryCatchBlock(L0, L1, L1, "java/lang/RuntimeException");

      mv.visitLabel(L0);
      mv.visitJumpInsn(GOTO, L3);

      mv.visitLdcInsn("foo");
      mv.visitVarInsn(ASTORE, 0);
      mv.visitVarInsn(ISTORE, 0);

      mv.visitLabel(L1);

      mv.visitInsn(ATHROW);

      mv.visitLabel(L3);

      mv.visitInsn(RETURN);

      mv.visitMaxs(-1, -1);
      mv.visitEnd();

      writer.visitEnd();

      CheckClassAdapter.verify(new ClassReader(writer.toByteArray()), 
true, new PrintWriter(System.err));


      Files.write(Paths.get("deadcode.class"), writer.toByteArray());
   }
}
message-footer.txt (text/plain, 238 B)
-- 
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.