[libbluray-devel] Try to recover class files with broken debug info

hpi1 git at videolan.org
Sun Nov 1 18:39:28 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Sun Nov  1 19:26:59 2015 +0200| [092c420ac5381dc382714b9a39174cd8eb2ed949] | committer: hpi1

Try to recover class files with broken debug info

Fixes Penguins of Madagascar

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=092c420ac5381dc382714b9a39174cd8eb2ed949
---

 .../java/org/videolan/BDJClassFileTransformer.java |   93 ++++++++++++++++++++
 src/libbluray/bdj/java/org/videolan/Libbluray.java |    3 +
 2 files changed, 96 insertions(+)

diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
new file mode 100644
index 0000000..4f8cb32
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
@@ -0,0 +1,93 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2015  Petri Hintukainen <phintuka at users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package org.videolan;
+
+/**
+ * This is a class which is called by java.lang.ClassLoader
+ * when ClassFormatError is thrown inside defineClass().
+ *
+ * Some discs have invalid debug info in class files (broken by
+ * malfunctioning obfuscater ?).
+ * We strip debug info from the class and try to load it again.
+ *
+ * Penguins of MAdagascar:
+ *   java.lang.ClassFormatError: Invalid index 0 in LocalVariableTable'
+ *       in class file com/tcs/blr/bluray/pal/fox/controller/d
+ */
+
+import sun.misc.ClassFileTransformer;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Attribute;
+
+public class BDJClassFileTransformer extends ClassFileTransformer
+{
+    public byte[] transform(byte[] b, int off, int len)
+        throws ClassFormatError
+    {
+        logger.info("Trying to transform broken class file (" + len + " bytes)");
+
+        byte[] r = new byte[len];
+        for (int i = 0; i < len; i++)
+            r[i] = b[i+off];
+
+        try {
+            ClassReader cr = new ClassReader(r);
+            ClassWriter cw = new ClassWriter(cr, 0/*ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS*/);
+            ClassVisitor cv = new MyClassVisitor(cw);
+            cr.accept(cv, ClassReader.SKIP_DEBUG);
+            return cw.toByteArray();
+        } catch (Exception e) {
+            logger.error("Failed transforming class: " + e);
+        }
+
+        return r;
+    }
+
+    public class MyClassVisitor extends ClassVisitor {
+        public MyClassVisitor(ClassVisitor cv) {
+            super(Opcodes.ASM4, cv);
+        }
+
+        public MethodVisitor visitMethod(int access, String name, String desc,
+                                         String signature, String[] exceptions) {
+            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+            //System.err.println("visit method: " + name);
+            return new MyMethodVisitor(mv);
+        }
+    }
+
+    public class MyMethodVisitor extends MethodVisitor {
+        public MyMethodVisitor(MethodVisitor mv) {
+            super(Opcodes.ASM4, mv);
+        }
+
+        public void visitAttribute(Attribute attr) {
+            //System.err.println("    attribute: " + attr.type);
+            super.visitAttribute(attr);
+        }
+    }
+
+    private static final Logger logger = Logger.getLogger(BDJClassFileTransformer.class.getName());
+}
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index 1a67fc9..c9db9a1 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -93,6 +93,9 @@ public class Libbluray {
 
         hookProperties();
 
+        /* hook calss loading */
+        sun.misc.ClassFileTransformer.add(new BDJClassFileTransformer());
+
         /* set up directories */
         persistentRoot = canonicalize(persistentRoot, true);
         budaRoot       = canonicalize(budaRoot, true);



More information about the libbluray-devel mailing list