Exemplo n.º 1
0
        private static void InsertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock
                                              , BasicBlock newblock)
        {
            List <BasicBlock> lstTemp = new List <BasicBlock>();

            Sharpen.Collections.AddAll(lstTemp, oldblock.GetPreds());
            Sharpen.Collections.AddAll(lstTemp, oldblock.GetPredExceptions());
            // replace predecessors
            foreach (BasicBlock pred in lstTemp)
            {
                pred.ReplaceSuccessor(oldblock, newblock);
            }
            // copy exception edges and extend protected ranges
            foreach (BasicBlock hd in oldblock.GetSuccExceptions())
            {
                newblock.AddSuccessorException(hd);
                ExceptionRangeCFG range = graph.GetExceptionRange(hd, oldblock);
                range.GetProtectedRange().Add(newblock);
            }
            // replace handler
            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                if (range.GetHandler() == oldblock)
                {
                    range.SetHandler(newblock);
                }
            }
            newblock.AddSuccessor(oldblock);
            graph.GetBlocks().AddWithKey(newblock, newblock.id);
            if (graph.GetFirst() == oldblock)
            {
                graph.SetFirst(newblock);
            }
        }
Exemplo n.º 2
0
        public static void InsertDummyExceptionHandlerBlocks(ControlFlowGraph graph, int
                                                             bytecode_version)
        {
            Dictionary <BasicBlock, HashSet <ExceptionRangeCFG> > mapRanges = new Dictionary <BasicBlock
                                                                                              , HashSet <ExceptionRangeCFG> >();

            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                mapRanges.ComputeIfAbsent(range.GetHandler(), (BasicBlock k) => new HashSet <ExceptionRangeCFG
                                                                                             >()).Add(range);
            }
            foreach (KeyValuePair <BasicBlock, HashSet <ExceptionRangeCFG> > ent in mapRanges)
            {
                BasicBlock handler = ent.Key;
                HashSet <ExceptionRangeCFG> ranges = ent.Value;
                if (ranges.Count == 1)
                {
                    continue;
                }
                foreach (ExceptionRangeCFG range in ranges)
                {
                    // add some dummy instructions to prevent optimizing away the empty block
                    SimpleInstructionSequence seq = new SimpleInstructionSequence();
                    seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                          .Group_General, bytecode_version, new int[] { 0 }), -1);
                    seq.AddInstruction(Instruction.Create(ICodeConstants.opc_pop, false, ICodeConstants
                                                          .Group_General, bytecode_version, null), -1);
                    BasicBlock dummyBlock = new BasicBlock(++graph.last_id);
                    dummyBlock.SetSeq(seq);
                    graph.GetBlocks().AddWithKey(dummyBlock, dummyBlock.id);
                    // only exception predecessors from this range considered
                    List <BasicBlock> lstPredExceptions = new List <BasicBlock>(handler.GetPredExceptions
                                                                                    ());
                    lstPredExceptions = lstPredExceptions.Intersect(range.GetProtectedRange()).ToList();
                    // replace predecessors
                    foreach (BasicBlock pred in lstPredExceptions)
                    {
                        pred.ReplaceSuccessor(handler, dummyBlock);
                    }
                    // replace handler
                    range.SetHandler(dummyBlock);
                    // add common exception edges
                    HashSet <BasicBlock> commonHandlers = new HashSet <BasicBlock>(handler.GetSuccExceptions
                                                                                       ());
                    foreach (BasicBlock pred in lstPredExceptions)
                    {
                        commonHandlers.IntersectWith(pred.GetSuccExceptions());
                    }
                    // TODO: more sanity checks?
                    foreach (BasicBlock commonHandler in commonHandlers)
                    {
                        ExceptionRangeCFG commonRange = graph.GetExceptionRange(commonHandler, handler);
                        dummyBlock.AddSuccessorException(commonHandler);
                        commonRange.GetProtectedRange().Add(dummyBlock);
                    }
                    dummyBlock.AddSuccessor(handler);
                }
            }
        }
Exemplo n.º 3
0
        public static void InsertEmptyExceptionHandlerBlocks(ControlFlowGraph graph)
        {
            HashSet <BasicBlock> setVisited = new HashSet <BasicBlock>();

            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                BasicBlock handler = range.GetHandler();
                if (setVisited.Contains(handler))
                {
                    continue;
                }
                setVisited.Add(handler);
                BasicBlock emptyblock = new BasicBlock(++graph.last_id);
                graph.GetBlocks().AddWithKey(emptyblock, emptyblock.id);
                // only exception predecessors considered
                List <BasicBlock> lstTemp = new List <BasicBlock>(handler.GetPredExceptions());
                // replace predecessors
                foreach (BasicBlock pred in lstTemp)
                {
                    pred.ReplaceSuccessor(handler, emptyblock);
                }
                // replace handler
                foreach (ExceptionRangeCFG range_ext in graph.GetExceptions())
                {
                    if (range_ext.GetHandler() == handler)
                    {
                        range_ext.SetHandler(emptyblock);
                    }
                    else if (range_ext.GetProtectedRange().Contains(handler))
                    {
                        emptyblock.AddSuccessorException(range_ext.GetHandler());
                        range_ext.GetProtectedRange().Add(emptyblock);
                    }
                }
                emptyblock.AddSuccessor(handler);
                if (graph.GetFirst() == handler)
                {
                    graph.SetFirst(emptyblock);
                }
            }
        }
Exemplo n.º 4
0
        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();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        private static void DeleteArea(ControlFlowGraph graph, FinallyProcessor.Area area
                                       )
        {
            BasicBlock start = area.start;
            BasicBlock next  = area.next;

            if (start == next)
            {
                return;
            }
            if (next == null)
            {
                // dummy exit block
                next = graph.GetLast();
            }
            // collect common exception ranges of predecessors and successors
            HashSet <BasicBlock> setCommonExceptionHandlers = new HashSet <BasicBlock>(next.GetSuccExceptions
                                                                                           ());

            foreach (BasicBlock pred in start.GetPreds())
            {
                setCommonExceptionHandlers.RetainAll(pred.GetSuccExceptions());
            }
            bool is_outside_range = false;
            HashSet <BasicBlock> setPredecessors = new HashSet <BasicBlock>(start.GetPreds());

            // replace start with next
            foreach (BasicBlock pred in setPredecessors)
            {
                pred.ReplaceSuccessor(start, next);
            }
            HashSet <BasicBlock>        setBlocks = area.sample;
            HashSet <ExceptionRangeCFG> setCommonRemovedExceptionRanges = null;

            // remove all the blocks inbetween
            foreach (BasicBlock block in setBlocks)
            {
                // artificial basic blocks (those resulted from splitting)
                // can belong to more than one area
                if (graph.GetBlocks().ContainsKey(block.id))
                {
                    if (!block.GetSuccExceptions().ContainsAll(setCommonExceptionHandlers))
                    {
                        is_outside_range = true;
                    }
                    HashSet <ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet <ExceptionRangeCFG
                                                                                         >();
                    foreach (BasicBlock handler in block.GetSuccExceptions())
                    {
                        setRemovedExceptionRanges.Add(graph.GetExceptionRange(handler, block));
                    }
                    if (setCommonRemovedExceptionRanges == null)
                    {
                        setCommonRemovedExceptionRanges = setRemovedExceptionRanges;
                    }
                    else
                    {
                        setCommonRemovedExceptionRanges.RetainAll(setRemovedExceptionRanges);
                    }
                    // shift extern edges on splitted blocks
                    if (block.GetSeq().IsEmpty() && block.GetSuccs().Count == 1)
                    {
                        BasicBlock succs = block.GetSuccs()[0];
                        foreach (BasicBlock pred in new List <BasicBlock>(block.GetPreds()))
                        {
                            if (!setBlocks.Contains(pred))
                            {
                                pred.ReplaceSuccessor(block, succs);
                            }
                        }
                        if (graph.GetFirst() == block)
                        {
                            graph.SetFirst(succs);
                        }
                    }
                    graph.RemoveBlock(block);
                }
            }
            if (is_outside_range)
            {
                // new empty block
                BasicBlock emptyblock = new BasicBlock(++graph.last_id);
                graph.GetBlocks().AddWithKey(emptyblock, emptyblock.id);
                // add to ranges if necessary
                foreach (ExceptionRangeCFG range in setCommonRemovedExceptionRanges)
                {
                    emptyblock.AddSuccessorException(range.GetHandler());
                    range.GetProtectedRange().Add(emptyblock);
                }
                // insert between predecessors and next
                emptyblock.AddSuccessor(next);
                foreach (BasicBlock pred in setPredecessors)
                {
                    pred.ReplaceSuccessor(next, emptyblock);
                }
            }
        }
Exemplo n.º 6
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);
        }
Exemplo n.º 7
0
        private static void InsertSemaphore(ControlFlowGraph graph, HashSet <BasicBlock> setTry
                                            , BasicBlock head, BasicBlock handler, int var, FinallyProcessor.Record information
                                            , int bytecode_version)
        {
            HashSet <BasicBlock> setCopy = new HashSet <BasicBlock>(setTry);
            int finallytype = information.firstCode;
            Dictionary <BasicBlock, bool> mapLast = information.mapLast;

            // first and last statements
            RemoveExceptionInstructionsEx(handler, 1, finallytype);
            foreach (KeyValuePair <BasicBlock, bool> entry in mapLast)
            {
                BasicBlock last = entry.Key;
                if (entry.Value)
                {
                    RemoveExceptionInstructionsEx(last, 2, finallytype);
                    graph.GetFinallyExits().Add(last);
                }
            }
            // disable semaphore at statement exit points
            foreach (BasicBlock block in setTry)
            {
                List <BasicBlock> lstSucc = block.GetSuccs();
                foreach (BasicBlock dest in lstSucc)
                {
                    // break out
                    if (dest != graph.GetLast() && !setCopy.Contains(dest))
                    {
                        // disable semaphore
                        SimpleInstructionSequence seq = new SimpleInstructionSequence();
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { 0 }), -1);
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { var }), -1);
                        // build a separate block
                        BasicBlock newblock = new BasicBlock(++graph.last_id);
                        newblock.SetSeq(seq);
                        // insert between block and dest
                        block.ReplaceSuccessor(dest, newblock);
                        newblock.AddSuccessor(dest);
                        setCopy.Add(newblock);
                        graph.GetBlocks().AddWithKey(newblock, newblock.id);
                        // exception ranges
                        // FIXME: special case synchronized
                        // copy exception edges and extend protected ranges
                        for (int j = 0; j < block.GetSuccExceptions().Count; j++)
                        {
                            BasicBlock hd = block.GetSuccExceptions()[j];
                            newblock.AddSuccessorException(hd);
                            ExceptionRangeCFG range = graph.GetExceptionRange(hd, block);
                            range.GetProtectedRange().Add(newblock);
                        }
                    }
                }
            }
            // enable semaphore at the statement entrance
            SimpleInstructionSequence seq_1 = new SimpleInstructionSequence();

            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 1 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newhead = new BasicBlock(++graph.last_id);

            newhead.SetSeq(seq_1);
            InsertBlockBefore(graph, head, newhead);
            // initialize semaphor with false
            seq_1 = new SimpleInstructionSequence();
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 0 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newheadinit = new BasicBlock(++graph.last_id);

            newheadinit.SetSeq(seq_1);
            InsertBlockBefore(graph, newhead, newheadinit);
            setCopy.Add(newhead);
            setCopy.Add(newheadinit);
            foreach (BasicBlock hd in new HashSet <BasicBlock>(newheadinit.GetSuccExceptions()
                                                               ))
            {
                ExceptionRangeCFG range = graph.GetExceptionRange(hd, newheadinit);
                if (setCopy.ContainsAll(range.GetProtectedRange()))
                {
                    newheadinit.RemoveSuccessorException(hd);
                    range.GetProtectedRange().Remove(newheadinit);
                }
            }
        }