AS3 register deobfuscator improved

This commit is contained in:
Jindra Petřík
2015-07-06 09:12:29 +02:00
parent 1caf4e4856
commit 0e1a76f279
6 changed files with 149 additions and 183 deletions

View File

@@ -773,7 +773,7 @@ public class AVM2Code implements Cloneable {
}
}
public AVM2Code(ABCInputStream ais) throws IOException {
public AVM2Code(ABCInputStream ais, MethodBody body) throws IOException {
Map<Long, AVM2Instruction> codeMap = new TreeMap<>();
DumpInfo diParent = ais.dumpInfo;
List<Long> addresses = new ArrayList<>();
@@ -789,6 +789,13 @@ public class AVM2Code implements Cloneable {
long startPos = ais.getPosition();
addresses.add(startPos);
if (body != null) {
for (ABCException e : body.exceptions) {
addresses.add((long) e.start);
addresses.add((long) e.end);
addresses.add((long) e.target);
}
}
loopaddr:
while (!addresses.isEmpty() || !switchAddresses.isEmpty() || !unAdresses.isEmpty()) {
@@ -919,6 +926,7 @@ public class AVM2Code implements Cloneable {
for (int c = 2; c < actualOperands.length; c++) {
addresses.add(beforeSwitchPos + actualOperands[c]);
}
unAdresses.add(ais.getPosition());
continue loopaddr;
}
}

View File

@@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
@@ -43,9 +44,8 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.decompiler.graph.TranslateStack;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -70,61 +70,65 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
@Override
public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody abody) throws InterruptedException {
//System.err.println("regdeo:" + path);
removeUnreachableActions(abody.getCode(), cpool, trait, minfo, abody);
Map<Integer, GraphTargetItem> outFirstAssigned = new HashMap<>();
Map<Integer, AVM2Instruction> outFirstAssignments = new HashMap<>();
Map<Integer, Integer> outAssignCount1 = new HashMap<>();
Map<Integer, Integer> outAssignCount2 = new HashMap<>();
Map<Integer, GraphTargetItem> singleRegisters = new HashMap<>();
List<AVM2Instruction> ignored = new ArrayList<>();
Map<Integer, GraphTargetItem> registers = new HashMap<>();
boolean extended = true;
/*for (AVM2Instruction ins : abody.getCode().code) {
System.err.println("" + ins.offset + ": " + ins);
}*/
Set<Integer> ignoredRegs = new HashSet<>();
MethodBody body = abody;
if (extended) {
body = abody.clone();
getFirstRegistersUsage(outAssignCount1, outFirstAssigned, outFirstAssignments, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, ignored, registers);
ignored.addAll(outFirstAssignments.values());
registers.putAll(outFirstAssigned);
replaceSingleUseRegisters(registers, ignored, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body);
super.deobfuscate(path, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body);
removeUnreachableActions(body.getCode(), cpool, trait, minfo, body);
//second pass - ignore all first assignments
registers.clear();
ignored.clear();
outFirstAssignments.clear();
getFirstRegistersUsage(outAssignCount2, new HashMap<>(), outFirstAssignments, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, ignored, registers);
for (int regId : outAssignCount1.keySet()) {
int ac = outAssignCount2.containsKey(regId) ? outAssignCount2.get(regId) : 0;
if (ac == 0) {
singleRegisters.put(regId, outFirstAssigned.get(regId));
}
}
body = abody;
} else {
getFirstRegistersUsage(outAssignCount1, outFirstAssigned, outFirstAssignments, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, ignored, registers);
for (int regId : outAssignCount1.keySet()) {
int ac = outAssignCount1.get(regId);
if (ac == 1) {
singleRegisters.put(regId, outFirstAssigned.get(regId));
}
}
body = abody.clone();
Reference<AVM2Instruction> assignment = new Reference<>(null);
ignoredRegs.clear();
for (int i = 0; i < body.getLocalReservedCount(); i++) {
ignoredRegs.add(i);
}
//body.max_regs
replaceSingleUseRegisters(singleRegisters, null, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body);
super.deobfuscate(path, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body);
int setReg = 0;
List<Integer> listedRegs = new ArrayList<>();
List<MethodBody> listedLastBodies = new ArrayList<>();
Set<Integer> ignoredRegGets = new HashSet<>();
while (setReg > -1) {
MethodBody bodybefore = body;
body = bodybefore.clone();
setReg = getFirstRegisterSetter(assignment, classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, ignoredRegs, ignoredRegGets);
//System.err.println("setreg " + setReg + " ass:" + assignment.getVal());
if (setReg < 0) {
break;
}
//if there is second assignment
if (listedRegs.contains(setReg)) {
//System.err.println("second assignment of loc" + setReg + ", ignoring");
int lindex = listedRegs.indexOf(setReg);
body = listedLastBodies.get(lindex); //switch to body before
ignoredRegs.add(setReg); //this is not obfuscated
for (int i = listedRegs.size() - 1; i >= lindex; i--) {
int r = listedRegs.get(i);
listedRegs.remove(i);
listedLastBodies.remove(i);
ignoredRegGets.remove(r);
}
continue;
}
if ((assignment.getVal().definition instanceof SetLocalTypeIns) || (assignment.getVal().definition instanceof GetLocalTypeIns /*First usage -> value undefined*/)) {
super.removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, Arrays.asList(assignment.getVal()));
}
if (assignment.getVal().definition instanceof GetLocalTypeIns) {
ignoredRegGets.add(setReg);
}
listedRegs.add(setReg);
listedLastBodies.add(bodybefore);
}
abody.exceptions = body.exceptions;
abody.setCode(body.getCode());
removeUnreachableActions(body.getCode(), cpool, trait, minfo, body);
//System.err.println("/deo");
}
private void replaceSingleUseRegisters(Map<Integer, GraphTargetItem> singleRegisters, List<AVM2Instruction> setInss, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) {
@@ -149,45 +153,19 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
}
}
private void getFirstRegistersUsage(Map<Integer, Integer> outAssignCount, Map<Integer, GraphTargetItem> outFirstAssigned, Map<Integer, AVM2Instruction> outFirstAssignments, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body, List<AVM2Instruction> ignoredAss, Map<Integer, GraphTargetItem> registers) {
private int getFirstRegisterSetter(Reference<AVM2Instruction> assignment, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body, Set<Integer> ignoredRegisters, Set<Integer> ignoredGets) {
AVM2Code code = body.getCode();
Map<Integer, GraphTargetItem> ret = new HashMap<>();
if (code.code.isEmpty()) {
return;
return -1;
}
ExecutionResult res = new ExecutionResult();
visitCode(new HashSet<>(), new TranslateStack("deo"), classIndex, isStatic, body, scriptIndex, abc, code, 0, code.code.size() - 1, res, registers, ignoredAss);
for (int reg : res.assignCount.keySet()) {
if (res.firstAssigned.get(reg) != null && res.firstAssigned.get(reg).isCompileTime()) {
outAssignCount.put(reg, res.assignCount.get(reg));
outFirstAssigned.put(reg, res.firstAssigned.get(reg));
outFirstAssignments.put(reg, res.firstAssignInstruction.get(reg));
}
}
return visitCode(assignment, new HashSet<>(), new TranslateStack("deo"), classIndex, isStatic, body, scriptIndex, abc, code, 0, code.code.size() - 1, res, ignoredRegisters, ignoredGets);
}
/*
private Map<Integer, GraphTargetItem> getSingleUseRegisters(int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) {
AVM2Code code = body.getCode();
Map<Integer, GraphTargetItem> ret = new HashMap<>();
if (code.code.isEmpty()) {
return ret;
}
ExecutionResult res = new ExecutionResult();
visitCode(new HashSet<>(), new TranslateStack("deo"), classIndex, isStatic, body, scriptIndex, abc, code, 0, code.code.size() - 1, res);
for (int reg : res.assignCount.keySet()) {
if (res.assignCount.get(reg) == 1) {
ret.put(reg, res.lastAssigned.get(reg));
}
}
return ret;
}*/
private void visitCode(Set<Integer> visited, TranslateStack stack, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, Map<Integer, GraphTargetItem> registers, List<AVM2Instruction> ignoredAss) {
private int visitCode(Reference<AVM2Instruction> assignment, Set<Integer> visited, TranslateStack stack, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, Set<Integer> ignored, Set<Integer> ignoredGets) {
List<GraphTargetItem> output = new ArrayList<>();
AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex);
localData.localRegs.put(0, new NullAVM2Item(null));//this
@@ -212,40 +190,33 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
AVM2Instruction action = code.code.get(idx);
InstructionDefinition def = action.definition;
//System.err.println("" + idx + ": " + action + " stack:" + stack.size());
if (action.definition instanceof GetLocalTypeIns) {
stack.push(registers.get(((GetLocalTypeIns) action.definition).getRegisterId(action)));
} else if (action.definition instanceof SetLocalTypeIns) {
SetLocalTypeIns slt = (SetLocalTypeIns) def;
GraphTargetItem regVal = stack.pop();//localData.localRegs.get(regId);
int regId = slt.getRegisterId(action);
if (!result.assignCount.containsKey(regId)) {
result.assignCount.put(regId, 0);
}
boolean isIgnored = false;
for (AVM2Instruction ins : ignoredAss) {
if (action == ins) {
isIgnored = true;
break;
}
}
if (isIgnored) {
} else {
result.assignCount.put(regId, result.assignCount.get(regId) + 1);
//GraphTargetItem regVal = localData.localRegs.get(regId);
if (regVal == null || !regVal.getNotCoerced().isCompileTime()) {
result.assignCount.put(regId, Integer.MAX_VALUE);
} else {
if (result.assignCount.get(regId) == 1) {
result.firstAssigned.put(regId, regVal.getNotCoerced());
result.firstAssignInstruction.put(regId, action);
action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
//if (!(def instanceof KillIns))
if (def instanceof SetLocalTypeIns) {
int regId = ((SetLocalTypeIns) def).getRegisterId(action);
if (!ignored.contains(regId)) {
assignment.setVal(action);
return regId;
}
} else if (def instanceof GetLocalTypeIns) {
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
if (!ignored.contains(regId) && !ignoredGets.contains(regId)) {
assignment.setVal(action);
return regId;
}
} else {
for (int p = 0; p < action.definition.operands.length; p++) {
int op = action.definition.operands[p];
if (op == AVM2Code.DAT_REGISTER_INDEX) {
int regId = action.operands[p];
if (!ignored.contains(regId)) {
assignment.setVal(action);
return regId;
}
result.lastAssigned.put(regId, regVal.getNotCoerced());
}
}
//assignCount
} else {
action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
}
idx++;
@@ -328,14 +299,6 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
//ignore
}
}
}
class ExecutionResult {
public Map<Integer, Integer> assignCount = new HashMap<>();
public Map<Integer, GraphTargetItem> lastAssigned = new HashMap<>();
public Map<Integer, GraphTargetItem> firstAssigned = new HashMap<>();
public Map<Integer, AVM2Instruction> firstAssignInstruction = new HashMap<>();
return -1;
}
}

View File

@@ -48,6 +48,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsI
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
@@ -60,6 +61,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushTrueIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOrConvertTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
@@ -77,6 +80,7 @@ import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerListener;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.NotCompileTimeItem;
import com.jpexs.decompiler.graph.ScopeStack;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -86,6 +90,7 @@ import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
@@ -156,60 +161,21 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
}
}
private boolean removeObfuscationIfs(int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException {
protected boolean removeObfuscationIfs(int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body, List<AVM2Instruction> inlineIns) throws InterruptedException {
AVM2Code code = body.getCode();
if (code.code.size() == 0) {
return false;
}
Map<Integer, GraphTargetItem> staticRegs = new HashMap<>();
for (AVM2Instruction ins : inlineIns) {
if (ins.definition instanceof GetLocalTypeIns) {
staticRegs.put(((GetLocalTypeIns) ins.definition).getRegisterId(ins), new UndefinedAVM2Item(ins));
}
}
for (int i = 0; i < code.code.size(); i++) {
ExecutionResult result = new ExecutionResult();
executeActions(classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result);
/*if (result.idx != -1) {
int newIstructionCount = 1; // jump
if (!result.stack.isEmpty()) {
newIstructionCount += result.stack.size();
}
if (newIstructionCount < result.instructionsProcessed) //if (result.isIf)
{
AVM2Instruction target = code.code.get(result.idx);
AVM2Instruction prevAction = code.code.get(i);
int idelta = 0;
if (result.stack.isEmpty() && prevAction.definition instanceof JumpIns) {
prevAction.operands[0] = ((int) (target.offset - prevAction.offset - prevAction.getBytes().length));
} else {
if (!result.stack.isEmpty()) {
for (GraphTargetItem graphTargetItem : result.stack) {
if (graphTargetItem instanceof PopItem) {
continue;
}
AVM2Instruction ins = makePush(graphTargetItem.getResult(), cpool);
if (ins != null) {
code.insertInstruction(i + (idelta++), ins, body);
//prevAction = ins;
} else {
throw new TranslateException("Cannot push: " + graphTargetItem);
}
}
}
AVM2Instruction jump = new AVM2Instruction(0, new JumpIns(), new int[]{0});
code.insertInstruction(i + (idelta++), jump, body);
jump.operands[0] = ((int) (target.offset - jump.offset - jump.getBytes().length));
}
removeUnreachableActions(code, cpool, trait, minfo, body);
removeZeroJumps(code, body);
i = -1;
}
}*/
executeActions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns);
}
return false;
@@ -237,7 +203,10 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
localData.isStatic = isStatic;
localData.classIndex = classIndex;
localData.localRegs = new HashMap<>();
for (int i = 0; i < body.max_regs; i++) {
for (int i = 0; i < body.getLocalReservedCount(); i++) {
localData.localRegs.put(i, new NotCompileTimeItem(null, new UndefinedAVM2Item(null)));
}
for (int i = body.getLocalReservedCount(); i < body.max_regs; i++) {
localData.localRegs.put(i, new UndefinedAVM2Item(null));
}
localData.scopeStack = new ScopeStack(true);
@@ -259,7 +228,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
return localData;
}
private void executeActions(int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result) {
private void executeActions(Map<Integer, GraphTargetItem> staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List<AVM2Instruction> inlineIns) {
List<GraphTargetItem> output = new ArrayList<>();
AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex);
@@ -288,8 +257,28 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
} else {
action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
}
InstructionDefinition def = action.definition;
if (inlineIns.contains(action)) {
if (def instanceof SetLocalTypeIns) {
int regId = ((SetLocalTypeIns) def).getRegisterId(action);
staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced());
code.replaceInstruction(idx, new AVM2Instruction(0, new DeobfuscatePopIns(), new int[]{}), body);
}
}
if (def instanceof GetLocalTypeIns) {
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
if (staticRegs.containsKey(regId)) {
stack.pop();
AVM2Instruction pushins = makePush(abc.constants, staticRegs.get(regId));
code.replaceInstruction(idx, pushins, body);
stack.push(staticRegs.get(regId));
action = pushins;
def = action.definition;
}
}
Class allowedDefs[] = new Class[]{
PushByteIns.class,
PushShortIns.class,
@@ -326,7 +315,8 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
StrictEqualsIns.class,
PopIns.class,
GetLocalTypeIns.class,
NewFunctionIns.class
NewFunctionIns.class,
CoerceOrConvertTypeIns.class
};
boolean ok = false;
@@ -342,10 +332,9 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
if (def instanceof GetLocalTypeIns) {
int regId = ((GetLocalTypeIns) def).getRegisterId(action);
if (regId > 0 && localData.localRegs.get(regId) instanceof UndefinedAVM2Item) {
//System.err.println(""+);
if (staticRegs.containsKey(regId)) {
stack.pop();
stack.push(new UndefinedAVM2Item(action));
stack.push(staticRegs.get(regId));
} else {
break;
}
@@ -435,7 +424,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
AVM2Code code = body.getCode();
code.fixJumps(body);
removeUnreachableActions(code, cpool, trait, minfo, body);
removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body);
removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, new ArrayList<>());
removeZeroJumps(code, body);
}

View File

@@ -121,7 +121,7 @@ public final class MethodBody implements Cloneable {
AVM2Code avm2Code;
try {
ABCInputStream ais = new ABCInputStream(new MemoryInputStream(codeBytes));
avm2Code = new AVM2Code(ais);
avm2Code = new AVM2Code(ais, this);
avm2Code.removeWrongIndices(abc.constants);
} catch (UnknownInstructionCode | IOException ex) {
avm2Code = new AVM2Code();
@@ -218,6 +218,17 @@ public final class MethodBody implements Cloneable {
getCode().insertInstruction(pos, instruction, mapOffsetsAfterIns, this);
}
public int getLocalReservedCount() {
int pos = abc.method_info.get(this.method_info).param_types.length + 1;
if (abc.method_info.get(this.method_info).flagNeed_arguments()) {
pos++;
}
if (abc.method_info.get(this.method_info).flagNeed_rest()) {
pos++;
}
return pos;
}
public HashMap<Integer, String> getLocalRegNames(ABC abc) {
HashMap<Integer, String> ret = new HashMap<>();
for (int i = 1; i <= abc.method_info.get(this.method_info).param_types.length; i++) {
@@ -247,9 +258,6 @@ public final class MethodBody implements Cloneable {
}
public void convert(final String path, ScriptExportMode exportMode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List<MethodInfo> method_info, final ScopeStack scopeStack, final boolean isStaticInitializer, final GraphTextWriter writer, final List<String> fullyQualifiedNames, final Traits initTraits, boolean firstLevel) throws InterruptedException {
/*if (!path.contains("forcedWidth")) {
return;
}*/
if (debugMode) {
System.err.println("Decompiling " + path);
}
@@ -296,9 +304,6 @@ public final class MethodBody implements Cloneable {
}
public GraphTextWriter toString(final String path, ScriptExportMode exportMode, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List<MethodInfo> method_info, final GraphTextWriter writer, final List<String> fullyQualifiedNames) throws InterruptedException {
/*if (!path.contains("forcedWidth")) {
return writer;
}*/
if (exportMode != ScriptExportMode.AS) {
getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer);
} else {