Binary patching for fun and profit @ JUG.ru, 25.02.2012

6,415 views

Published on

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,415
On SlideShare
0
From Embeds
0
Number of Embeds
5,278
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Binary patching for fun and profit @ JUG.ru, 25.02.2012

  1. 1. Binary Patching for Fun and Profit with JRebel SDK
  2. 2. Binary PatchingNinja.class Ninja.class’10101010101 1010101010111000101010 1110000101010101010001 1010101000100010001110 0001000111011011101011 11011101110 a.k.a instrumentation
  3. 3. Binary Patching ClassLoaderApplication MyClass.class New code: 1001010010010 Transformer 0101011001010 MyObject
  4. 4. Why?• Programming model (AOP, ORM)• Tooling (profilers, coverage)• Legacy integration… or maybe you’re just bored? 
  5. 5. How?• Add –javaagent to hook into class loading process• Implement ClassFileTransformer• Use bytecode manipulation libraries (Javassist, cglib, asm) to add any custom logic java.lang.instrument
  6. 6. java.lang.instrumentimport java.lang.instrument.ClassFileTransformer;import java.lang.instrument.Instrumentation;public class Agent { public static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { … }); }}
  7. 7. java.lang.instrumentimport java.lang.instrument.ClassFileTransformer;import java.lang.instrument.Instrumentation;public class Agent { public static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { … }); }}
  8. 8. java.lang.instrumentimport java.lang.instrument.ClassFileTransformer;import java.lang.instrument.Instrumentation; META-INF/MANIFEST.MFpublic class Agent { Premain-Class: Agent public static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { … }); }} java –javaagent:agent.jar …
  9. 9. j.l.instrument.ClassFileTransformernew ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); }}
  10. 10. j.l.instrument.ClassFileTransformernew ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); }}
  11. 11. j.l.instrument.ClassFileTransformernew ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); }}
  12. 12. j.l.instrument.ClassFileTransformernew ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?>classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); transformClass(ct, cp); return ct.toBytecode(); }}
  13. 13. Javassist 1-2-3
  14. 14. Javassist• Bytecode manipulation made easy• Source-level and bytecode-level API• Uses the vocabulary of Java language• On-the-fly compilation of the injected code• http://www.jboss.org/javassist
  15. 15. Adding InterfacesClassPool cp = ClassPool.getDefault();CtClass ct = cp.get("org.geecon.Alarm");ct.addInterface(cp.get(Listener.class.getName()));ct.addMethod(CtNewMethod.make("public void fire(){ alert(); }", ct));public class Alarm { public interface Listener { void alert() {} void fire();} }
  16. 16. Adding InterfacesClassPool cp = ClassPool.getDefault();CtClass ct = cp.get("org.geecon.Alarm");ct.addInterface(cp.get(Listener.class.getName()));ct.addMethod(CtNewMethod.make("public void fire(){ alert(); }", ct));public class Alarm { public interface Listener { void alert() {} void fire();} }
  17. 17. Adding InterfacesClassPool cp = ClassPool.getDefault();CtClass ct = cp.get("org.geecon.Alarm");ct.addInterface(cp.get(Listener.class.getName()));ct.addMethod(CtNewMethod.make("public void fire(){ alert(); }", ct));public class Alarm { public interface Listener { void alert() {} void fire();} }
  18. 18. Adding InterfacesClassPool cp = ClassPool.getDefault();CtClass ct = cp.get("org.geecon.Alarm");ct.addInterface(cp.get(Listener.class.getName()));ct.addMethod(CtNewMethod.make("public void fire(){ alert(); }", ct));public class Alarm { public interface Listener { void alert() {} void fire();} }
  19. 19. Simple AOPProxyFactory pf = new ProxyFactory();pf.setSuperclass(Notifier.class);pf.setFilter(new MethodFilter() { … });Notifier notifier = (Notifier) pf.createClass().newInstance();((ProxyObject) notifier).setHandler(new MethodHandler() { … });System.out.println("calling on()");notifier.on(); public class Notifier {System.out.println("calling off()"); public void on(){ }notifier.off(); @Pointcut public void off(){} }
  20. 20. Intercept StatementsClassPool pool = ClassPool.getDefault();CtClass ct = pool.get("org.geecon.PaymentMachine");ct.getDeclaredMethod("process") .instrument(new ExprEditor() { public void edit(NewExpr e) throws CannotCompileException { e.replace("$_ = $proceed($$);"); }});
  21. 21. JRebel SDK Ö_õ
  22. 22. IDEs Containers Frameworks Build ToolsMore at http://www.jrebel.com/features

×