@Override public void translate( boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) { int multinameIndex = ins.operands[0]; FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins); GraphTargetItem obj = stack.pop(); stack.push(new GetPropertyAVM2Item(ins, obj, multiname)); }
@Override public void translateInverted( HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, AVM2Instruction ins) { GraphTargetItem v2 = stack.pop(); GraphTargetItem v1 = stack.pop(); stack.push(new StrictEqAVM2Item(ins, v1, v2)); }
@Override public void translate( boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) { GraphTargetItem v2 = stack.pop(); GraphTargetItem v1 = stack.pop(); stack.push(new EqAVM2Item(ins, v1, v2)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(localData.getConstants(), ins))); }
@Override public int getStackPopCount(BaseLocalData localData, TranslateStack stack) { int result = 3; if (stack.size() >= 3) { result += stack.peek(3).getAsLong(); } return result; }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { GraphTargetItem obj = stack.pop(); stack.push(new FilteredCheckAVM2Item(ins, localData.lineStartInstruction, obj)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) throws InterruptedException { int argCount = ins.operands[0]; List<GraphTargetItem> args = new ArrayList<>(); for (int a = 0; a < argCount; a++) { args.add(0, stack.pop()); } GraphTargetItem obj = stack.pop(); boolean isXML = false; if (obj instanceof GetPropertyAVM2Item) { GetPropertyAVM2Item gpt = (GetPropertyAVM2Item) obj; if (gpt.object instanceof FindPropertyAVM2Item) { FindPropertyAVM2Item fpt = (FindPropertyAVM2Item) gpt.object; FullMultinameAVM2Item fptXmlMult = (FullMultinameAVM2Item) fpt.propertyName; FullMultinameAVM2Item gptXmlMult = (FullMultinameAVM2Item) gpt.propertyName; isXML = fptXmlMult.isXML( localData.getConstants(), localData.localRegNames, localData.fullyQualifiedNames) && gptXmlMult.isXML( localData.getConstants(), localData.localRegNames, localData.fullyQualifiedNames); } } if (obj instanceof GetLexAVM2Item) { GetLexAVM2Item glt = (GetLexAVM2Item) obj; isXML = glt.propertyName .getName(localData.getConstants(), localData.fullyQualifiedNames, true) .equals("XML"); } if (isXML) { if (args.size() == 1) { GraphTargetItem arg = args.get(0); List<GraphTargetItem> xmlLines = new ArrayList<>(); if (walkXML(arg, xmlLines)) { stack.push(new XMLAVM2Item(ins, xmlLines)); return; } } } stack.push(new ConstructAVM2Item(ins, obj, args)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { GraphTargetItem v2 = stack.pop(); GraphTargetItem v1 = stack.pop(); stack.push(new LtAVM2Item(ins, localData.lineStartInstruction, v1, v2)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { GraphTargetItem ofs = stack.pop(); GraphTargetItem value = stack.pop(); output.add(new AlchemyStoreAVM2Item(ins, value, ofs, 'i', 8)); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem a = stack.pop(); stack.push(new MBCharToAsciiActionItem(this, a)); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem value = stack.peek(); stack.push(new DuplicateItem(this, value)); value.getMoreSrc().add(new GraphSourceItemPos(this, 0)); }
@Override public void translate( GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem object = stack.pop(); stack.push(new TargetPathActionItem(this, lineStartAction, object)); }
protected FullMultinameAVM2Item resolveMultiname( TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) { GraphTargetItem ns = null; GraphTargetItem name = null; if (multinameIndex > 0 && multinameIndex < constants.constant_multiname.size()) { if (constants.getMultiname(multinameIndex).needsName()) { name = stack.pop(); } if (constants.getMultiname(multinameIndex).needsNs()) { ns = stack.pop(); } } return new FullMultinameAVM2Item(ins, multinameIndex, name, ns); }
@Override public void translateContainer( List<List<GraphTargetItem>> content, GraphSourceItem lineStartItem, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) { List<FunctionActionItem> funcList = new ArrayList<>(); for (String key : functions.keySet()) { GraphTargetItem val = functions.get(key); if (val instanceof FunctionActionItem) { funcList.add((FunctionActionItem) val); } } FunctionActionItem fti = new FunctionActionItem( this, lineStartItem, functionName, paramNames, getRegNames(), content.get(0), constantPool, getFirstRegister(), new ArrayList<>(), funcList); functions.put(functionName, fti); stack.push(fti); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { int argCount = ins.operands[0]; List<GraphTargetItem> args = new ArrayList<>(); for (int a = 0; a < argCount; a++) { args.add(0, stack.pop()); } GraphTargetItem receiver = stack.pop(); GraphTargetItem function = stack.pop(); stack.push(new CallAVM2Item(ins, localData.lineStartInstruction, receiver, function, args)); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem subclass = stack.pop(); long inCount = popLong(stack); List<GraphTargetItem> superclasses = new ArrayList<>(); for (long l = 0; l < inCount; l++) { superclasses.add(stack.pop()); } output.add(new ImplementsOpActionItem(this, subclass, superclasses)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { stack.push(new NewActivationAVM2Item(ins, localData.lineStartInstruction)); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem methodName = stack.pop(); GraphTargetItem scriptObject = stack.pop(); long numArgs = popLong(stack); List<GraphTargetItem> args = new ArrayList<>(); for (long l = 0; l < numArgs; l++) { args.add(stack.pop()); } stack.push(new NewMethodActionItem(this, scriptObject, methodName, args)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { output.add(new ThrowAVM2Item(ins, localData.lineStartInstruction, stack.pop())); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { stack.push(new UndefinedAVM2Item(ins)); }
@Override public void translateContainer( List<List<GraphTargetItem>> content, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) { output.add(new WithActionItem(this, stack.pop(), content.get(0))); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { int multinameIndex = ins.operands[0]; Multiname multiname = localData.getConstants().getMultiname(multinameIndex); stack.push(new GetLexAVM2Item(ins, multiname)); }
@Override public void translate( AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) { GraphTargetItem top = stack.pop(); if ((!(top instanceof MarkItem))) { output.add(top); } }
@Override public void translate( GraphSourceItem lineStartAction, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { output.add(new CallActionItem(this, lineStartAction, stack.pop())); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) { GraphTargetItem object = stack.pop(); output.add(new EnumerateActionItem(this, object)); }
@Override public void translateContainer( List<List<GraphTargetItem>> content, TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) { FunctionActionItem fti = new FunctionActionItem( this, functionName, paramNames, content.get(0), constantPool, 1, new ArrayList<>()); // ActionGraph.translateViaGraph(regNames, variables, functions, code, version) stack.push(fti); functions.put(functionName, fti); }
@Override public void translate( TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException { GraphTargetItem frame = stack.pop(); List<GraphTargetItem> body = ActionGraph.translateViaGraph( regNames, variables, functions, skipped, SWF.DEFAULT_VERSION, staticOperation, path); output.add(new IfFrameLoadedActionItem(frame, body, this)); }
@Override public void translate( boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) { stack.push(new IntegerValueAVM2Item(ins, constants.getUInt(ins.operands[0]))); }
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, Set<Integer> ignored, Set<Integer> ignoredGets) throws InterruptedException { List<GraphTargetItem> output = new ArrayList<>(); AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); initLocalRegs(localData, body.getLocalReservedCount(), body.max_regs); localData.localRegs.put(0, new NullAVM2Item(null, null)); // this List<Integer> toVisit = new ArrayList<>(); toVisit.add(idx); List<TranslateStack> toVisitStacks = new ArrayList<>(); toVisitStacks.add(stack); outer: while (!toVisit.isEmpty()) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } idx = toVisit.remove(0); stack = toVisitStacks.remove(0); while (true) { if (idx > endIdx) { break; } if (visited.contains(idx)) { break; } visited.add(idx); AVM2Instruction ins = code.code.get(idx); InstructionDefinition def = ins.definition; // System.err.println("" + idx + ": " + ins + " stack:" + stack.size()); // do not throw EmptyStackException, much faster int requiredStackSize = ins.getStackPopCount(localData); if (stack.size() < requiredStackSize) { continue outer; } ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); if (def instanceof SetLocalTypeIns) { int regId = ((SetLocalTypeIns) def).getRegisterId(ins); if (!ignored.contains(regId)) { assignment.setVal(ins); return regId; } } else if (def instanceof GetLocalTypeIns) { int regId = ((GetLocalTypeIns) def).getRegisterId(ins); if (!ignored.contains(regId) && !ignoredGets.contains(regId)) { assignment.setVal(ins); return regId; } } else if (!(def instanceof KillIns) && !(def instanceof DebugIns)) { // can be inclocal, declocal, hasnext... for (int p = 0; p < ins.definition.operands.length; p++) { int op = ins.definition.operands[p]; if (op == AVM2Code.DAT_LOCAL_REG_INDEX) { int regId = ins.operands[p]; if (!ignored.contains(regId)) { assignment.setVal(ins); return regId; } } } } idx++; if (ins.definition instanceof JumpIns) { long address = ins.offset + ins.getBytesLength() + ins.operands[0]; idx = code.adr2pos(address); // code.indexOf(code.getByAddress(address)); if (idx == -1) { throw new TranslateException("Jump target not found: " + address); } } if (ins.isBranch()) { List<Integer> branches = ins.getBranches( new GraphSource() { @Override public int size() { throw new UnsupportedOperationException( "Not supported yet."); // To change body of generated methods, choose // Tools | Templates. } @Override public GraphSourceItem get(int pos) { throw new UnsupportedOperationException( "Not supported yet."); // To change body of generated methods, choose // Tools | Templates. } @Override public boolean isEmpty() { throw new UnsupportedOperationException( "Not supported yet."); // To change body of generated methods, choose // Tools | Templates. } @Override public List<GraphTargetItem> translatePart( GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException { throw new UnsupportedOperationException( "Not supported yet."); // To change body of generated methods, choose // Tools | Templates. } @Override public int adr2pos(long adr) { return code.adr2pos(adr); } @Override public long pos2adr(int pos) { return code.pos2adr(pos); } }); idx = branches.get(0); for (int n = 1; n < branches.size(); n++) { // visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body, // scriptIndex, abc, code, branches.get(n), endIdx, result); int nidx = branches.get(n); if (visited.contains(nidx)) { continue; } toVisit.add(nidx); toVisitStacks.add((TranslateStack) stack.clone()); } } /*if (ins.definition instanceof IfTypeIns) { long address = ins.offset + ins.getBytes().length + ins.operands[0]; int newIdx = code.adr2pos(address); if (newIdx == -1) { throw new TranslateException("If target not found: " + address); } visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body, scriptIndex, abc, code, newIdx, endIdx, result); }*/ if (ins.definition instanceof ReturnValueIns) { break; } if (ins.definition instanceof ThrowIns) { break; } if (ins.definition instanceof ReturnVoidIns) { break; } } } return -1; }
@Override public void translate( boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) { int slotIndex = ins.operands[0]; GraphTargetItem value = stack.pop(); GraphTargetItem obj = stack.pop(); // scopeId GraphTargetItem objnoreg = obj; obj = obj.getThroughRegister(); Multiname slotname = null; if (obj instanceof NewActivationAVM2Item) { ((NewActivationAVM2Item) obj).slots.put(slotIndex, value); } if (obj instanceof ExceptionAVM2Item) { slotname = constants.getMultiname(((ExceptionAVM2Item) obj).exception.name_index); } else if (obj instanceof ClassAVM2Item) { slotname = ((ClassAVM2Item) obj).className; } else if (obj instanceof ThisAVM2Item) { slotname = ((ThisAVM2Item) obj).className; } else if (obj instanceof ScriptAVM2Item) { for (int t = 0; t < abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.size(); t++) { Trait tr = abc.script_info.get(((ScriptAVM2Item) obj).scriptIndex).traits.traits.get(t); if (tr instanceof TraitWithSlot) { if (((TraitWithSlot) tr).getSlotIndex() == slotIndex) { slotname = tr.getName(abc); } } } } else if (obj instanceof NewActivationAVM2Item) { for (int t = 0; t < body.traits.traits.size(); t++) { if (body.traits.traits.get(t) instanceof TraitWithSlot) { if (((TraitWithSlot) body.traits.traits.get(t)).getSlotIndex() == slotIndex) { slotname = body.traits.traits.get(t).getName(abc); } } } } if (slotname != null) { if (value instanceof LocalRegAVM2Item) { LocalRegAVM2Item lr = (LocalRegAVM2Item) value; String slotNameStr = slotname.getName(constants, fullyQualifiedNames, true); if (localRegNames.containsKey(lr.regIndex)) { if (localRegNames.get(lr.regIndex).equals(slotNameStr)) { return; // Register with same name to slot } } } } if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementAVM2Item) { GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()) .value .getThroughRegister() .getNotCoerced() .getThroughDuplicate(); if (inside instanceof GetSlotAVM2Item) { GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) && (slotItem.slotName == slotname)) { if (stack.size() > 0) { GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostIncrementAVM2Item(ins, inside)); } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { stack.pop(); stack.push(new PreIncrementAVM2Item(ins, inside)); } else { output.add(new PostIncrementAVM2Item(ins, inside)); } } else { output.add(new PostIncrementAVM2Item(ins, inside)); } return; } } } if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementAVM2Item) { GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()) .value .getThroughRegister() .getNotCoerced() .getThroughDuplicate(); if (inside instanceof GetSlotAVM2Item) { GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside; if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister()) && (slotItem.slotName == slotname)) { if (stack.size() > 0) { GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); if (top == inside) { stack.pop(); stack.push(new PostDecrementAVM2Item(ins, inside)); } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { stack.pop(); stack.push(new PreDecrementAVM2Item(ins, inside)); } else { output.add(new PostDecrementAVM2Item(ins, inside)); } } else { output.add(new PostDecrementAVM2Item(ins, inside)); } return; } } } output.add(new SetSlotAVM2Item(ins, obj, slotname, value)); }