binary patching for fun and profit @ jug.ru, 25.02.2012
DESCRIPTION
TRANSCRIPT
![Page 1: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/1.jpg)
Binary Patching for Fun and Profit
withJRebel SDK
![Page 2: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/2.jpg)
Binary Patching
1010101010111000101010101010100010001000111011011101011
1010101010111100001010101010100010001000111011011101110
Ninja.class Ninja.class’
a.k.a instrumentation
![Page 3: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/3.jpg)
Binary Patching
MyClass.class
New code:10010100100100101011001010
ClassLoader
MyObject
Transformer
Ap
plicati
on
![Page 4: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/4.jpg)
Why?
• Programming model (AOP, ORM)• Tooling (profilers, coverage)• Legacy integration
… or maybe you’re just bored?
![Page 5: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/5.jpg)
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
![Page 6: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/6.jpg)
java.lang.instrument
import 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 { … }); }}
![Page 7: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/7.jpg)
java.lang.instrument
import 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 { … }); }}
![Page 8: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/8.jpg)
java.lang.instrument
import 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 { … }); }}
META-INF/MANIFEST.MFPremain-Class: Agent
java –javaagent:agent.jar …
![Page 9: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/9.jpg)
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(); }}
![Page 10: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/10.jpg)
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(); }}
![Page 11: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/11.jpg)
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(); }}
![Page 12: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/12.jpg)
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(); }}
![Page 13: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/13.jpg)
Javassist1-2-3
![Page 14: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/14.jpg)
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
![Page 15: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/15.jpg)
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 interface Listener {
void fire();
}
public class Alarm {
void alert() {}
}
![Page 16: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/16.jpg)
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 interface Listener {
void fire();
}
public class Alarm {
void alert() {}
}
![Page 17: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/17.jpg)
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 interface Listener {
void fire();
}
public class Alarm {
void alert() {}
}
![Page 18: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/18.jpg)
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 interface Listener {
void fire();
}
public class Alarm {
void alert() {}
}
![Page 19: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/19.jpg)
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();
System.out.println("calling off()");notifier.off();
public class Notifier {
public void on(){ }
@Pointcut public void off(){}}
![Page 20: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/20.jpg)
Intercept Statements ClassPool 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($$);"); } });
![Page 21: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/21.jpg)
JRebel SDKÖ_õ
![Page 22: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/22.jpg)
IDEs Containers Frameworks
Build Tools
More at http://www.jrebel.com/features
![Page 23: Binary patching for fun and profit @ JUG.ru, 25.02.2012](https://reader034.vdocuments.site/reader034/viewer/2022042713/5455f63caf79592b448b4bda/html5/thumbnails/23.jpg)