use of org.objectweb.asm.tree.LabelNode in project Bookshelf by Darkhax-Minecraft.
the class TransformerEnchantmentHelper method transform.
public static byte[] transform(String name, String transformedName, byte[] classBytes) {
final ClassNode clazz = ASMUtils.createClassFromByteArray(classBytes);
final MethodNode method = METHOD_GET_ENCH_LEVEL.getMethodNode(clazz);
final InsnList n1 = new InsnList();
final LabelNode start = new LabelNode();
n1.add(start);
n1.add(new TypeInsnNode(Opcodes.NEW, "net/darkhax/bookshelf/events/EnchantmentModifierEvent"));
n1.add(new InsnNode(Opcodes.DUP));
n1.add(new VarInsnNode(Opcodes.ALOAD, 0));
n1.add(new VarInsnNode(Opcodes.ALOAD, 1));
n1.add(METHOD_INIT_EVENT.getMethodInsn(Opcodes.INVOKESPECIAL, false));
n1.add(new VarInsnNode(Opcodes.ASTORE, 2));
final LabelNode l1 = new LabelNode();
n1.add(l1);
n1.add(FIELD_EVENT_BUS.getFieldNode(Opcodes.GETSTATIC));
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_POST.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
n1.add(new InsnNode(Opcodes.POP));
final LabelNode l2 = new LabelNode();
n1.add(l2);
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_CANCELED.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
final LabelNode vanillaLogic = new LabelNode();
n1.add(new JumpInsnNode(Opcodes.IFEQ, vanillaLogic));
final LabelNode l4 = new LabelNode();
n1.add(l4);
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_GET_LEVELS.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
n1.add(new InsnNode(Opcodes.IRETURN));
n1.add(vanillaLogic);
method.instructions.insertBefore(method.instructions.getFirst(), n1);
return ASMUtils.createByteArrayFromClass(clazz, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
}
use of org.objectweb.asm.tree.LabelNode in project Galacticraft by micdoodle8.
the class ASMBlock method applyLabels.
public ASMBlock applyLabels(InsnListSection list2) {
if (labels.isEmpty()) {
return new ASMBlock(list2);
}
Set<LabelNode> cFlowLabels1 = labels.values();
Set<LabelNode> cFlowLabels2 = InsnComparator.getControlFlowLabels(list2);
ASMBlock block = new ASMBlock(list2);
HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
for (int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
AbstractInsnNode insn1 = list.get(i);
if (!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
i++;
continue;
}
AbstractInsnNode insn2 = list2.get(k);
if (!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
k++;
continue;
}
if (insn1.getOpcode() != insn2.getOpcode()) {
throw new IllegalArgumentException("Lists do not match:\n" + list + "\n\n" + list2);
}
switch(insn1.getType()) {
case LABEL:
labelMap.put((LabelNode) insn1, (LabelNode) insn2);
break;
case JUMP_INSN:
labelMap.put(((JumpInsnNode) insn1).label, ((JumpInsnNode) insn2).label);
break;
}
i++;
k++;
}
for (Entry<String, LabelNode> entry : labels.entrySet()) {
block.labels.put(entry.getKey(), labelMap.get(entry.getValue()));
}
return block;
}
use of org.objectweb.asm.tree.LabelNode in project Galacticraft by micdoodle8.
the class ASMBlock method mergeLabels.
/**
* Pulls all common labels from other into this
*
* @return this
*/
public ASMBlock mergeLabels(ASMBlock other) {
if (labels.isEmpty() || other.labels.isEmpty()) {
return this;
}
// common labels, give them our nodes
HashMap<LabelNode, LabelNode> labelMap = list.identityLabelMap();
for (Entry<String, LabelNode> entry : other.labels.entrySet()) {
LabelNode old = labels.get(entry.getKey());
if (old != null) {
labelMap.put(old, entry.getValue());
}
}
HashSet<LabelNode> usedLabels = new HashSet<LabelNode>();
for (AbstractInsnNode insn = other.list.list.getFirst(); insn != null; insn = insn.getNext()) {
if (insn.getType() == LABEL) {
usedLabels.add((LabelNode) insn);
}
}
replaceLabels(labelMap, usedLabels);
return this;
}
use of org.objectweb.asm.tree.LabelNode in project Galacticraft by micdoodle8.
the class ASMBlock method replaceLabels.
public void replaceLabels(Map<LabelNode, LabelNode> labelMap, Set<LabelNode> usedLabels) {
for (AbstractInsnNode insn : list) {
switch(insn.getType()) {
case LABEL:
AbstractInsnNode insn2 = insn.clone(labelMap);
if (// identity mapping
insn2 == insn) {
continue;
}
if (usedLabels.contains(insn2)) {
throw new IllegalStateException("LabelNode cannot be a part of two InsnLists");
}
list.replace(insn, insn2);
break;
case JUMP_INSN:
case FRAME:
case LOOKUPSWITCH_INSN:
case TABLESWITCH_INSN:
list.replace(insn, insn.clone(labelMap));
}
}
for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
String key = labels.inverse().get(entry.getKey());
if (key != null) {
labels.put(key, entry.getValue());
}
}
}
use of org.objectweb.asm.tree.LabelNode in project phosphor by gmu-swe.
the class TaintTrackingClassVisitor method visitMethod.
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("hashCode") && desc.equals("()I"))
generateHashCode = false;
if (name.equals("equals") && desc.equals("(Ljava/lang/Object;)Z"))
generateEquals = false;
superMethodsToOverride.remove(name + desc);
if (name.equals("compareTo"))
implementsComparable = false;
if (name.equals("hasAnyTaints"))
isProxyClass = true;
// Hack needed for java 7 + integer->tostring fixes
if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("toUnsignedString"))
access = (access & ~Opcodes.ACC_PRIVATE) | Opcodes.ACC_PUBLIC;
if (name.contains(TaintUtils.METHOD_SUFFIX)) {
// Some dynamic stuff might result in there being weird stuff here
return new MethodVisitor(Opcodes.ASM5) {
};
}
if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethodFromOurAnalysis(className, name, desc)) {
// if (TaintUtils.DEBUG_CALLS)
// System.out.println("Skipping instrumentation for class: " + className + " method: " + name + " desc: " + desc);
String newName = name;
String newDesc = desc;
if (!name.contains("<") && 0 == (access & Opcodes.ACC_NATIVE))
newName = name + TaintUtils.METHOD_SUFFIX_UNINST;
else if (name.equals("<init>")) {
newDesc = desc.substring(0, desc.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + desc.substring(desc.indexOf(')') + 1);
}
newDesc = TaintUtils.remapMethodDescForUninst(newDesc);
MethodVisitor mv = super.visitMethod(access, newName, newDesc, signature, exceptions);
mv = new UninstTaintSentinalArgFixer(mv, access, newName, newDesc, desc);
mv = new SpecialOpcodeRemovingMV(mv, ignoreFrames, className, fixLdcClass);
MethodVisitor _mv = mv;
NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
mv = new UninstrumentedReflectionHidingMV(analyzer, className);
mv = new UninstrumentedCompatMV(access, className, name, newDesc, signature, (String[]) exceptions, mv, analyzer, ignoreFrames);
LocalVariableManager lvs = new LocalVariableManager(access, newDesc, mv, analyzer, _mv, generateExtraLVDebug);
((UninstrumentedCompatMV) mv).setLocalVariableSorter(lvs);
final PrimitiveArrayAnalyzer primArrayAnalyzer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, null);
lvs.setPrimitiveArrayAnalyzer(primArrayAnalyzer);
lvs.disable();
mv = lvs;
final MethodVisitor cmv = mv;
MethodNode wrapper = new MethodNode(Opcodes.ASM5, (isInterface ? access : access & ~Opcodes.ACC_ABSTRACT), name, desc, signature, exceptions) {
public void visitEnd() {
super.visitEnd();
this.accept(cmv);
}
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
// determine if this is going to be uninst, and then if we need to pre-alloc for its return :/
if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethod(owner, name, desc)) {
// uninst
} else {
Type returnType = Type.getReturnType(desc);
Type newReturnType = TaintUtils.getContainerReturnType(returnType);
if (newReturnType != returnType && !(returnType.getSort() == Type.ARRAY))
primArrayAnalyzer.wrapperTypesToPreAlloc.add(newReturnType);
}
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
};
if (!name.equals("<clinit>"))
methodsToMakeUninstWrappersAround.add(wrapper);
return wrapper;
}
if (Configuration.WITH_ENUM_BY_VAL && className.equals("java/lang/Enum") && name.equals("clone"))
return null;
if (TaintUtils.DEBUG_CALLS || TaintUtils.DEBUG_FIELDS || TaintUtils.DEBUG_FRAMES || TaintUtils.DEBUG_LOCAL)
System.out.println("Instrumenting " + name + "\n\n\n\n\n\n");
if (Instrumenter.IS_KAFFE_INST && className.equals("java/lang/VMSystem"))
access = access | Opcodes.ACC_PUBLIC;
else if (Instrumenter.IS_HARMONY_INST && className.endsWith("java/lang/VMMemoryManager")) {
access = access & ~Opcodes.ACC_PRIVATE;
access = access | Opcodes.ACC_PUBLIC;
} else if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("getChars")) {
access = access | Opcodes.ACC_PUBLIC;
}
String originalName = name;
if (FIELDS_ONLY) {
// || isAnnotation
return super.visitMethod(access, name, desc, signature, exceptions);
}
if (originalName.contains("$$INVIVO")) {
name = name + "_orig";
}
// We will need to add shadow args for each parameter that is a primitive. Because that worked so well last time.
Type[] argTypes = Type.getArgumentTypes(desc);
LinkedList<Type> newArgTypes = new LinkedList<Type>();
boolean isRewrittenDesc = false;
for (Type t : argTypes) {
if (t.getSort() == Type.ARRAY) {
if (t.getElementType().getSort() != Type.OBJECT) {
if (t.getDimensions() > 1) {
newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
isRewrittenDesc = true;
continue;
} else {
newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
isRewrittenDesc = true;
}
}
} else if (t.getSort() != Type.OBJECT) {
isRewrittenDesc = true;
newArgTypes.add(Type.getType(Configuration.TAINT_TAG_DESC));
}
newArgTypes.add(t);
}
if (Configuration.IMPLICIT_TRACKING && !name.equals("<clinit>")) {
isRewrittenDesc = true;
newArgTypes.add(Type.getType(ControlTaintTagStack.class));
}
if (isRewrittenDesc && name.equals("<init>"))
newArgTypes.add(Type.getType(TaintSentinel.class));
// If we are rewriting the return type, also add a param to pass for pre-alloc
Type oldReturnType = Type.getReturnType(desc);
Type newReturnType = TaintUtils.getContainerReturnType(Type.getReturnType(desc));
if ((oldReturnType.getSort() != Type.VOID && oldReturnType.getSort() != Type.OBJECT && oldReturnType.getSort() != Type.ARRAY)) {
newArgTypes.add(newReturnType);
}
Type[] newArgs = new Type[newArgTypes.size()];
newArgs = newArgTypes.toArray(newArgs);
boolean requiresNoChange = !isRewrittenDesc && newReturnType.equals(Type.getReturnType(desc));
MethodNode wrapper = new MethodNode(access, name, desc, signature, exceptions);
if (!requiresNoChange && !name.equals("<clinit>") && !(name.equals("<init>") && !isRewrittenDesc))
methodsToAddWrappersFor.add(wrapper);
String newDesc = Type.getMethodDescriptor(newReturnType, newArgs);
// System.out.println("olddesc " + desc + " newdesc " + newDesc);
if ((access & Opcodes.ACC_NATIVE) == 0 && !methodIsTooBigAlready(name, desc)) {
// not a native method
if (!name.contains("<") && !requiresNoChange)
name = name + TaintUtils.METHOD_SUFFIX;
// if(className.equals("sun/misc/URLClassPath$JarLoader"))
// System.out.println("\t\t:"+name+newDesc);
MethodVisitor mv = super.visitMethod(access, name, newDesc, signature, exceptions);
mv = new TaintTagFieldCastMV(mv);
MethodVisitor rootmV = mv;
mv = new SourceSinkTaintingMV(mv, access, className, name, newDesc, desc);
// mv = new CheckMethodAdapter(mv);
// mv = new SpecialOpcodeRemovingMV(mv,ignoreFrames, className);
// mv = reflectionMasker;
// PropertyDebug debug = new PropertyDebug(Opcodes.ASM4, mv, access, name, newDesc,className);
MethodVisitor optimizer;
optimizer = mv;
// if (DO_OPT)
// optimizer = new PopOptimizingMV(mv, access, className, name, newDesc, signature, exceptions);
mv = new SpecialOpcodeRemovingMV(optimizer, ignoreFrames, className, fixLdcClass);
// optimizer = new PopOptimizingMV(mv, access,className, name, newDesc, signature, exceptions);
NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
// TODO - how do we handle directbytebuffers?
mv = new StringTaintVerifyingMV(analyzer, (implementsSerializable || className.startsWith("java/nio/") || className.startsWith("java/io/BUfferedInputStream") || className.startsWith("sun/nio")), analyzer);
ReflectionHidingMV reflectionMasker = new ReflectionHidingMV(mv, className, name, analyzer);
PrimitiveBoxingFixer boxFixer = new PrimitiveBoxingFixer(access, className, name, desc, signature, exceptions, reflectionMasker, analyzer);
LocalVariableManager lvs;
TaintPassingMV tmv;
MethodVisitor nextMV;
{
// ImplicitTaintRemoverMV implicitCleanup = new ImplicitTaintRemoverMV(access, className, name, desc, signature, exceptions, boxFixer, analyzer);
tmv = new TaintPassingMV(boxFixer, access, className, name, newDesc, signature, exceptions, desc, analyzer, rootmV);
tmv.setFields(fields);
TaintAdapter custom = null;
lvs = new LocalVariableManager(access, newDesc, tmv, analyzer, mv, generateExtraLVDebug);
nextMV = lvs;
}
MethodArgReindexer mar = new MethodArgReindexer(nextMV, access, name, newDesc, desc, wrapper);
TaintLoadCoercer tlc = new TaintLoadCoercer(className, access, name, desc, signature, exceptions, mar, ignoreFrames);
PrimitiveArrayAnalyzer primitiveArrayFixer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, tlc);
NeverNullArgAnalyzerAdapter preAnalyzer = new NeverNullArgAnalyzerAdapter(className, access, name, desc, primitiveArrayFixer);
MethodVisitor mvNext = preAnalyzer;
mvNext = preAnalyzer;
primitiveArrayFixer.setAnalyzer(preAnalyzer);
boxFixer.setLocalVariableSorter(lvs);
tmv.setArrayAnalyzer(primitiveArrayFixer);
tmv.setLVOffset(mar.getNewArgOffset());
tmv.setLocalVariableSorter(lvs);
// i'm lazy. this guy will tell the LVS what return types to prealloc
lvs.setPrimitiveArrayAnalyzer(primitiveArrayFixer);
reflectionMasker.setLvs(lvs);
// if(IS_RUNTIME_INST)
// {
// return mvNext;
// }
final MethodVisitor prev = mvNext;
MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
@Override
protected LabelNode getLabelNode(Label l) {
if (!Configuration.READ_AND_SAVE_BCI)
return super.getLabelNode(l);
if (!(l.info instanceof LabelNode)) {
l.info = new LabelNode(l);
}
return (LabelNode) l.info;
}
@Override
public void visitEnd() {
super.visitEnd();
this.accept(prev);
}
};
if (!isInterface && !originalName.contains("$$INVIVO"))
this.myMethods.add(rawMethod);
forMore.put(wrapper, rawMethod);
if (Configuration.extensionMethodVisitor != null) {
try {
TaintAdapter custom = Configuration.extensionMethodVisitor.getConstructor(Integer.TYPE, String.class, String.class, String.class, String.class, String[].class, MethodVisitor.class, NeverNullArgAnalyzerAdapter.class, String.class, String.class).newInstance(access, className, name, desc, signature, exceptions, rawMethod, null, classSource, classDebug);
custom.setFields(fields);
custom.setSuperName(superName);
return custom;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
return rawMethod;
} else {
// this is a native method. we want here to make a $taint method that will call the original one.
final MethodVisitor prev = super.visitMethod(access, name, desc, signature, exceptions);
MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
@Override
public void visitEnd() {
super.visitEnd();
this.accept(prev);
}
};
forMore.put(wrapper, rawMethod);
return rawMethod;
}
}
Aggregations