zoukankan      html  css  js  c++  java
  • 批量数据替换助手V1.0版发布

          前段时间网站被挂马,数据库表中很多文本字段都被加上了一段js脚本。修复完程序漏洞之后便开始着手清理这些被注入的数据,其间参考了一些网上的方法,大都是写一个存储过程进行一个表一个表逐一清理。这种方法操作繁琐,而且一般不是很懂数据库的人很难操作。于是萌发了要写一个小程序的念头,经过两天时间的折腾这个小软件终于和各位见面了,希望各位童鞋多给点意见。说了这么些之后还是先上界面吧,^..^

    现在就来说说这个小程序的开发思路吧。
    第一步:通过 sp_helpdb系统存储过程得到SqlServer中的所有数据库名称。

    View Code
    #region 测试数据库连接,并显示数据库列表
    /// <summary>
    /// 测试数据库连接,并显示数据库列表
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnTest_Click(object sender, EventArgs e)
    {
    this.btnTest.Enabled = false;
    saveConfig();

    ConfigInfo.Server = this.txtIP.Text.Trim();
    ConfigInfo.DataBase = "master";
    ConfigInfo.UID = this.txtUID.Text.Trim();
    ConfigInfo.Pwd = this.txtPwd.Text.Trim();

    try
    {
    DataTable dt = Data.SqlHelper.ExecuteDataset(ConfigInfo.getConnect(), CommandType.Text, "sp_helpdb").Tables[0];

    this.cmbDataBaseList.DataSource = dt;
    this.cmbDataBaseList.DisplayMember = "name";
    this.cmbDataBaseList.SelectedIndex = 0;
    this.cmbDataBaseList.DropDownStyle = ComboBoxStyle.DropDownList;

    this.ExecuteFilterBtn.Enabled = true;
    }
    catch (Exception ex)
    {
    this.ExecuteFilterBtn.Enabled = false;
    MessageBox.Show(string.Format("错误:{0}!",ex.Message),"错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
    this.btnTest.Enabled = true;
    }
    }
    #endregion



    第二步:当选择某个数据库时得到数据库里面的所有表信息,通过下面Sql语句就可以查询到了。
    select [name] from sysobjects where xtype='u' order by [name] asc

    View Code
    #region 当选择不同的数据库时,读取数据库的表信息
    /// <summary>
    /// 当选择不同的数据库时,读取数据库的表信息
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
    this.chkboxTableList.Items.Clear();
    ConfigInfo.DataBase = ((DataRowView)this.cmbDataBaseList.SelectedItem)["name"].ToString();
    DataSet ds = Data.SqlHelper.ExecuteDataset(ConfigInfo.getConnect(), CommandType.Text, "select [name] from sysobjects where xtype='u' order by [name] asc");

    foreach (DataRow row in ds.Tables[0].Rows)
    {
    this.chkboxTableList.Items.Add(row["name"].ToString());
    }
    }
    #endregion



    第三步:当点击替换按钮时获取被选中表的信息,并遍历表中的行列信息,并进行查找替换。

    View Code
     #region 执行批量替换操作
    /// <summary>
    /// 执行批量替换操作
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ExecuteFilterBtn_Click(object sender, EventArgs e)
    {
    saveConfig();
    total = 0;
    if (this.chkboxTableList.CheckedIndices.Count == 0) return; //没有选中任何表的情况
    if (this.txtSearchKey.Text.Trim() == "")
    {
    DialogResult result = MessageBox.Show("当前查找内容为空,确认此操作?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
    if (result == DialogResult.No) return;
    }

    this.ExecuteFilterBtn.Enabled = false;

    List<TableInfo> tabList = new List<TableInfo>();
    string searchString = this.txtSearchKey.Text.Trim() == "" ? " " : this.txtSearchKey.Text;
    string replaceString = this.txtReplaceStr.Text;
    KeyType kt = this.chkIsRegex.Checked == true ? KeyType.Regex : KeyType.Text;
    bool isRegex = this.chkIsRegex.Checked;

    //得到被选中表的基本信息,并添加到集合中
    foreach (int index in this.chkboxTableList.CheckedIndices)
    {
    string tabName = this.chkboxTableList.Items[index].ToString();
    TableInfo tInfo = FilterInfo.initTableInfo(tabName);
    if (tInfo == null)
    {
    continue;
    }
    tabList.Add(tInfo);
    }

    try
    {
    if (tabList.Count == 0) return; //没有符合检测的数据表

    pBar1.Visible = true;
    pBar1.Minimum = 1;
    pBar1.Maximum = tabList.Count;
    pBar1.Value = 1;
    pBar1.Step = 1;

    //循环过滤表中要替换的数据
    foreach (TableInfo info in tabList)
    {
    FilterInfo.Execute(info, searchString, replaceString, kt);
    pBar1.PerformStep(); //进度条
    }
    }
    catch (Exception ex)
    {
    MessageBox.Show(string.Format("异常:{0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
    }
    finally
    {
    this.ExecuteFilterBtn.Enabled = true;
    }

    MessageBox.Show(string.Format("数据替换完毕,共有{0}行数据被修改!",total),"消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    #endregion

    以上就是整个大致思路,详情可以参看源代码。

    附带一些操作截图,希望大家可以看的更清楚一些。

    这个就是被注入的数据,当然实际的会有区别。

    编写查找内容,并启用正则匹配功能。

    哈哈,数据终于恢复原貌!!

    源程序下载地址:http://dl.dbank.com/c0qh0l03dc

  • 相关阅读:
    SRM 441(1-250pt, 1-500pt)
    SRM 387(1-250pt)
    SRM 388(1-250pt)
    SRM 389(1-250pt)
    SRM 601(1-250pt,500pt)
    SRM 409(1-250pt, 1-500pt)
    SRM 408(1-250pt, 1-500pt)
    unique() 去重函数
    poj3468(A Simple Problem with Integers)
    HDU1394(Minimum Inversion Number)
  • 原文地址:https://www.cnblogs.com/huangzelin/p/2198047.html
Copyright © 2011-2022 走看看