Skip to content

Commit

Permalink
UPCSEC-0000 Added support for multiple methods patching in the same c…
Browse files Browse the repository at this point in the history
…lass (v1.0.1)
  • Loading branch information
Vladimir committed May 27, 2016
1 parent 754a5c6 commit 00922cc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group 'FTC-Prepaid'
version '1.0'
version '1.0.1'

apply plugin: 'java'

Expand Down
35 changes: 25 additions & 10 deletions src/main/java/ru/ftc/upc/testing/dropper/PatchingTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;

import static java.lang.String.format;
Expand All @@ -22,7 +22,7 @@
class PatchingTransformer implements ClassFileTransformer {
private static final Logger log = LoggerFactory.getLogger(PatchingTransformer.class);

private final Map<String, Droplet> dropletMap = new HashMap<String, Droplet>();
private final DropletsMap dropletMap = new DropletsMap();
private final ClassPool pool;

PatchingTransformer(Set<Droplet> droplets) {
Expand All @@ -44,28 +44,43 @@ public byte[] transform(ClassLoader loader,
return null;
}
try {
return applyDroplet(dropletMap.get(className), classFileBuffer);
return applyDroplets(dropletMap.get(className), classFileBuffer);

} catch (Exception e) {
log.error(format("Failed to patch class '%s'. Class skipped.", className), e);
return null;
}
}

private byte[] applyDroplet(Droplet droplet, byte[] classFileBuffer) throws Exception {
String className = droplet.getClazz();
private byte[] applyDroplets(Set<Droplet> droplets, byte[] classFileBuffer) throws Exception {
String className = droplets.iterator().next().getClazz();
pool.insertClassPath(new ByteArrayClassPath(className, classFileBuffer));
CtClass ctClass = pool.get(className);
if (ctClass.isFrozen())
throw new IllegalStateException(format("Class '%s' is frozen.", ctClass.getName()));

CtMethod ctMethod = ctClass.getDeclaredMethod(droplet.getMethod());
for (Droplet droplet : droplets) {
CtMethod ctMethod = ctClass.getDeclaredMethod(droplet.getMethod());

Cutpoint cutpoint = droplet.getCutpoint();
MethodPatcher patcher = cutpoint.patcherClass.newInstance();
Cutpoint cutpoint = droplet.getCutpoint();
MethodPatcher patcher = cutpoint.patcherClass.newInstance();

patcher.apply(ctMethod, droplet);
log.info("Class {} has been patched with {}.", ctClass.getName(), patcher.getClass().getSimpleName());
patcher.apply(ctMethod, droplet);
log.info("Method {} of class {} has been patched with {}.", ctMethod.getName(), ctClass.getName(),
patcher.getClass().getSimpleName());
}
return ctClass.toBytecode();
}

static class DropletsMap extends HashMap<String, Set<Droplet>> {

void put(String key, Droplet value) {
Set<Droplet> droplets = this.get(key);
if (droplets == null) {
droplets = new HashSet<Droplet>();
super.put(key, droplets);
}
droplets.add(value);
}
}
}

0 comments on commit 00922cc

Please sign in to comment.