下面列出了怎么用org.objectweb.asm.tree.analysis.SourceInterpreter的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public boolean transform() throws Throwable {
DelegatingProvider provider = new DelegatingProvider();
provider.register(new JVMMethodProvider());
provider.register(new JVMComparisonProvider());
provider.register(new MappedMethodProvider(classes));
provider.register(new MappedFieldProvider());
AtomicInteger count = new AtomicInteger();
Set<MethodNode> decryptor = new HashSet<>();
System.out.println("[Smoke] [StringEncryptionTransformer] Starting");
for(ClassNode classNode : classes.values())
for(MethodNode method : classNode.methods)
{
InstructionModifier modifier = new InstructionModifier();
Frame<SourceValue>[] frames;
try
{
frames = new Analyzer<>(new SourceInterpreter()).analyze(classNode.name, method);
}catch(AnalyzerException e)
{
oops("unexpected analyzer exception", e);
continue;
}
for(AbstractInsnNode ain : TransformerHelper.instructionIterator(method))
if(ain instanceof MethodInsnNode)
{
MethodInsnNode m = (MethodInsnNode)ain;
String strCl = m.owner;
if(m.desc.equals("(Ljava/lang/String;I)Ljava/lang/String;"))
{
Frame<SourceValue> f = frames[method.instructions.indexOf(m)];
if(f.getStack(f.getStackSize() - 2).insns.size() != 1
|| f.getStack(f.getStackSize() - 1).insns.size() != 1)
continue;
AbstractInsnNode a1 = f.getStack(f.getStackSize() - 2).insns.iterator().next();
AbstractInsnNode a2 = f.getStack(f.getStackSize() - 1).insns.iterator().next();
if(a1.getOpcode() != Opcodes.LDC || !Utils.isInteger(a2))
continue;
Object obfString = ((LdcInsnNode)a1).cst;
int number = Utils.getIntValue(a2);
Context context = new Context(provider);
if(classes.containsKey(strCl))
{
ClassNode innerClassNode = classes.get(strCl);
MethodNode decrypterNode = innerClassNode.methods.stream().filter(mn -> mn.name.equals(m.name) && mn.desc.equals(m.desc)).findFirst().orElse(null);
if(isSmokeMethod(decrypterNode))
{
String value = MethodExecutor.execute(classNode, decrypterNode, Arrays.asList(JavaValue.valueOf(obfString), new JavaInteger(number)), null, context);
modifier.remove(a2);
modifier.remove(a1);
modifier.replace(m, new LdcInsnNode(value));
decryptor.add(decrypterNode);
count.getAndIncrement();
}
}
}
}
modifier.apply(method);
}
System.out.println("[Smoke] [StringEncryptionTransformer] Decrypted " + count + " encrypted strings");
System.out.println("[Smoke] [StringEncryptionTransformer] Removed " + cleanup(decryptor) + " decryption methods");
System.out.println("[Smoke] [StringEncryptionTransformer] Done");
return true;
}