下面列出了怎么用org.objectweb.asm.tree.TryCatchBlockNode的API类实例代码及写法,或者点击链接到github查看源代码。
private void assignCatchHandlers() {
@SuppressWarnings("unchecked")
ArrayList<TryCatchBlockNode> tcbs = (ArrayList<TryCatchBlockNode>) tryCatchBlocks;
/// aargh. I'd love to create an array of Handler objects, but generics
// doesn't care for it.
if (tcbs.size() == 0) return;
ArrayList<Handler> handlers= new ArrayList<Handler>(tcbs.size());
for (int i = 0; i < tcbs.size(); i++) {
TryCatchBlockNode tcb = tcbs.get(i);
handlers.add(new Handler(
getLabelPosition(tcb.start),
getLabelPosition(tcb.end) - 1, // end is inclusive
tcb.type,
getOrCreateBasicBlock(tcb.handler)));
}
for (BasicBlock bb : basicBlocks) {
bb.chooseCatchHandlers(handlers);
}
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<>();
List<LocalVariableNode> newLocalVariables = new ArrayList<>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
private void verifyRanges() {
for (TryCatchBlockNode tc : m.node.tryCatchBlocks) {
int start = -1, end = -1, handler = -1;
for (int i = 0; i < m.node.instructions.size(); i++) {
AbstractInsnNode ain = m.node.instructions.get(i);
if (!(ain instanceof LabelNode))
continue;
Label l = ((LabelNode) ain).getLabel();
if (l == tc.start.getLabel())
start = i;
if (l == tc.end.getLabel()) {
if (start == -1)
throw new IllegalStateException("Try block end before start " + m);
end = i;
}
if (l == tc.handler.getLabel()) {
handler = i;
}
}
if (start == -1 || end == -1 || handler == -1)
throw new IllegalStateException("Try/catch endpoints missing: " + start + " " + end + " " + handler + m);
}
}
private void check(ClassNode cn, MethodNode mn, TryCatchBlockNode tcb, LabelNode handler) {
AbstractInsnNode ain = handler;
while (ain.getOpcode() == -1) { // skip labels and frames
ain = ain.getNext();
}
if (ain.getOpcode() == ATHROW) {
removeTCB(mn, tcb);
} else if (ain instanceof MethodInsnNode && ain.getNext().getOpcode() == ATHROW) {
MethodInsnNode min = (MethodInsnNode) ain;
if (min.owner.equals(cn.name)) {
MethodNode getter = ClassUtils.getMethod(cn, min.name, min.desc);
AbstractInsnNode getterFirst = getter.instructions.getFirst();
while (getterFirst.getOpcode() == -1) {
getterFirst = ain.getNext();
}
if (getterFirst instanceof VarInsnNode && getterFirst.getNext().getOpcode() == ARETURN) {
if (((VarInsnNode) getterFirst).var == 0) {
removeTCB(mn, tcb);
}
}
}
}
}
public static InsnList cutClinit(MethodNode mn) {
InsnList insns = MethodUtils.copy(mn.instructions, null, null);
ArrayList<LabelNode> handlers = new ArrayList<>();
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
handlers.add((LabelNode) insns.get(mn.instructions.indexOf(tcbn.handler)));
}
for(LabelNode ln : handlers) {
findSubroutinesAndDelete(insns, ln);
}
AbstractInsnNode endLabel = findEndLabel(insns);
while (endLabel.getOpcode() == -1) {
endLabel = endLabel.getNext();
}
AbstractInsnNode end = endLabel.getPrevious();
if (endLabel.getOpcode() != RETURN) {
findSubroutinesAndDelete(insns, endLabel);
insns.insert(end, new InsnNode(RETURN));
}
return insns;
}
public static void athrow(final Frame frame) {
ObjectRef objectRef = frame.operandStack.popRef();
if (objectRef == null) {
frame.throwNullPointerException();
return;
}
//Log.opcode(frame.getCurrentOpCode(), objectRef);
while (frame.vm.isNotEmptyFrame()) {
final Frame lastFrame = frame.vm.lastFrame();
TryCatchBlockNode tryCatchBlockNode = getTryCatchBlockNode(lastFrame, objectRef);
if (tryCatchBlockNode != null) {
lastFrame.operandStack.clear();
lastFrame.operandStack.pushRef(objectRef);
lastFrame.jump(tryCatchBlockNode.handler);
return;
} else {
frame.vm.popFrame();
}
}
frame.vm.getResult().exception(objectRef);
}
private static TryCatchBlockNode getTryCatchBlockNode(Frame frame, ObjectRef objectRef) {
for (TryCatchBlockNode tryCatchBlockNode : frame.methodCode.tryCatchBlocks) {
String type = tryCatchBlockNode.type;
int line = frame.getLine();
int start = frame.getLine(tryCatchBlockNode.start);
int end = frame.getLine(tryCatchBlockNode.end);
int handler = frame.getLine(tryCatchBlockNode.handler);
if (type != null && handler < end) {
end = handler;
}
boolean result = start <= line && line < end;
if (result && (type == null || extends_(objectRef.getVariableType().getType(), type, frame))) {
return tryCatchBlockNode;
}
}
return null;
}
public static void athrow(final Frame frame) {
ObjectRef objectRef = frame.operandStack.popRef();
if (objectRef == null) {
frame.throwNullPointerException();
return;
}
//Log.opcode(frame.getCurrentOpCode(), objectRef);
while (frame.vm.isNotEmptyFrame()) {
final Frame lastFrame = frame.vm.lastFrame();
TryCatchBlockNode tryCatchBlockNode = getTryCatchBlockNode(lastFrame, objectRef);
if (tryCatchBlockNode != null) {
lastFrame.operandStack.clear();
lastFrame.operandStack.pushRef(objectRef);
lastFrame.jump(tryCatchBlockNode.handler);
return;
} else {
frame.vm.popFrame();
}
}
frame.vm.getResult().exception(objectRef);
}
private static TryCatchBlockNode getTryCatchBlockNode(Frame frame, ObjectRef objectRef) {
for (TryCatchBlockNode tryCatchBlockNode : frame.methodCode.tryCatchBlocks) {
String type = tryCatchBlockNode.type;
int line = frame.getLine();
int start = frame.getLine(tryCatchBlockNode.start);
int end = frame.getLine(tryCatchBlockNode.end);
int handler = frame.getLine(tryCatchBlockNode.handler);
if (type != null && handler < end) {
end = handler;
}
boolean result = start <= line && line < end;
if (result && (type == null || extends_(objectRef.getVariableType().getType(), type, frame))) {
return tryCatchBlockNode;
}
}
return null;
}
/** Adds an exception try block node to this graph */
protected void exception(@NonNull AbstractInsnNode from, @NonNull TryCatchBlockNode tcb) {
// Add tcb's to all instructions in the range
LabelNode start = tcb.start;
LabelNode end = tcb.end; // exclusive
// Add exception edges for all method calls in the range
AbstractInsnNode curr = start;
Node handlerNode = getNode(tcb.handler);
while (curr != end && curr != null) {
if (curr.getType() == AbstractInsnNode.METHOD_INSN) {
// Method call; add exception edge to handler
if (tcb.type == null) {
// finally block: not an exception path
getNode(curr).addSuccessor(handlerNode);
}
getNode(curr).addExceptionPath(handlerNode);
}
curr = curr.getNext();
}
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
private boolean isTCBO(MethodNode mn) {
if (mn.tryCatchBlocks.size() > mn.instructions.size() / 8 || mn.tryCatchBlocks.size() > 15) {
return true;
}
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
int start = OpUtils.getLabelIndex(tcbn.start);
int end = OpUtils.getLabelIndex(tcbn.start);
for (TryCatchBlockNode tcbn2 : mn.tryCatchBlocks) {
int start2 = OpUtils.getLabelIndex(tcbn2.start);
if (start2 >= start && start2 < end) {
return true;
}
}
}
return false;
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
/**
* Creates the new instructions, inlining each instantiation of each subroutine until the code is
* fully elaborated.
*/
private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
// Create an instantiation of the main "subroutine", which is just the main routine.
worklist.add(new Instantiation(null, mainSubroutineInsns));
// Emit instantiations of each subroutine we encounter, including the main subroutine.
InsnList newInstructions = new InsnList();
List<TryCatchBlockNode> newTryCatchBlocks = new ArrayList<TryCatchBlockNode>();
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) {
Instantiation instantiation = worklist.removeFirst();
emitInstantiation(
instantiation, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
}
instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks;
localVariables = newLocalVariables;
}
private void addCatchBlock(LabelNode startNode, LabelNode endNode) {
InsnList il = new InsnList();
LabelNode handlerNode = new LabelNode();
il.add(handlerNode);
int exceptionVariablePosition = getFistAvailablePosition();
il.add(new VarInsnNode(Opcodes.ASTORE, exceptionVariablePosition));
this.methodOffset++; // Actualizamos el offset
addGetCallback(il);
il.add(new VarInsnNode(Opcodes.ALOAD, this.methodVarIndex));
il.add(new VarInsnNode(Opcodes.ALOAD, exceptionVariablePosition));
il.add(new VarInsnNode(Opcodes.ALOAD, this.executionIdIndex));
il.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
"org/brutusin/instrumentation/Callback", "onThrowableUncatched",
"(Ljava/lang/Object;Ljava/lang/Throwable;Ljava/lang/String;)V", false));
il.add(new VarInsnNode(Opcodes.ALOAD, exceptionVariablePosition));
il.add(new InsnNode(Opcodes.ATHROW));
TryCatchBlockNode blockNode = new TryCatchBlockNode(startNode, endNode, handlerNode, null);
this.mn.tryCatchBlocks.add(blockNode);
this.mn.instructions.add(il);
}
public void sort() {
if (this.methodNode.tryCatchBlocks == null) {
return;
}
Collections.sort(this.methodNode.tryCatchBlocks, new Comparator<TryCatchBlockNode>() {
@Override
public int compare(TryCatchBlockNode o1, TryCatchBlockNode o2) {
return blockLength(o1) - blockLength(o2);
}
private int blockLength(TryCatchBlockNode block) {
final int startidx = methodNode.instructions.indexOf(block.start);
final int endidx = methodNode.instructions.indexOf(block.end);
return endidx - startidx;
}
});
// Updates the 'target' of each try catch block annotation.
for (int i = 0; i < this.methodNode.tryCatchBlocks.size(); i++) {
this.methodNode.tryCatchBlocks.get(i).updateIndex(i);
}
}
@Override
public void accept(MethodContext context, T node) {
props = new HashMap<>();
StringBuilder tryCatch = new StringBuilder("\n");
if (context.tryCatches.size() > 0) {
tryCatch.append(String.format(" %s\n", context.getSnippets().getSnippet("TRYCATCH_START")));
for (int i = context.tryCatches.size() - 1; i >= 0; i--) {
TryCatchBlockNode tryCatchBlock = context.tryCatches.get(i);
if (tryCatchBlock.type == null) {
tryCatch.append(" ").append(context.getSnippets().getSnippet("TRYCATCH_ANY_L", Util.createMap(
"rettype", MethodProcessor.CPP_TYPES[context.ret.getSort()],
"handler_block", tryCatchBlock.handler.getLabel().toString()
))).append("\n");
break;
} else {
tryCatch.append(" ").append(context.getSnippets().getSnippet("TRYCATCH_CHECK", Util.createMap(
"rettype", MethodProcessor.CPP_TYPES[context.ret.getSort()],
"exception_class_ptr", context.getCachedClasses().getPointer(tryCatchBlock.type),
"handler_block", tryCatchBlock.handler.getLabel().toString()
))).append("\n");
}
}
tryCatch.append(" ").append(context.getSnippets().getSnippet("TRYCATCH_END",
Util.createMap("rettype", MethodProcessor.CPP_TYPES[context.ret.getSort()])));
} else {
tryCatch.append(" ").append(context.getSnippets().getSnippet("TRYCATCH_EMPTY",
Util.createMap("rettype", MethodProcessor.CPP_TYPES[context.ret.getSort()])));
}
context.output.append(" ");
instructionName = MethodProcessor.INSTRUCTIONS.getOrDefault(node.getOpcode(), "NOTFOUND");
props.put("line", String.valueOf(context.line));
props.put("trycatchhandler", tryCatch.toString());
props.put("rettype", MethodProcessor.CPP_TYPES[context.ret.getSort()]);
trimmedTryCatchBlock = tryCatch.toString().trim().replace("\n", " ");
process(context, node);
context.output.append(context.obfuscator.getSnippets().getSnippet(instructionName, props));
context.output.append("\n");
}
void visitTryCatchBlocks(MethodVisitor mv) {
MethodFlow mf = methodFlow;
ArrayList<BasicBlock> bbs = mf.getBasicBlocks();
ArrayList<Handler> allHandlers = new ArrayList<Handler>(bbs.size() * 2);
for (BasicBlock bb : bbs) {
allHandlers.addAll(bb.handlers);
}
//allHandlers = Handler.consolidate(allHandlers);
//trying to be too clever above
for (Handler h : allHandlers) {
new TryCatchBlockNode(mf.getLabelAt(h.from), mf.getOrCreateLabelAtPos(h.to+1), h.catchBB.startLabel, h.type).accept(mv);
}
}
@Override
public void visitEnd() {
// Sort the TryCatchBlockNode elements by the length of their "try" block.
Collections.sort(
tryCatchBlocks,
new Comparator<TryCatchBlockNode>() {
@Override
public int compare(
final TryCatchBlockNode tryCatchBlockNode1,
final TryCatchBlockNode tryCatchBlockNode2) {
return blockLength(tryCatchBlockNode1) - blockLength(tryCatchBlockNode2);
}
private int blockLength(final TryCatchBlockNode tryCatchBlockNode) {
int startIndex = instructions.indexOf(tryCatchBlockNode.start);
int endIndex = instructions.indexOf(tryCatchBlockNode.end);
return endIndex - startIndex;
}
});
// Update the 'target' of each try catch block annotation.
for (int i = 0; i < tryCatchBlocks.size(); ++i) {
tryCatchBlocks.get(i).updateIndex(i);
}
if (mv != null) {
accept(mv);
}
}
/**
* Finds the instructions that belong to the subroutine starting at the given instruction index.
* For this the control flow graph is visited with a depth first search (this includes the normal
* control flow and the exception handlers).
*
* @param startInsnIndex the index of the first instruction of the subroutine.
* @param subroutineInsns where the indices of the instructions of the subroutine must be stored.
* @param visitedInsns the indices of the instructions that have been visited so far (including in
* previous calls to this method). This bitset is updated by this method each time a new
* instruction is visited. It is used to make sure each instruction is visited at most once.
*/
private void findSubroutineInsns(
final int startInsnIndex, final BitSet subroutineInsns, final BitSet visitedInsns) {
// First find the instructions reachable via normal execution.
findReachableInsns(startInsnIndex, subroutineInsns, visitedInsns);
// Then find the instructions reachable via the applicable exception handlers.
while (true) {
boolean applicableHandlerFound = false;
for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlocks) {
// If the handler has already been processed, skip it.
int handlerIndex = instructions.indexOf(tryCatchBlockNode.handler);
if (subroutineInsns.get(handlerIndex)) {
continue;
}
// If an instruction in the exception handler range belongs to the subroutine, the handler
// can be reached from the routine, and its instructions must be added to the subroutine.
int startIndex = instructions.indexOf(tryCatchBlockNode.start);
int endIndex = instructions.indexOf(tryCatchBlockNode.end);
int firstSubroutineInsnAfterTryCatchStart = subroutineInsns.nextSetBit(startIndex);
if (firstSubroutineInsnAfterTryCatchStart >= startIndex
&& firstSubroutineInsnAfterTryCatchStart < endIndex) {
findReachableInsns(handlerIndex, subroutineInsns, visitedInsns);
applicableHandlerFound = true;
}
}
// If an applicable exception handler has been found, other handlers may become applicable, so
// we must examine them again.
if (!applicableHandlerFound) {
return;
}
}
}
static void printAnalyzerResult(
final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
Textifier textifier = new Textifier();
TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
printWriter.println(method.name + method.desc);
for (int i = 0; i < method.instructions.size(); ++i) {
method.instructions.get(i).accept(traceMethodVisitor);
StringBuilder stringBuilder = new StringBuilder();
Frame<BasicValue> frame = analyzer.getFrames()[i];
if (frame == null) {
stringBuilder.append('?');
} else {
for (int j = 0; j < frame.getLocals(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
}
stringBuilder.append(" : ");
for (int j = 0; j < frame.getStackSize(); ++j) {
stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
}
}
while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
stringBuilder.append(' ');
}
printWriter.print(Integer.toString(i + 100000).substring(1));
printWriter.print(
" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
}
for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
tryCatchBlock.accept(traceMethodVisitor);
printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
}
printWriter.println();
}
@Override
public void visitEnd() {
// Sort the TryCatchBlockNode elements by the length of their "try" block.
Collections.sort(
tryCatchBlocks,
new Comparator<TryCatchBlockNode>() {
public int compare(
final TryCatchBlockNode tryCatchBlockNode1,
final TryCatchBlockNode tryCatchBlockNode2) {
return blockLength(tryCatchBlockNode1) - blockLength(tryCatchBlockNode2);
}
private int blockLength(final TryCatchBlockNode tryCatchBlockNode) {
int startIndex = instructions.indexOf(tryCatchBlockNode.start);
int endIndex = instructions.indexOf(tryCatchBlockNode.end);
return endIndex - startIndex;
}
});
// Update the 'target' of each try catch block annotation.
for (int i = 0; i < tryCatchBlocks.size(); ++i) {
tryCatchBlocks.get(i).updateIndex(i);
}
if (mv != null) {
accept(mv);
}
}
/**
* Finds the instructions that belong to the subroutine starting at the given instruction index.
* For this the control flow graph is visited with a depth first search (this includes the normal
* control flow and the exception handlers).
*
* @param startInsnIndex the index of the first instruction of the subroutine.
* @param subroutineInsns where the indices of the instructions of the subroutine must be stored.
* @param visitedInsns the indices of the instructions that have been visited so far (including in
* previous calls to this method). This bitset is updated by this method each time a new
* instruction is visited. It is used to make sure each instruction is visited at most once.
*/
private void findSubroutineInsns(
final int startInsnIndex, final BitSet subroutineInsns, final BitSet visitedInsns) {
// First find the instructions reachable via normal execution.
findReachableInsns(startInsnIndex, subroutineInsns, visitedInsns);
// Then find the instructions reachable via the applicable exception handlers.
while (true) {
boolean applicableHandlerFound = false;
for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlocks) {
// If the handler has already been processed, skip it.
int handlerIndex = instructions.indexOf(tryCatchBlockNode.handler);
if (subroutineInsns.get(handlerIndex)) {
continue;
}
// If an instruction in the exception handler range belongs to the subroutine, the handler
// can be reached from the routine, and its instructions must be added to the subroutine.
int startIndex = instructions.indexOf(tryCatchBlockNode.start);
int endIndex = instructions.indexOf(tryCatchBlockNode.end);
int firstSubroutineInsnAfterTryCatchStart = subroutineInsns.nextSetBit(startIndex);
if (firstSubroutineInsnAfterTryCatchStart >= startIndex
&& firstSubroutineInsnAfterTryCatchStart < endIndex) {
findReachableInsns(handlerIndex, subroutineInsns, visitedInsns);
applicableHandlerFound = true;
}
}
// If an applicable exception handler has been found, other handlers may become applicable, so
// we must examine them again.
if (!applicableHandlerFound) {
return;
}
}
}
public TCBEntry(ClassNode cn, MethodNode mn, TryCatchBlockNode tcbn) {
this.cn = cn;
this.mn = mn;
this.tcbn = tcbn;
this.text = TextUtils.toHtml(
(tcbn.type != null ? InstrUtils.getDisplayType(tcbn.type, true) : TextUtils.addTag("Null type", "font color=" + InstrUtils.primColor.getString())) + ": label " + OpUtils.getLabelIndex(tcbn.start) + " -> label "
+ OpUtils.getLabelIndex(tcbn.end) + " handler: label " + (tcbn.handler == null ? "null" : OpUtils.getLabelIndex(tcbn.handler)));
}
private boolean doesTrapCatch(TryCatchBlockNode node, String... exceptions) {
if (node.type == null) {
return true;
}
if (node.type.equals("java/lang/Throwable")) {
return true;
}
for (String exception : exceptions) {
if (getDeobfuscator().isSubclass(node.type, exception)) {
return true;
}
}
return false;
}
@Override
public boolean transform() throws Throwable {
System.out.println("[DashO] [FakeExceptionTransformer] Starting");
AtomicInteger counter = new AtomicInteger();
Set<String> fakeExceptionClass = new HashSet<>();
classNodes().forEach(classNode -> {
classNode.methods.stream().filter(Utils::notAbstractOrNative).forEach(methodNode -> {
List<TryCatchBlockNode> remove = new ArrayList<>();
for(TryCatchBlockNode tcbn : methodNode.tryCatchBlocks)
{
String handler = tcbn.type;
if(handler != null && classes.containsKey(handler))
{
ClassNode handlerClass = classes.get(handler);
if(handlerClass.methods.size() == 0 && handlerClass.superName.equals("java/lang/RuntimeException"))
{
remove.add(tcbn);
fakeExceptionClass.add(handler);
counter.incrementAndGet();
}
}
}
methodNode.tryCatchBlocks.removeIf(remove::contains);
});
});
fakeExceptionClass.forEach(str -> {
classes.remove(str);
classpath.remove(str);
});
System.out.println("[DashO] [FakeExceptionTransformer] Removed " + counter.get() + " fake try-catch blocks");
System.out.println("[DashO] [FakeExceptionTransformer] Removed " + fakeExceptionClass.size() + " fake exception classes");
System.out.println("[DashO] [FakeExceptionTransformer] Done");
return counter.get() > 0;
}
AsmMethodSource(int maxLocals, InsnList insns,
List<LocalVariableNode> localVars,
List<TryCatchBlockNode> tryCatchBlocks) {
this.maxLocals = maxLocals;
this.instructions = insns;
this.localVars = localVars;
this.tryCatchBlocks = tryCatchBlocks;
}
public static List<TryCatchBlockNode> cloneTryCatchBlocks(Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
ArrayList<TryCatchBlockNode> clone = new ArrayList<>(tcblocks.size());
for (TryCatchBlockNode node : tcblocks) {
clone.add(new TryCatchBlockNode(labelMap.get(node.start), labelMap.get(node.end), labelMap.get(node.handler), node.type));
}
return clone;
}
public static List<TryCatchBlockNode> cloneTryCatchBlocks(Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
ArrayList<TryCatchBlockNode> clone = new ArrayList<TryCatchBlockNode>();
for (TryCatchBlockNode node : tcblocks) {
clone.add(new TryCatchBlockNode(labelMap.get(node.start), labelMap.get(node.end), labelMap.get(node.handler), node.type));
}
return clone;
}
public static List<TryCatchBlockNode> cloneTryCatchBlocks(Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
ArrayList<TryCatchBlockNode> clone = new ArrayList<TryCatchBlockNode>();
for (TryCatchBlockNode node : tcblocks) {
clone.add(new TryCatchBlockNode(labelMap.get(node.start), labelMap.get(node.end), labelMap.get(node.handler), node.type));
}
return clone;
}