Esempio n. 1
0
        private VBStyleCollection <BasicBlock, int> CreateBasicBlocks(short[] startblock,
                                                                      InstructionSequence instrseq, Dictionary <int, BasicBlock> mapInstrBlocks)
        {
            VBStyleCollection <BasicBlock, int> col = new VBStyleCollection <BasicBlock, int>();
            InstructionSequence currseq             = null;
            List <int>          lstOffs             = null;
            int        len          = startblock.Length;
            short      counter      = 0;
            int        blockoffset  = 0;
            BasicBlock currentBlock = null;

            for (int i = 0; i < len; i++)
            {
                if (startblock[i] == 1)
                {
                    currentBlock = new BasicBlock(++counter);
                    currseq      = currentBlock.GetSeq();
                    lstOffs      = currentBlock.GetInstrOldOffsets();
                    col.AddWithKey(currentBlock, currentBlock.id);
                    blockoffset = instrseq.GetOffset(i);
                }
                startblock[i] = counter;
                Sharpen.Collections.Put(mapInstrBlocks, i, currentBlock);
                currseq.AddInstruction(instrseq.GetInstr(i), instrseq.GetOffset(i) - blockoffset);
                lstOffs.Add(instrseq.GetOffset(i));
            }
            last_id = counter;
            return(col);
        }
Esempio n. 2
0
        private static short[] FindStartInstructions(InstructionSequence seq)
        {
            int len = seq.Length();

            short[]       inststates = new short[len];
            HashSet <int> excSet     = new HashSet <int>();

            foreach (ExceptionHandler handler in seq.GetExceptionTable().GetHandlers())
            {
                excSet.Add(handler.from_instr);
                excSet.Add(handler.to_instr);
                excSet.Add(handler.handler_instr);
            }
            for (int i = 0; i < len; i++)
            {
                // exception blocks
                if (excSet.Contains(i))
                {
                    inststates[i] = 1;
                }
                Instruction instr = seq.GetInstr(i);
                switch (instr.group)
                {
                case Group_Jump:
                {
                    inststates[((JumpInstruction)instr).destination] = 1;
                    goto case Group_Return;
                }

                case Group_Return:
                {
                    if (i + 1 < len)
                    {
                        inststates[i + 1] = 1;
                    }
                    break;
                }

                case Group_Switch:
                {
                    SwitchInstruction swinstr = (SwitchInstruction)instr;
                    int[]             dests   = swinstr.GetDestinations();
                    for (int j = dests.Length - 1; j >= 0; j--)
                    {
                        inststates[dests[j]] = 1;
                    }
                    inststates[swinstr.GetDefaultDestination()] = 1;
                    if (i + 1 < len)
                    {
                        inststates[i + 1] = 1;
                    }
                    break;
                }
                }
            }
            // first instruction
            inststates[0] = 1;
            return(inststates);
        }
Esempio n. 3
0
        private static void RemoveJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint
                                                  data)
        {
            ListStack <VarType> stack = data.GetStack();
            InstructionSequence seq   = block.GetSeq();

            for (int i = 0; i < seq.Length(); i++)
            {
                Instruction instr = seq.GetInstr(i);
                VarType     var   = null;
                if (instr.opcode == ICodeConstants.opc_astore || instr.opcode == ICodeConstants.opc_pop)
                {
                    var = stack.GetByOffset(-1);
                }
                InstructionImpact.StepTypes(data, instr, pool);
                switch (instr.opcode)
                {
                case ICodeConstants.opc_jsr:
                case ICodeConstants.opc_ret:
                {
                    seq.RemoveInstruction(i);
                    i--;
                    break;
                }

                case ICodeConstants.opc_astore:
                case ICodeConstants.opc_pop:
                {
                    if (var.type == ICodeConstants.Type_Address)
                    {
                        seq.RemoveInstruction(i);
                        i--;
                    }
                    break;
                }
                }
            }
            block.mark = 1;
            for (int i = 0; i < block.GetSuccs().Count; i++)
            {
                BasicBlock suc = block.GetSuccs()[i];
                if (suc.mark != 1)
                {
                    RemoveJsrInstructions(pool, suc, data.Copy());
                }
            }
            for (int i = 0; i < block.GetSuccExceptions().Count; i++)
            {
                BasicBlock suc = block.GetSuccExceptions()[i];
                if (suc.mark != 1)
                {
                    DataPoint point = new DataPoint();
                    point.SetLocalVariables(new List <VarType>(data.GetLocalVariables()));
                    point.GetStack().Push(new VarType(ICodeConstants.Type_Object, 0, null));
                    RemoveJsrInstructions(pool, suc, point);
                }
            }
        }
Esempio n. 4
0
        public virtual void BuildMonitorFlags()
        {
            foreach (Statement st in stats)
            {
                st.BuildMonitorFlags();
            }
            switch (type)
            {
            case Type_Basicblock:
            {
                BasicBlockStatement bblock = (BasicBlockStatement)this;
                InstructionSequence seq    = bblock.GetBlock().GetSeq();
                if (seq != null && seq.Length() > 0)
                {
                    for (int i = 0; i < seq.Length(); i++)
                    {
                        if (seq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                        {
                            containsMonitorExit = true;
                            break;
                        }
                    }
                    isMonitorEnter__ = (seq.GetLastInstr().opcode == ICodeConstants.opc_monitorenter);
                }
                break;
            }

            case Type_Sequence:
            case Type_If:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }

            case Type_Syncronized:
            case Type_Root:
            case Type_General:
            {
                break;
            }

            default:
            {
                containsMonitorExit = false;
                foreach (Statement st in stats)
                {
                    containsMonitorExit |= st.IsContainsMonitorExit();
                }
                break;
            }
            }
        }
Esempio n. 5
0
        private static bool IsAnonymous(StructClass cl, StructClass enclosingCl)
        {
            // checking super class and interfaces
            int[] interfaces = cl.GetInterfaces();
            if (interfaces.Length > 0)
            {
                bool hasNonTrivialSuperClass = cl.superClass != null && !VarType.Vartype_Object.Equals
                                                   (new VarType(cl.superClass.GetString(), true));
                if (hasNonTrivialSuperClass || interfaces.Length > 1)
                {
                    // can't have multiple 'sources'
                    string message = "Inconsistent anonymous class definition: '" + cl.qualifiedName
                                     + "'. Multiple interfaces and/or super class defined.";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               );
                    return(false);
                }
            }
            else if (cl.superClass == null)
            {
                // neither interface nor super class defined
                string message = "Inconsistent anonymous class definition: '" + cl.qualifiedName
                                 + "'. Neither interface nor super class defined.";
                DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                           );
                return(false);
            }
            // FIXME: check constructors
            // FIXME: check enclosing class/method
            ConstantPool pool       = enclosingCl.GetPool();
            int          refCounter = 0;
            bool         refNotNew  = false;
            StructEnclosingMethodAttribute attribute = cl.GetAttribute(StructGeneralAttribute
                                                                       .Attribute_Enclosing_Method);
            string enclosingMethod = attribute != null?attribute.GetMethodName() : null;

            // checking references in the enclosing class
            foreach (StructMethod mt in enclosingCl.GetMethods())
            {
                if (enclosingMethod != null && !enclosingMethod.Equals(mt.GetName()))
                {
                    continue;
                }
                try
                {
                    mt.ExpandData();
                    InstructionSequence seq = mt.GetInstructionSequence();
                    if (seq != null)
                    {
                        int len = seq.Length();
                        for (int i = 0; i < len; i++)
                        {
                            Instruction instr = seq.GetInstr(i);
                            switch (instr.opcode)
                            {
                            case opc_checkcast:
                            case opc_instanceof:
                            {
                                if (cl.qualifiedName.Equals(pool.GetPrimitiveConstant(instr.Operand(0)).GetString
                                                                ()))
                                {
                                    refCounter++;
                                    refNotNew = true;
                                }
                                break;
                            }

                            case opc_new:
                            case opc_anewarray:
                            case opc_multianewarray:
                            {
                                if (cl.qualifiedName.Equals(pool.GetPrimitiveConstant(instr.Operand(0)).GetString
                                                                ()))
                                {
                                    refCounter++;
                                }
                                break;
                            }

                            case opc_getstatic:
                            case opc_putstatic:
                            {
                                if (cl.qualifiedName.Equals(pool.GetLinkConstant(instr.Operand(0)).classname))
                                {
                                    refCounter++;
                                    refNotNew = true;
                                }
                                break;
                            }
                            }
                        }
                    }
                    mt.ReleaseResources();
                }
                catch (IOException)
                {
                    string message = "Could not read method while checking anonymous class definition: '"
                                     + enclosingCl.qualifiedName + "', '" + InterpreterUtil.MakeUniqueKey(mt.GetName
                                                                                                              (), mt.GetDescriptor()) + "'";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               );
                    return(false);
                }
                if (refCounter > 1 || refNotNew)
                {
                    string message = "Inconsistent references to the class '" + cl.qualifiedName + "' which is supposed to be anonymous";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               );
                    return(false);
                }
            }
            return(true);
        }
        public static void RestorePopRanges(ControlFlowGraph graph)
        {
            List <ExceptionDeobfuscator.Range> lstRanges = new List <ExceptionDeobfuscator.Range
                                                                     >();

            // aggregate ranges
            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                bool found = false;
                foreach (ExceptionDeobfuscator.Range arr in lstRanges)
                {
                    if (arr.handler == range.GetHandler() && InterpreterUtil.EqualObjects(range.GetUniqueExceptionsString
                                                                                              (), arr.uniqueStr))
                    {
                        Sharpen.Collections.AddAll(arr.protectedRange, range.GetProtectedRange());
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    // doesn't matter, which range chosen
                    lstRanges.Add(new ExceptionDeobfuscator.Range(range.GetHandler(), range.GetUniqueExceptionsString
                                                                      (), new HashSet <BasicBlock>(range.GetProtectedRange()), range));
                }
            }
            // process aggregated ranges
            foreach (ExceptionDeobfuscator.Range range in lstRanges)
            {
                if (range.uniqueStr != null)
                {
                    BasicBlock          handler = range.handler;
                    InstructionSequence seq     = handler.GetSeq();
                    Instruction         firstinstr;
                    if (seq.Length() > 0)
                    {
                        firstinstr = seq.GetInstr(0);
                        if (firstinstr.opcode == ICodeConstants.opc_pop || firstinstr.opcode == ICodeConstants
                            .opc_astore)
                        {
                            HashSet <BasicBlock> setrange = new HashSet <BasicBlock>(range.protectedRange);
                            foreach (ExceptionDeobfuscator.Range range_super in lstRanges)
                            {
                                // finally or strict superset
                                if (range != range_super)
                                {
                                    HashSet <BasicBlock> setrange_super = new HashSet <BasicBlock>(range_super.protectedRange
                                                                                                   );
                                    if (!setrange.Contains(range_super.handler) && !setrange_super.Contains(handler) &&
                                        (range_super.uniqueStr == null || setrange.All(setrange_super.Contains)))
                                    {
                                        if (range_super.uniqueStr == null)
                                        {
                                            setrange_super.IntersectWith(setrange);
                                        }
                                        else
                                        {
                                            setrange_super.ExceptWith(setrange);
                                        }
                                        if (!(setrange_super.Count == 0))
                                        {
                                            BasicBlock newblock = handler;
                                            // split the handler
                                            if (seq.Length() > 1)
                                            {
                                                newblock = new BasicBlock(++graph.last_id);
                                                InstructionSequence newseq = new SimpleInstructionSequence();
                                                newseq.AddInstruction(firstinstr.Clone(), -1);
                                                newblock.SetSeq(newseq);
                                                graph.GetBlocks().AddWithKey(newblock, newblock.id);
                                                List <BasicBlock> lstTemp = new List <BasicBlock>();
                                                Sharpen.Collections.AddAll(lstTemp, handler.GetPreds());
                                                Sharpen.Collections.AddAll(lstTemp, handler.GetPredExceptions());
                                                // replace predecessors
                                                foreach (BasicBlock pred in lstTemp)
                                                {
                                                    pred.ReplaceSuccessor(handler, newblock);
                                                }
                                                // replace handler
                                                foreach (ExceptionRangeCFG range_ext in graph.GetExceptions())
                                                {
                                                    if (range_ext.GetHandler() == handler)
                                                    {
                                                        range_ext.SetHandler(newblock);
                                                    }
                                                    else if (range_ext.GetProtectedRange().Contains(handler))
                                                    {
                                                        newblock.AddSuccessorException(range_ext.GetHandler());
                                                        range_ext.GetProtectedRange().Add(newblock);
                                                    }
                                                }
                                                newblock.AddSuccessor(handler);
                                                if (graph.GetFirst() == handler)
                                                {
                                                    graph.SetFirst(newblock);
                                                }
                                                // remove the first pop in the handler
                                                seq.RemoveInstruction(0);
                                            }
                                            newblock.AddSuccessorException(range_super.handler);
                                            range_super.rangeCFG.GetProtectedRange().Add(newblock);
                                            handler = range.rangeCFG.GetHandler();
                                            seq     = handler.GetSeq();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 7
0
 public static void IncorporateValueReturns(ControlFlowGraph graph)
 {
     foreach (BasicBlock block in graph.GetBlocks())
     {
         InstructionSequence seq = block.GetSeq();
         int len = seq.Length();
         if (len > 0 && len < 3)
         {
             bool ok = false;
             if (seq.GetLastInstr().opcode >= ICodeConstants.opc_ireturn && seq.GetLastInstr()
                 .opcode <= ICodeConstants.opc_return)
             {
                 if (len == 1)
                 {
                     ok = true;
                 }
                 else if (seq.GetLastInstr().opcode != ICodeConstants.opc_return)
                 {
                     switch (seq.GetInstr(0).opcode)
                     {
                     case ICodeConstants.opc_iload:
                     case ICodeConstants.opc_lload:
                     case ICodeConstants.opc_fload:
                     case ICodeConstants.opc_dload:
                     case ICodeConstants.opc_aload:
                     case ICodeConstants.opc_aconst_null:
                     case ICodeConstants.opc_bipush:
                     case ICodeConstants.opc_sipush:
                     case ICodeConstants.opc_lconst_0:
                     case ICodeConstants.opc_lconst_1:
                     case ICodeConstants.opc_fconst_0:
                     case ICodeConstants.opc_fconst_1:
                     case ICodeConstants.opc_fconst_2:
                     case ICodeConstants.opc_dconst_0:
                     case ICodeConstants.opc_dconst_1:
                     case ICodeConstants.opc_ldc:
                     case ICodeConstants.opc_ldc_w:
                     case ICodeConstants.opc_ldc2_w:
                     {
                         ok = true;
                         break;
                     }
                     }
                 }
             }
             if (ok)
             {
                 if (!(block.GetPreds().Count == 0))
                 {
                     HashSet <BasicBlock> setPredHandlersUnion        = new HashSet <BasicBlock>();
                     HashSet <BasicBlock> setPredHandlersIntersection = new HashSet <BasicBlock>();
                     bool firstpred = true;
                     foreach (BasicBlock pred in block.GetPreds())
                     {
                         if (firstpred)
                         {
                             Sharpen.Collections.AddAll(setPredHandlersIntersection, pred.GetSuccExceptions());
                             firstpred = false;
                         }
                         else
                         {
                             setPredHandlersIntersection.IntersectWith(pred.GetSuccExceptions());
                         }
                         Sharpen.Collections.AddAll(setPredHandlersUnion, pred.GetSuccExceptions());
                     }
                     // add exception ranges from predecessors
                     setPredHandlersIntersection.ExceptWith(block.GetSuccExceptions());
                     BasicBlock predecessor = block.GetPreds()[0];
                     foreach (BasicBlock handler in setPredHandlersIntersection)
                     {
                         ExceptionRangeCFG range = graph.GetExceptionRange(handler, predecessor);
                         range.GetProtectedRange().Add(block);
                         block.AddSuccessorException(handler);
                     }
                     // remove redundant ranges
                     HashSet <BasicBlock> setRangesToBeRemoved = new HashSet <BasicBlock>(block.GetSuccExceptions
                                                                                              ());
                     setRangesToBeRemoved.ExceptWith(setPredHandlersUnion);
                     foreach (BasicBlock handler in setRangesToBeRemoved)
                     {
                         ExceptionRangeCFG range = graph.GetExceptionRange(handler, block);
                         if (range.GetProtectedRange().Count > 1)
                         {
                             range.GetProtectedRange().Remove(block);
                             block.RemoveSuccessorException(handler);
                         }
                     }
                 }
                 if (block.GetPreds().Count == 1 && (block.GetPredExceptions().Count == 0))
                 {
                     BasicBlock bpred = block.GetPreds()[0];
                     if (bpred.GetSuccs().Count == 1)
                     {
                         // add exception ranges of predecessor
                         foreach (BasicBlock succ in bpred.GetSuccExceptions())
                         {
                             if (!block.GetSuccExceptions().Contains(succ))
                             {
                                 ExceptionRangeCFG range = graph.GetExceptionRange(succ, bpred);
                                 range.GetProtectedRange().Add(block);
                                 block.AddSuccessorException(succ);
                             }
                         }
                         // remove superfluous ranges from successors
                         foreach (BasicBlock succ in new HashSet <BasicBlock>(block.GetSuccExceptions()))
                         {
                             if (!bpred.GetSuccExceptions().Contains(succ))
                             {
                                 ExceptionRangeCFG range = graph.GetExceptionRange(succ, block);
                                 if (range.GetProtectedRange().Count > 1)
                                 {
                                     range.GetProtectedRange().Remove(block);
                                     block.RemoveSuccessorException(succ);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Esempio n. 8
0
 public static void ExtendSynchronizedRangeToMonitorexit(ControlFlowGraph graph)
 {
     while (true)
     {
         bool range_extended = false;
         foreach (ExceptionRangeCFG range in graph.GetExceptions())
         {
             HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setPreds, block.GetPreds());
             }
             setPreds.ExceptWith(range.GetProtectedRange());
             if (setPreds.Count != 1)
             {
                 continue;
             }
             // multiple predecessors, obfuscated range
             var                 setPredsEnumerator = new EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator());
             BasicBlock          predBlock          = setPredsEnumerator.Next();
             InstructionSequence predSeq            = predBlock.GetSeq();
             if (predSeq.IsEmpty() || predSeq.GetLastInstr().opcode != ICodeConstants.opc_monitorenter)
             {
                 continue;
             }
             // not a synchronized range
             bool monitorexit_in_range = false;
             HashSet <BasicBlock> setProtectedBlocks = new HashSet <BasicBlock>();
             Sharpen.Collections.AddAll(setProtectedBlocks, range.GetProtectedRange());
             setProtectedBlocks.Add(range.GetHandler());
             foreach (BasicBlock block in setProtectedBlocks)
             {
                 InstructionSequence blockSeq = block.GetSeq();
                 for (int i = 0; i < blockSeq.Length(); i++)
                 {
                     if (blockSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                     {
                         monitorexit_in_range = true;
                         break;
                     }
                 }
                 if (monitorexit_in_range)
                 {
                     break;
                 }
             }
             if (monitorexit_in_range)
             {
                 continue;
             }
             // protected range already contains monitorexit
             HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>();
             foreach (BasicBlock block in range.GetProtectedRange())
             {
                 Sharpen.Collections.AddAll(setSuccs, block.GetSuccs());
             }
             setSuccs.ExceptWith(range.GetProtectedRange());
             if (setSuccs.Count != 1)
             {
                 continue;
             }
             // non-unique successor
             BasicBlock          succBlock = new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next();
             InstructionSequence succSeq   = succBlock.GetSeq();
             int succ_monitorexit_index    = -1;
             for (int i = 0; i < succSeq.Length(); i++)
             {
                 if (succSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     succ_monitorexit_index = i;
                     break;
                 }
             }
             if (succ_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the single successor block
             BasicBlock handlerBlock = range.GetHandler();
             if (handlerBlock.GetSuccs().Count != 1)
             {
                 continue;
             }
             // non-unique handler successor
             BasicBlock          succHandler    = handlerBlock.GetSuccs()[0];
             InstructionSequence succHandlerSeq = succHandler.GetSeq();
             if (succHandlerSeq.IsEmpty() || succHandlerSeq.GetLastInstr().opcode != ICodeConstants
                 .opc_athrow)
             {
                 continue;
             }
             // not a standard synchronized range
             int handler_monitorexit_index = -1;
             for (int i = 0; i < succHandlerSeq.Length(); i++)
             {
                 if (succHandlerSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit)
                 {
                     handler_monitorexit_index = i;
                     break;
                 }
             }
             if (handler_monitorexit_index < 0)
             {
                 continue;
             }
             // monitorexit not found in the handler successor block
             // checks successful, prerequisites satisfied, now extend the range
             if (succ_monitorexit_index < succSeq.Length() - 1)
             {
                 // split block
                 SimpleInstructionSequence seq = new SimpleInstructionSequence();
                 for (int counter = 0; counter < succ_monitorexit_index; counter++)
                 {
                     seq.AddInstruction(succSeq.GetInstr(0), -1);
                     succSeq.RemoveInstruction(0);
                 }
                 // build a separate block
                 BasicBlock newblock = new BasicBlock(++graph.last_id);
                 newblock.SetSeq(seq);
                 // insert new block
                 foreach (BasicBlock block in succBlock.GetPreds())
                 {
                     block.ReplaceSuccessor(succBlock, newblock);
                 }
                 newblock.AddSuccessor(succBlock);
                 graph.GetBlocks().AddWithKey(newblock, newblock.id);
                 succBlock = newblock;
             }
             // copy exception edges and extend protected ranges (successor block)
             BasicBlock rangeExitBlock = succBlock.GetPreds()[0];
             for (int j = 0; j < rangeExitBlock.GetSuccExceptions().Count; j++)
             {
                 BasicBlock hd = rangeExitBlock.GetSuccExceptions()[j];
                 succBlock.AddSuccessorException(hd);
                 ExceptionRangeCFG rng = graph.GetExceptionRange(hd, rangeExitBlock);
                 rng.GetProtectedRange().Add(succBlock);
             }
             // copy instructions (handler successor block)
             InstructionSequence handlerSeq = handlerBlock.GetSeq();
             for (int counter = 0; counter < handler_monitorexit_index; counter++)
             {
                 handlerSeq.AddInstruction(succHandlerSeq.GetInstr(0), -1);
                 succHandlerSeq.RemoveInstruction(0);
             }
             range_extended = true;
             break;
         }
         if (!range_extended)
         {
             break;
         }
     }
 }
Esempio n. 9
0
        private bool CompareBasicBlocksEx(ControlFlowGraph graph, BasicBlock pattern, BasicBlock
                                          sample, int type, int finallytype, List <int[]> lstStoreVars)
        {
            InstructionSequence seqPattern = pattern.GetSeq();
            InstructionSequence seqSample  = sample.GetSeq();

            if (type != 0)
            {
                seqPattern = seqPattern.Clone();
                if ((type & 1) > 0)
                {
                    // first
                    if (finallytype > 0)
                    {
                        seqPattern.RemoveInstruction(0);
                    }
                }
                if ((type & 2) > 0)
                {
                    // last
                    if (finallytype == 0 || finallytype == 2)
                    {
                        seqPattern.RemoveLast();
                    }
                    if (finallytype == 2)
                    {
                        seqPattern.RemoveLast();
                    }
                }
            }
            if (seqPattern.Length() > seqSample.Length())
            {
                return(false);
            }
            for (int i = 0; i < seqPattern.Length(); i++)
            {
                Instruction instrPattern = seqPattern.GetInstr(i);
                Instruction instrSample  = seqSample.GetInstr(i);
                // compare instructions with respect to jumps
                if (!EqualInstructions(instrPattern, instrSample, lstStoreVars))
                {
                    return(false);
                }
            }
            if (seqPattern.Length() < seqSample.Length())
            {
                // split in two blocks
                SimpleInstructionSequence seq        = new SimpleInstructionSequence();
                LinkedList <int>          oldOffsets = new LinkedList <int>();
                for (int i = seqSample.Length() - 1; i >= seqPattern.Length(); i--)
                {
                    seq.AddInstruction(0, seqSample.GetInstr(i), -1);
                    oldOffsets.AddFirst(sample.GetOldOffset(i));
                    seqSample.RemoveInstruction(i);
                }
                BasicBlock newblock = new BasicBlock(++graph.last_id);
                newblock.SetSeq(seq);
                Sharpen.Collections.AddAll(newblock.GetInstrOldOffsets(), oldOffsets);
                List <BasicBlock> lstTemp = new List <BasicBlock>(sample.GetSuccs());
                // move successors
                foreach (BasicBlock suc in lstTemp)
                {
                    sample.RemoveSuccessor(suc);
                    newblock.AddSuccessor(suc);
                }
                sample.AddSuccessor(newblock);
                graph.GetBlocks().AddWithKey(newblock, newblock.id);
                HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits();
                if (setFinallyExits.Contains(sample))
                {
                    setFinallyExits.Remove(sample);
                    setFinallyExits.Add(newblock);
                }
                // copy exception edges and extend protected ranges
                for (int j = 0; j < sample.GetSuccExceptions().Count; j++)
                {
                    BasicBlock hd = sample.GetSuccExceptions()[j];
                    newblock.AddSuccessorException(hd);
                    ExceptionRangeCFG range = graph.GetExceptionRange(hd, sample);
                    range.GetProtectedRange().Add(newblock);
                }
            }
            return(true);
        }
Esempio n. 10
0
        private static BasicBlock GetUniqueNext(ControlFlowGraph graph, HashSet <BasicBlock
                                                                                 []> setNext)
        {
            // precondition: there is at most one true exit path in a finally statement
            BasicBlock next     = null;
            bool       multiple = false;

            foreach (BasicBlock[] arr in setNext)
            {
                if (arr[2] != null)
                {
                    next     = arr[1];
                    multiple = false;
                    break;
                }
                else
                {
                    if (next == null)
                    {
                        next = arr[1];
                    }
                    else if (next != arr[1])
                    {
                        multiple = true;
                    }
                    if (arr[1].GetPreds().Count == 1)
                    {
                        next = arr[1];
                    }
                }
            }
            if (multiple)
            {
                // TODO: generic solution
                foreach (BasicBlock[] arr in setNext)
                {
                    BasicBlock block = arr[1];
                    if (block != next)
                    {
                        if (InterpreterUtil.EqualSets(next.GetSuccs(), block.GetSuccs()))
                        {
                            InstructionSequence seqNext  = next.GetSeq();
                            InstructionSequence seqBlock = block.GetSeq();
                            if (seqNext.Length() == seqBlock.Length())
                            {
                                for (int i = 0; i < seqNext.Length(); i++)
                                {
                                    Instruction instrNext  = seqNext.GetInstr(i);
                                    Instruction instrBlock = seqBlock.GetInstr(i);
                                    if (!Instruction.Equals(instrNext, instrBlock))
                                    {
                                        return(null);
                                    }
                                    for (int j = 0; j < instrNext.OperandsCount(); j++)
                                    {
                                        if (instrNext.Operand(j) != instrBlock.Operand(j))
                                        {
                                            return(null);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                //			try {
                //				DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
                //			} catch(IOException ex) {
                //				ex.printStackTrace();
                //			}
                foreach (BasicBlock[] arr in setNext)
                {
                    if (arr[1] != next)
                    {
                        // FIXME: exception edge possible?
                        arr[0].RemoveSuccessor(arr[1]);
                        arr[0].AddSuccessor(next);
                    }
                }
                DeadCodeHelper.RemoveDeadBlocks(graph);
            }
            return(next);
        }
Esempio n. 11
0
 public virtual Instruction GetInstruction(int index)
 {
     return(seq.GetInstr(index));
 }
Esempio n. 12
0
        /// <exception cref="IOException"/>
        public virtual void ProcessClass(ClassesProcessor.ClassNode node)
        {
            foreach (ClassesProcessor.ClassNode child in node.nested)
            {
                ProcessClass(child);
            }
            ClassesProcessor clProcessor = DecompilerContext.GetClassProcessor();
            StructClass      cl          = node.classStruct;

            if (cl.GetBytecodeVersion() < ICodeConstants.Bytecode_Java_8)
            {
                // lambda beginning with Java 8
                return;
            }
            StructBootstrapMethodsAttribute bootstrap = cl.GetAttribute(StructGeneralAttribute
                                                                        .Attribute_Bootstrap_Methods);

            if (bootstrap == null || bootstrap.GetMethodsNumber() == 0)
            {
                return;
            }
            // no bootstrap constants in pool
            BitSet lambda_methods = new BitSet();

            // find lambda bootstrap constants
            for (int i = 0; i < bootstrap.GetMethodsNumber(); ++i)
            {
                LinkConstant method_ref = bootstrap.GetMethodReference(i);
                // method handle
                // FIXME: extend for Eclipse etc. at some point
                if (Javac_Lambda_Class.Equals(method_ref.classname) && (Javac_Lambda_Method.Equals
                                                                            (method_ref.elementname) || Javac_Lambda_Alt_Method.Equals(method_ref.elementname
                                                                                                                                       )))
                {
                    lambda_methods.Set(i);
                }
            }
            if (lambda_methods.IsEmpty())
            {
                return;
            }
            // no lambda bootstrap constant found
            Dictionary <string, string> mapMethodsLambda = new Dictionary <string, string>();

            // iterate over code and find invocations of bootstrap methods. Replace them with anonymous classes.
            foreach (StructMethod mt in cl.GetMethods())
            {
                mt.ExpandData();
                InstructionSequence seq = mt.GetInstructionSequence();
                if (seq != null && seq.Length() > 0)
                {
                    int len = seq.Length();
                    for (int i = 0; i < len; ++i)
                    {
                        Instruction instr = seq.GetInstr(i);
                        if (instr.opcode == ICodeConstants.opc_invokedynamic)
                        {
                            LinkConstant invoke_dynamic = cl.GetPool().GetLinkConstant(instr.Operand(0));
                            if (lambda_methods.Get(invoke_dynamic.index1))
                            {
                                // lambda invocation found
                                List <PooledConstant> bootstrap_arguments = bootstrap.GetMethodArguments(invoke_dynamic
                                                                                                         .index1);
                                MethodDescriptor md = MethodDescriptor.ParseDescriptor(invoke_dynamic.descriptor);
                                string           lambda_class_name        = md.ret.value;
                                string           lambda_method_name       = invoke_dynamic.elementname;
                                string           lambda_method_descriptor = ((PrimitiveConstant)bootstrap_arguments[2]).GetString
                                                                                ();
                                // method type
                                LinkConstant content_method_handle     = (LinkConstant)bootstrap_arguments[1];
                                ClassesProcessor.ClassNode node_lambda = new ClassesProcessor.ClassNode(content_method_handle
                                                                                                        .classname, content_method_handle.elementname, content_method_handle.descriptor,
                                                                                                        content_method_handle.index1, lambda_class_name, lambda_method_name, lambda_method_descriptor
                                                                                                        , cl);
                                node_lambda.simpleName = cl.qualifiedName + "##Lambda_" + invoke_dynamic.index1 +
                                                         "_" + invoke_dynamic.index2;
                                node_lambda.enclosingMethod = InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.GetDescriptor
                                                                                                ());
                                node.nested.Add(node_lambda);
                                node_lambda.parent = node;
                                Sharpen.Collections.Put(clProcessor.GetMapRootClasses(), node_lambda.simpleName,
                                                        node_lambda);
                                if (!node_lambda.lambdaInformation.is_method_reference)
                                {
                                    Sharpen.Collections.Put(mapMethodsLambda, node_lambda.lambdaInformation.content_method_key
                                                            , node_lambda.simpleName);
                                }
                            }
                        }
                    }
                }
                mt.ReleaseResources();
            }
            // build class hierarchy on lambda
            foreach (ClassesProcessor.ClassNode nd in node.nested)
            {
                if (nd.type == ClassesProcessor.ClassNode.Class_Lambda)
                {
                    string parent_class_name = mapMethodsLambda.GetOrNull(nd.enclosingMethod);
                    if (parent_class_name != null)
                    {
                        ClassesProcessor.ClassNode parent_class = clProcessor.GetMapRootClasses().GetOrNull
                                                                      (parent_class_name);
                        parent_class.nested.Add(nd);
                        nd.parent = parent_class;
                    }
                }
            }
        }