private void btnOK_Click(object sender, EventArgs e)
        {
            switch (btnOK.Text)
            {
                case Consts.Stop:
                    _isCancelPending = true;
                    return;
                default:
                    break;
            }

            string outputDir = txtOutputDir.Text;
            if (!Directory.Exists(outputDir))
            {
                SimpleMessage.ShowInfo("Please choose output directory.");
                return;
            }

            if (_sourceDir != null && _sourceDir.Equals(outputDir))
                Config.DeobfOutputDir = String.Empty;
            else
                Config.DeobfOutputDir = outputDir;

            Config.DeobfFlowOptionBranchLoopCount = (int)nudLoopCount.Value;
            Config.DeobfFlowOptionMaxRefCount = (int)nudMaxRefCount.Value;
            Config.LastRegex = txtRegex.Text;
            Config.DeobfProfile = cboProfile.SelectedIndex;
            Config.DeobfFlowOptionBranchDirection = cboDirection.SelectedIndex;

            try
            {
                btnOK.Text = Consts.Stop;
                _isCancelPending = false;

                Utils.EnableUI(this.Controls, false);

                DeobfOptions options = GetOptions();
                _host.TextInfo = options;
                Deobfuscator deobf = new Deobfuscator(options);
                deobf.Go();

                List<DeobfError> errors = deobf.Errors;
                if (errors.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach(DeobfError error in errors) 
                    {
                        sb.Append(error.ToString());
                        sb.Append("\r\n\r\n");
                    }
                    SimpleMessage.ShowError(sb.ToString());
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                _host.TextInfo = null;
                btnOK.Text = Consts.OK;

                Utils.EnableUI(this.Controls, true);
            }
        }
        private void CheckCustomAttributes(List<string> errors,
            TypeDefinition sourceTd,
            TypeDefinition targetTd,
            Deobfuscator deobf)
        {
            if (sourceTd.CustomAttributes.Count > 0)
            {
                for (int i = 0; i < sourceTd.CustomAttributes.Count; i++)
                {
                    CustomAttribute ca = sourceTd.CustomAttributes[i];
                    
                    for (int j = 0; j < ca.ConstructorArguments.Count; j++)
                    {
                        CustomAttributeArgument caa = ca.ConstructorArguments[j];
                        TypeDefinition valueType = caa.Value as TypeDefinition;
                        if (caa.Type.FullName == "System.Type" && IsRenameMe(valueType.Name))
                        {
                            string targetTypeName = GetTargetTypeName(deobf, valueType);
                            TypeDefinition targetValueType = targetTd.CustomAttributes[i].ConstructorArguments[j].Value as TypeDefinition;
                            if (targetTypeName != targetValueType.FullName)
                            {
                                errors.Add(String.Format("Unmatched custom attribute type \"{0}\"->\"{1}\".", valueType.FullName, targetValueType.FullName));
                            }
                        }
                    }

                    for (int j = 0; j < ca.Fields.Count; j++)
                    {
                        CustomAttributeNamedArgument cana = ca.Fields[j];
                        if (IsRenameMe(cana.Name))
                        {
                            string targetName = targetTd.CustomAttributes[i].Fields[j].Name;
                            if (cana.Name == targetName)
                            {
                                errors.Add(String.Format("Unrenamed custom attribute named argument found \"{0}\".", cana.Name));
                            }
                        }
                    }

                    for (int j = 0; j < ca.Properties.Count; j++)
                    {
                        CustomAttributeNamedArgument cana = ca.Properties[j];
                        if (IsRenameMe(cana.Name))
                        {
                            string targetName = targetTd.CustomAttributes[i].Properties[j].Name;
                            if (cana.Name == targetName)
                            {
                                errors.Add(String.Format("Unrenamed custom attribute named argument found \"{0}\".", cana.Name));
                            }
                        }
                    }

                    continue;
                }
            }

        }
        public void cmDeobf_Click(object sender, EventArgs e)
        {
            if (_currentMethod == null) return;

            if (_frmDeobfMethod == null)
            {
                _frmDeobfMethod = new frmDeobfMethod(_currentMethod);
            }
            else
            {
                _frmDeobfMethod.InitForm(_currentMethod);
            }

            if (_frmDeobfMethod.ShowDialog() != DialogResult.OK) return;

            bool resolveDirAdded = false;
            SimpleWaitCursor wc = new SimpleWaitCursor();
            try
            {
                resolveDirAdded = _form.Host.AddAssemblyResolveDir(_form.SourceDir);

                AssemblyDefinition ad = _currentMethod.DeclaringType.Module.Assembly;
                string file = null;
                foreach (TreeNode n in _form.TreeView.Nodes)
                {
                    if (ad.Equals(n.Tag))
                    {
                        file = _form.TreeViewHandler.GetTreeNodeText(n);
                        break;
                    }
                }

                if (file == null)
                    return;
                
                file = Path.Combine(_form.SourceDir, file);
                if (String.IsNullOrEmpty(file) || !File.Exists(file))
                {
                    throw new ApplicationException("Cannot find assembly file: " + file);
                }
                

                DeobfOptions options = new DeobfOptions();
                options.Clear();

                options.Host = _form.Host;
                options.Rows = new string[] { file };
                options.SourceDir = _form.SourceDir;
                options.OutputDir = _form.SourceDir;
                options.BranchDirection = _frmDeobfMethod.BranchDirection;

                options.LoopCount = Config.DeobfFlowOptionBranchLoopCount;
                options.MaxRefCount = Config.DeobfFlowOptionMaxRefCount;
                options.MaxMoveCount = Config.DeobfFlowOptionMaxMoveCount;

                options.chkPatternChecked = _frmDeobfMethod.AutoFlowPattern;
                options.chkBranchChecked = _frmDeobfMethod.AutoFlowBranch;
                options.chkCondBranchDownChecked = _frmDeobfMethod.AutoFlowConditionalBranchDown;
                options.chkCondBranchUpChecked = _frmDeobfMethod.AutoFlowConditionalBranchUp;
                
                options.chkSwitchChecked = _frmDeobfMethod.AutoFlowSwitch;
                options.chkUnreachableChecked = _frmDeobfMethod.AutoFlowUnreachable;
                options.chkRemoveExceptionHandlerChecked = _frmDeobfMethod.AutoFlowExceptionHandler;
                options.chkBoolFunctionChecked = _frmDeobfMethod.AutoFlowBoolFunction;
                options.chkDelegateCallChecked = _frmDeobfMethod.AutoFlowDelegateCall;
                options.chkDirectCallChecked = _frmDeobfMethod.AutoFlowDirectCall;
                options.chkBlockMoveChecked = _frmDeobfMethod.AutoFlowBlockMove;
                options.chkReflectorFixChecked = _frmDeobfMethod.AutoFlowReflectorFix;
                options.chkRemoveInvalidInstructionChecked = _frmDeobfMethod.AutoFlowRemoveInvalidInstruction;

                options.chkAutoStringChecked = _frmDeobfMethod.AutoString || _frmDeobfMethod.SelectedMethod != null;
                options.StringOptionSearchForMethod = _frmDeobfMethod.SelectedMethod;

                options.PluginList = _frmDeobfMethod.PluginList;
                options.chkInitLocalVarsChecked = _frmDeobfMethod.InitLocalVars;

                Deobfuscator deobf = new Deobfuscator(options);
                int deobfCount = deobf.DeobfMethod(file, _currentMethod);
                
                if (deobfCount > 0)
                {
                    InitBody(_currentMethod);
                }

                //need to be after InitBody
                _form.SetStatusCount(deobfCount);

            }
            catch (Exception ex)
            {
                SimpleMessage.ShowException(ex);
                InitBody(_currentMethod);
            }
            finally
            {
                if (resolveDirAdded)
                    _form.Host.RemoveAssemblyResolveDir(_form.SourceDir);
                wc.Dispose();
            }
        }
 private string GetTargetTypeName(Deobfuscator deobf, TypeDefinition sourceTd)
 {
     return String.Format("NS001.{0}", deobf.GetNewTypeName(sourceTd));
 }
        public void cmDeobfBranch_Click(object sender, EventArgs e)
        {
            if (dgBody.SelectedRows == null || dgBody.SelectedRows.Count != 1) return;
            int insIndex = GetInstructionIndex(dgBody.SelectedRows[0]);
            if (insIndex >= 0)
            {
                Instruction ins = _currentMethod.Body.Instructions[insIndex];

                Deobfuscator deobf = new Deobfuscator();
                if (_frmDeobfMethod != null)
                {
                    deobf.Options.BranchDirection = _frmDeobfMethod.BranchDirection;
                }

                if (DeobfUtils.IsDirectJumpInstruction(ins))
                {
                    deobf.DeobfFlowBranch(_currentMethod, insIndex, insIndex, 0, 0);
                }
                else if (DeobfUtils.IsConditionalJumpInstruction(ins))
                {
                    deobf.Options.chkCondBranchDownChecked = true;
                    deobf.Options.chkCondBranchUpChecked = true;
                    deobf.DeobfFlowConditionalBranch(_currentMethod, insIndex, insIndex, 0);
                }
                else if (ins.OpCode.Code == Code.Switch)
                {
                    deobf.DeobfFlowSwitch(_currentMethod, insIndex, insIndex);
                }
                InitBody(_currentMethod);
            }
        }