Ejemplo n.º 1
0
        bool IsStLdlocBranch(Block switchBlock, bool isSwitch)
        {
            int numInstrs = 2 + (isSwitch ? 1 : 0);

            return(switchBlock.Instructions.Count == numInstrs &&
                   switchBlock.Instructions[0].IsStloc() &&
                   switchBlock.Instructions[1].IsLdloc() &&
                   Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[0]) == Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[1]));
        }
Ejemplo n.º 2
0
 private bool NeedSwitchKey(Block block)
 {
     foreach (var instr in block.Instructions)
     {
         if (instr.IsLdloc() && Instr.GetLocalVar(_blocks.Locals, instr) == _switchKey)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 3
0
 static bool CheckStloc(IList <Local> locals, Instr instr, Local local)
 {
     if (!instr.IsStloc())
     {
         return(false);
     }
     if (Instr.GetLocalVar(locals, instr) != local)
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 4
0
        void FindLoadStores()
        {
            foreach (var block in allBlocks)
            {
                foreach (var instr in block.Instructions)
                {
                    Local       local;
                    AccessFlags flags;
                    switch (instr.OpCode.Code)
                    {
                    case Code.Ldloc:
                    case Code.Ldloc_S:
                    case Code.Ldloc_0:
                    case Code.Ldloc_1:
                    case Code.Ldloc_2:
                    case Code.Ldloc_3:
                        local = Instr.GetLocalVar(blocks.Locals, instr);
                        flags = AccessFlags.Read;
                        break;

                    case Code.Stloc:
                    case Code.Stloc_S:
                    case Code.Stloc_0:
                    case Code.Stloc_1:
                    case Code.Stloc_2:
                    case Code.Stloc_3:
                        local = Instr.GetLocalVar(blocks.Locals, instr);
                        flags = AccessFlags.Write;
                        break;

                    case Code.Ldloca_S:
                    case Code.Ldloca:
                        local = instr.Operand as Local;
                        flags = AccessFlags.Read | AccessFlags.Write;
                        break;

                    default:
                        local = null;
                        flags = AccessFlags.None;
                        break;
                    }

                    if (local == null)
                    {
                        continue;
                    }
                    localFlags[local.Index] |= flags;
                }
            }
        }
Ejemplo n.º 5
0
        private void isNative(Block block)
        {
            if (block.Instructions.Count <= 5)
            {
                return;
            }
            if (block.FirstInstr.OpCode != OpCodes.Call)
            {
                return;
            }
            switchBlock = block;
            native      = true;

            //set the local to a variable to compare to later
            localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]);
        }
Ejemplo n.º 6
0
        private void isSwitchBlock(Block block)
        {
            if (block.Instructions.Count <= 6)
            {
                return;
            }
            if (!block.FirstInstr.IsLdcI4())
            {
                return;
            }
            //check to see if its confuserex switch block

            switchBlock = block;
            //set the local to a variable to compare to later
            localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]);
        }
Ejemplo n.º 7
0
        protected override bool Deobfuscate(Block block)
        {
            bool modified     = false;
            var  instructions = block.Instructions;

            for (int i = 0; i < instructions.Count; i++)
            {
                var instr = instructions[i];
                switch (instr.OpCode.Code)
                {
                // Xenocode generates stloc + ldloc (bool). Replace it with dup + stloc. It will eventually
                // become dup + pop and be removed.
                case Code.Stloc:
                case Code.Stloc_S:
                case Code.Stloc_0:
                case Code.Stloc_1:
                case Code.Stloc_2:
                case Code.Stloc_3:
                    if (i + 1 >= instructions.Count)
                    {
                        break;
                    }
                    if (!instructions[i + 1].IsLdloc())
                    {
                        break;
                    }
                    var local = Instr.GetLocalVar(locals, instr);
                    if (local.Type.ElementType != ElementType.Boolean)
                    {
                        continue;
                    }
                    if (local != Instr.GetLocalVar(locals, instructions[i + 1]))
                    {
                        break;
                    }
                    instructions[i]     = new Instr(OpCodes.Dup.ToInstruction());
                    instructions[i + 1] = instr;
                    modified            = true;
                    break;

                default:
                    break;
                }
            }

            return(modified);
        }
Ejemplo n.º 8
0
        void isExpressionBlock(Block block)
        {
            if (block.Instructions.Count < 7)
            {
                return;
            }
            if (!block.FirstInstr.IsStloc())
            {
                return;
            }
            //we check to see if the switch block is confuserex cflow expression

            switchBlock = block;
            //set the local to a variable to compare to later
            localSwitch = Instr.GetLocalVar(blocks.Method.Body.Variables.Locals, block.Instructions[block.Instructions.Count - 4]);
            return;
        }
Ejemplo n.º 9
0
        //		ldloc N
        //		br swblk
        // or
        //		stloc N
        //		ldloc N
        //		br swblk
        bool DeobfuscateTos_Ldloc(IList <Block> switchTargets, Block switchFallThrough, Block block)
        {
            if (IsLdlocBranch(block, false))
            {
                var switchVariable = Instr.GetLocalVar(blocks.Locals, block.Instructions[0]);
                if (switchVariable == null)
                {
                    return(false);
                }
                return(DeobfuscateLdloc(switchTargets, switchFallThrough, block, switchVariable));
            }
            else if (IsStLdlocBranch(block, false))
            {
                return(DeobfuscateStLdloc(switchTargets, switchFallThrough, block));
            }

            return(false);
        }
Ejemplo n.º 10
0
        bool IsSwitchType2(Block switchBlock)
        {
            Local local = null;

            foreach (var instr in switchBlock.Instructions)
            {
                if (!instr.IsLdloc())
                {
                    continue;
                }
                local = Instr.GetLocalVar(blocks.Locals, instr);
                break;
            }
            if (local == null)
            {
                return(false);
            }

            foreach (var source in switchBlock.Sources)
            {
                var instrs = source.Instructions;
                for (int i = 1; i < instrs.Count; i++)
                {
                    var ldci4 = instrs[i - 1];
                    if (!ldci4.IsLdcI4())
                    {
                        continue;
                    }
                    var stloc = instrs[i];
                    if (!stloc.IsStloc())
                    {
                        continue;
                    }
                    if (Instr.GetLocalVar(blocks.Locals, stloc) != local)
                    {
                        continue;
                    }

                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 11
0
        Dictionary <Local, int> GetBccLocalConstants(Block block)
        {
            var dict   = new Dictionary <Local, int>();
            var instrs = block.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.IsStloc())
                {
                    var local = Instr.GetLocalVar(blocks.Locals, instr);
                    if (local == null)
                    {
                        continue;
                    }
                    var ldci4 = i == 0 ? null : instrs[i - 1];
                    if (ldci4 == null || !ldci4.IsLdcI4())
                    {
                        dict.Remove(local);
                    }
                    else
                    {
                        dict[local] = ldci4.GetLdcI4Value();
                    }
                }
                else if (instr.IsLdloc())
                {
                    var local = Instr.GetLocalVar(blocks.Locals, instr);
                    if (local != null)
                    {
                        dict.Remove(local);
                    }
                }
                else if (instr.OpCode.Code == Code.Ldloca || instr.OpCode.Code == Code.Ldloca_S)
                {
                    var local = instr.Operand as Local;
                    if (local != null)
                    {
                        dict.Remove(local);
                    }
                }
            }
            return(dict);
        }
Ejemplo n.º 12
0
        bool RemoveDeadStores()
        {
            bool modified = false;

            foreach (var block in allBlocks)
            {
                var instructions = block.Instructions;
                for (int i = 0; i < instructions.Count; i++)
                {
                    var   instr = instructions[i];
                    Local local;
                    switch (instr.OpCode.Code)
                    {
                    case Code.Stloc:
                    case Code.Stloc_S:
                    case Code.Stloc_0:
                    case Code.Stloc_1:
                    case Code.Stloc_2:
                    case Code.Stloc_3:
                        local = Instr.GetLocalVar(blocks.Locals, instr);
                        break;

                    default:
                        continue;
                    }

                    if (local == null)
                    {
                        continue;
                    }
                    if (!deadLocals[local.Index])
                    {
                        continue;
                    }
                    instructions[i] = new Instr(OpCodes.Pop.ToInstruction());
                    modified        = true;
                }
            }

            return(modified);
        }
Ejemplo n.º 13
0
        bool DeobfuscateStLdloc(Block switchBlock)
        {
            bool modified = false;

            var switchVariable = Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[0]);

            if (switchVariable == null)
            {
                return(modified);
            }

            if (switchBlock.Targets == null)
            {
                return(modified);
            }
            var targets = new List <Block>(switchBlock.Targets);

            modified |= DeobfuscateStLdloc(targets, switchBlock.FallThrough, switchBlock);

            return(modified);
        }
        void Initialize()
        {
            foreach (var variable in locals)
            {
                variableToValue[variable] = new Variable();
            }

            foreach (var block in allBlocks)
            {
                for (int i = 0; i < block.Instructions.Count; i++)
                {
                    var instr = block.Instructions[i];

                    switch (instr.OpCode.Code)
                    {
                    case Code.Stloc:
                    case Code.Stloc_S:
                    case Code.Stloc_0:
                    case Code.Stloc_1:
                    case Code.Stloc_2:
                    case Code.Stloc_3:
                        var variable = Instr.GetLocalVar(locals, instr);
                        var val      = variableToValue[variable];
                        val.AddWrite();
                        object obj;
                        if (!GetValue(block, i, out obj))
                        {
                            val.SetUnknown();
                        }
                        val.Value = obj;
                        break;

                    default:
                        break;
                    }
                }
            }
        }
Ejemplo n.º 15
0
        public bool Deobfuscate(List <Block> methodBlocks)
        {
            List <Block> switchBlocks  = GetSwitchBlocks(methodBlocks); // blocks that contain a switch
            int          modifications = 0;

            foreach (Block switchBlock in switchBlocks)
            {
                if (switchBlock.SwitchData.IsKeyHardCoded)
                {
                    ProcessHardcodedSwitch(switchBlock);
                    modifications++;
                    continue;
                }

                _switchKey = Instr.GetLocalVar(_blocks.Locals,
                                               switchBlock.Instructions[switchBlock.Instructions.Count - 4]);

                if (DeobfuscateSwitchBlock(methodBlocks, switchBlock))
                {
                    modifications++;
                }
            }
            return(modifications > 0);
        }
Ejemplo n.º 16
0
        protected override bool Deobfuscate(Block block)
        {
            ins = ControlFlowRemover.Inemu;
            var modified = false;

            //		var blocks2 = blocks.MethodBlocks.GetAllBlocks();


            if (block.LastInstr.OpCode != OpCodes.Switch)
            {
                return(false);
            }
            if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
            {
            }
            if (block.Instructions.Count <= 4)
            {
                return(false);
            }
            if (block.Instructions[block.Instructions.Count - 4].IsStloc())
            {
                if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
                {
                }
                //		return false;
                var baseBlocksParent = block.Parent;
                var abc = baseBlocksParent.GetAllBlocks()[0].Instructions;

                foreach (var blockInstruction in abc)
                {
                    if (blockInstruction.IsStloc())
                    {
                        if (blockInstruction.Instruction.GetLocal(blocks.Method.Body.Variables).Type ==
                            blocks.Method.Module.CorLibTypes.UInt32)
                        {
                            loc = blockInstruction.Instruction.GetLocal(blocks.Locals);
                            ins.Emulate(abc);
                            break;
                        }
                    }
                }

                //    return false;

                swlocal = Instr.GetLocalVar(blocks.Locals, block.Instructions[block.Instructions.Count - 4]);

                swBlock = block;

                modified = doit(block);
            }
            else if (!block.Instructions[block.Instructions.Count - 4].IsStloc() &&
                     block.Instructions[block.Instructions.Count - 2].OpCode != OpCodes.Nop)
            {
                //		return false;
                if (blocks.Method.MDToken.ToInt32() == 0x060000CC)
                {
                }
                var baseBlocksParent = block.Parent;
                var abc = baseBlocksParent.GetAllBlocks()[0].Instructions;

                foreach (var blockInstruction in abc)
                {
                    if (blockInstruction.IsStloc())
                    {
                        loc = blockInstruction.Instruction.GetLocal(blocks.Locals);
                        ins.Emulate(abc);
                        break;
                    }
                }

                //    return false;

                swlocal = null;

                swBlock = block;

                modified = doit(block);
            }

            return(modified);
        }
Ejemplo n.º 17
0
        bool Remove(Blocks blocks, Block block)
        {
            var       instrs            = block.Instructions;
            const int numInstrsToRemove = 11;

            if (instrs.Count < numInstrsToRemove)
            {
                return(false);
            }
            int startIndex = instrs.Count - numInstrsToRemove;
            int index      = startIndex;

            if (instrs[index++].OpCode.Code != Code.Ldtoken)
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)"))
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.Reflection.Assembly System.Type::get_Assembly()"))
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.Reflection.AssemblyName System.Reflection.Assembly::GetName()"))
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.Byte[] System.Reflection.AssemblyName::GetPublicKeyToken()"))
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.String System.Convert::ToBase64String(System.Byte[])"))
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Ldstr)
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.String", "(System.String,System.String)"))
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Ldstr)
            {
                return(false);
            }
            if (!CheckCall(instrs[index++], "System.Boolean System.String::op_Inequality(System.String,System.String)"))
            {
                return(false);
            }
            if (!instrs[index++].IsBrfalse())
            {
                return(false);
            }

            var badBlock  = block.FallThrough;
            var goodblock = block.Targets[0];

            if (badBlock == null)
            {
                return(false);
            }

            if (badBlock == goodblock)
            {
                // All of the bad block was removed by the cflow deobfuscator. It was just a useless
                // calculation (div by zero).
                block.ReplaceLastInstrsWithBranch(numInstrsToRemove, goodblock);
            }
            else if (badBlock.Sources.Count == 1)
            {
                instrs = badBlock.Instructions;
                if (instrs.Count != 12)
                {
                    return(false);
                }
                index = 0;
                if (!instrs[index++].IsLdcI4())
                {
                    return(false);
                }
                if (!instrs[index].IsStloc())
                {
                    return(false);
                }
                var local = Instr.GetLocalVar(blocks.Locals, instrs[index++]);
                if (local == null)
                {
                    return(false);
                }
                if (!CheckLdloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }
                if (!CheckLdloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }
                if (instrs[index++].OpCode.Code != Code.Sub)
                {
                    return(false);
                }
                if (instrs[index++].OpCode.Code != Code.Conv_U1)
                {
                    return(false);
                }
                if (!CheckStloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }
                if (!CheckLdloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }
                if (!CheckLdloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }
                if (instrs[index++].OpCode.Code != Code.Div)
                {
                    return(false);
                }
                if (instrs[index++].OpCode.Code != Code.Conv_U1)
                {
                    return(false);
                }
                if (!CheckStloc(blocks.Locals, instrs[index++], local))
                {
                    return(false);
                }

                block.ReplaceLastInstrsWithBranch(numInstrsToRemove, goodblock);
                badBlock.Parent.RemoveDeadBlock(badBlock);
            }
            else
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 18
0
        public void Deobfuscate(Blocks blocks)
        {
            var instrsToRemove = new List <int>();

            foreach (var block in blocks.MethodBlocks.GetAllBlocks())
            {
                instrsToRemove.Clear();
                var instrs = block.Instructions;
                for (int i = 0; i < instrs.Count; i++)
                {
                    var           instr = instrs[i];
                    int           indexToRemove;
                    ITypeDefOrRef type;
                    Local         local = null;

                    if (instr.OpCode.Code == Code.Newobj)
                    {
                        if (i + 1 >= instrs.Count)
                        {
                            continue;
                        }
                        var ctor = instr.Operand as IMethod;
                        if (ctor == null || ctor.DeclaringType == null)
                        {
                            continue;
                        }
                        if (ctor.Name != ".ctor")
                        {
                            continue;
                        }

                        var next = instrs[i + 1];
                        if (!next.IsStloc() && !next.IsLeave() && next.OpCode.Code != Code.Pop)
                        {
                            continue;
                        }

                        indexToRemove = i;
                        type          = ctor.DeclaringType;
                        if (next.IsStloc())
                        {
                            local = Instr.GetLocalVar(blocks.Locals, next);
                        }
                    }
                    else if (instr.OpCode.Code == Code.Ldfld)
                    {
                        if (i == 0)
                        {
                            continue;
                        }
                        var ldloc = instrs[i - 1];
                        if (!ldloc.IsLdloc())
                        {
                            continue;
                        }

                        var field = instr.Operand as IField;
                        if (field == null || field.DeclaringType == null)
                        {
                            continue;
                        }

                        indexToRemove = i;
                        type          = field.DeclaringType;
                        local         = Instr.GetLocalVar(blocks.Locals, ldloc);
                    }
                    else
                    {
                        continue;
                    }

                    if (type == null)
                    {
                        continue;
                    }
                    var info = typeToInfo.Find(type);
                    if (info == null)
                    {
                        continue;
                    }

                    info.referenced = true;
                    instrsToRemove.Add(indexToRemove);
                    if (local != null)
                    {
                        local.Type = info.localType;
                    }
                }
                if (instrsToRemove.Count > 0)
                {
                    block.Remove(instrsToRemove);
                }
            }
        }
Ejemplo n.º 19
0
        bool FindFirstBlocks(Block block, TamperBlocks tamperBlocks, IList <Block> allBlocks, IList <Local> locals)
        {
            if (!block.LastInstr.IsBrfalse())
            {
                return(false);
            }

            /*
             * ldc.i4.0
             * stloc X
             * call GetExecutingAssembly()
             * stloc Y
             * ldloc Y
             * callvirt Location
             * ldc.i4.1
             * ldloca X
             * call StrongNameSignatureVerificationEx
             * pop / brfalse bad_code
             * ldloc X
             * brfalse bad_code
             * ldloc Y
             * callvirt FullName()
             * ldstr "......"
             * callvirt EndsWith(string)
             * brfalse bad_code / brtrue good_code
             */

            var     instrs = block.Instructions;
            int     end    = instrs.Count - 1;
            Instr   instr;
            IMethod method;

            tamperBlocks.type = Type.V1;

            int index = 0;

            int start = FindCallMethod(block, index, true, (calledMethod) => calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()");

            if (start < 0)
            {
                return(false);
            }
            index = start + 1;
            instr = instrs[--start];
            if (!instr.IsStloc())
            {
                return(false);
            }
            var loc0 = Instr.GetLocalVar(locals, instr);

            instr = instrs[--start];
            if (!instr.IsLdcI4())
            {
                return(false);
            }

            index = FindCallMethod(block, index, false, (calledMethod) => calledMethod.ToString() == "System.String System.Reflection.Assembly::get_Location()");
            if (index < 0)
            {
                return(false);
            }
            index++;

            index = FindCallMethod(block, index, false, (calledMethod) => {
                tamperBlocks.pinvokeMethod = DotNetUtils.GetMethod(module, calledMethod);
                return(DotNetUtils.IsPinvokeMethod(tamperBlocks.pinvokeMethod, "mscorwks", "StrongNameSignatureVerificationEx"));
            });
            if (index < 0)
            {
                return(false);
            }
            index++;

            if (!instrs[index].IsBrfalse())
            {
                if (instrs[index].OpCode.Code != Code.Pop)
                {
                    return(false);
                }
                instr = instrs[index + 1];
                if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0)
                {
                    return(false);
                }
                if (!instrs[index + 2].IsBrfalse())
                {
                    return(false);
                }

                tamperBlocks.type  = Type.V1;
                tamperBlocks.first = new BlockInfo {
                    Block = block,
                    Start = start,
                    End   = end,
                };
            }
            else
            {
                tamperBlocks.type  = Type.V2;
                tamperBlocks.first = new BlockInfo {
                    Block = block,
                    Start = start,
                    End   = end,
                };

                block = block.FallThrough;
                if (block == null)
                {
                    return(false);
                }
                instrs = block.Instructions;
                index  = 0;
                instr  = instrs[index];
                if (!instr.IsLdloc() || Instr.GetLocalVar(locals, instr) != loc0)
                {
                    return(false);
                }
                if (!instrs[index + 1].IsBrfalse())
                {
                    return(false);
                }
            }

            block  = block.FallThrough;
            instrs = block.Instructions;
            start  = end = 0;

            instr = instrs[end++];
            if (!instr.IsLdloc())
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Callvirt)
            {
                return(false);
            }
            method = instr.Operand as IMethod;
            if (method == null || method.ToString() != "System.String System.Reflection.Assembly::get_FullName()")
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Ldstr)
            {
                return(false);
            }

            instr = instrs[end++];
            if (instr.OpCode != OpCodes.Callvirt)
            {
                return(false);
            }
            method = instr.Operand as IMethod;
            if (method == null || method.ToString() != "System.Boolean System.String::EndsWith(System.String)")
            {
                return(false);
            }

            instr = instrs[end++];
            if (!instr.IsBrfalse() && !instr.IsBrtrue())
            {
                return(false);
            }

            end--;
            tamperBlocks.second = new BlockInfo {
                Block = block,
                Start = start,
                End   = end,
            };

            return(true);
        }