C#Access数据库工具及密码破解修改
没有数据的程序是没有灵魂的程序,没有数据库的程序或许很NB。数据库的种类面试的时候都回答过,大一点的需要环境,小一点的不好调试,谁用谁知道。Acces作为windows的亲生数据库,组件集成到系统里,工具合并到Office中,核心就在“mdb”这种后缀名的文件里。表格化的数据电脑的思维,
一、mdb文件遇到的麻烦
开发容易,看数据难
假如运行的电脑上没有安装Microsoft全家桶里的Access,mdb文件的数据就看不到,而且不能编辑。既然是微软的,那就应当可以开发一个简单的access数据库工具,实现简单的增删改查,还有密码破解
二、对标 Microsoft Access 功能
2.1 对 Access 数据库文件的增删改查
连接字符串,select,delete,insert,update
2.2 界面好操作,就像 Excell 一样的增删改查
DataGridView 就是王道。双击选择table,能生成连接字符串,各种排序,复制列字段,自定义筛选条件,批量更新表,显示操作的行列索引,右键设置需要显示哪些列,像Sql server 编辑前两百行一样和编辑和新增
2.3 单独的一个 exe 工具,不需要安装,也不需要环境
划重点,这里的环境是framework环境,用最低的2.0,xp也能用
2.4 破解密码,改密码
其实很简单
2.5 这个是不是还能对标 SQL Server
功能完全一样,就是字符串连接不一样而已,有兴趣的留言
三、详细设计
3.1 主程序代码
using System;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using RegisterSpace;
namespace tempJH0116
{
public partial class Form1 : Form
{
string strDBConn = "";
OleDbDataAdapter DBAdapter;
OleDbConnection OleConn;
DataTable tbDBSource = new DataTable();
BindingSource bs = new BindingSource();//数据源
Label labelX;
public Form1()
{
InitializeComponent();
InitX();
OpenControlDoubleBuffered(dataGridView1);
OpenControlDoubleBuffered(splitter1);
if (Program.strDropFilePath != null)
{
txtFilePath.Text = Program.strDropFilePath;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("数据库编辑器退出 确定吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
}
else
{
e.Cancel = true;
}
}
private void btnLink_Click(object sender, EventArgs e)
{
string filePath = txtFilePath.Text;
string password = txtPwd.Text;
try
{
strDBConn = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Persist Security Info=False;Jet OLEDB:Database Password={password}";
OleConn = new OleDbConnection(strDBConn);
OleConn.Open();
}
catch (Exception)
{
MessageBox.Show("文件配置错误!");
return;
}
txtLinkStr.Text = strDBConn;
DataTable tbDB = OleConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
tbDB.DefaultView.Sort = "TABLE_NAME ASC";
tbDB = tbDB.DefaultView.ToTable();
dataGridView1.DataSource = tbDB;
treeList.Nodes.Clear();
for (int i = 0; i < tbDB.Rows.Count; i++)
{
treeList.Nodes.Add(tbDB.Rows[i][2].ToString());
}
txtPwd.ReadOnly = true;
btnLink.Enabled = false;
btnGetPwd.Enabled = false;
txtFilePath.AllowDrop = false;
string name = txtFilePath.Text.Substring(txtFilePath.Text.LastIndexOf('\\') + 1);
txtDBName.Text = name;
}
private void treeList_DoubleClick(object sender, EventArgs e)
{
txtFilter.Text = "";
TreeNode selectTable = treeList.SelectedNode;
//if (selectTable.Level != 1) return;
txtTableName.Text = selectTable.Text;
txtShow.Text = "【" + selectTable.Text + "】";
string strAllTable = $"Select * From [{txtTableName.Text}]";
DBAdapter = new OleDbDataAdapter(strAllTable, OleConn);//【】不需要数据库名称也可以
txtStrExec.Text = strAllTable;
//txtLinkStr.Text = strDBConn;
tbDBSource = new DataTable();
DBAdapter.Fill(tbDBSource);
bs.DataSource = tbDBSource;
man.BindingSource = bs;
dataGridView1.DataSource = bs;
txtInfo.Text = $"共{tbDBSource.Rows.Count}行/共{tbDBSource.Columns.Count}列";
cbAllowEdit.Checked = false;
cbAllowEdit_CheckedChanged(null, null);
cbAllowSort.Checked = false;
cbAllowSort_CheckedChanged(null, null);
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentCell == null) return;
dataGridView1.BeginEdit(true);
DataGridViewCell d = dataGridView1.CurrentCell;
string col = d.OwningColumn.HeaderText;
txtFilter.Text = col + "='" + d.Value.ToString() + "'";
txtStatusNow.Text = $"当前单元格索引({d.RowIndex},{d.ColumnIndex})";
}
private void cbAllowEdit_CheckedChanged(object sender, EventArgs e)
{
dataGridView1.ReadOnly = !cbAllowEdit.Checked;
btnSave.Enabled = cbAllowEdit.Checked;
if (cbAllowEdit.Checked)
cbAllowEdit.ForeColor = Color.Red;
else
cbAllowEdit.ForeColor = DefaultForeColor;
}
private void cbAllowSort_CheckedChanged(object sender, EventArgs e)
{
if (cbAllowSort.Checked)
{
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.Automatic;
}
}
else
{
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.Programmatic;
}
tbDBSource = tbDBSource.Copy();
bs.DataSource = tbDBSource;
dataGridView1.DataSource = bs;//取消排序效果
}
}
private void btnFilter_Click(object sender, EventArgs e)
{
//tbDBSource.DefaultView.RowFilter = txtFilter.Text;
bs.Filter = txtFilter.Text;
}
private void splitter1_Click(object sender, EventArgs e)
{
groupBox2.Visible = !groupBox2.Visible;
if (!groupBox2.Visible)
{
splitter1.Cursor = Cursors.PanEast;
this.toolTip1.SetToolTip(this.splitter1, "单击显示对象资源管理器");
}
else
{
splitter1.Cursor = Cursors.VSplit;
this.toolTip1.SetToolTip(this.splitter1, "单击隐藏对象资源管理器");
}
}
private void btnSave_Click(object sender, EventArgs e)
{
tbDBSource = (DataTable)bs.DataSource;
if (tbDBSource.GetChanges() == null) return;
OleDbCommandBuilder sqlCommandBuilder = new OleDbCommandBuilder(DBAdapter);
int nowCount = 0;
try
{
nowCount = DBAdapter.Update(tbDBSource);
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
MessageBox.Show("更新了" + nowCount.ToString() + "行数据!");
//tbDBSource.AcceptChanges();
dataGridView1.Refresh();
}
private void 设置列ToolStripMenuItem_Click(object sender, EventArgs e)
{
FormColumnFilter formColumnFilter = new FormColumnFilter();
formColumnFilter.InitUI(dataGridView1);
formColumnFilter.ShowDialog();
}
public void OpenControlDoubleBuffered(Control ctr)
{
Type type = ctr.GetType();
PropertyInfo pi = type.GetProperty("DoubleBuffered",
BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(ctr, true, null);
}
public void InitX()
{
labelX = new Label();
labelX.Text = "×";
toolTip1.SetToolTip(labelX, "取消筛选条件");
labelX.AutoSize = true;
labelX.ForeColor = Color.Red;
labelX.Dock = DockStyle.Right;
labelX.Cursor = Cursors.Hand;
labelX.Click += ClearText;
txtFilter.Controls.Add(labelX);
txtFilter_TextChanged(null, null);
//textBox1_TextChanged(null, null);
}
public void ClearText(object sender, EventArgs e)
{
txtFilter.Text = "";
btnFilter_Click(null, null);
}
private void txtFilter_TextChanged(object sender, EventArgs e)
{
if (txtFilter.TextLength > 0)
labelX.Visible = true;
else
labelX.Visible = false;
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
dataGridView1_CellClick(null, null);
}
private void txtFilePath_DragDrop(object sender, DragEventArgs e)
{
txtFilePath.Text = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
}
private void txtFilePath_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
//如果拖进来的是文件类型
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] paths = e.Data.GetData(DataFormats.FileDrop) as string[];
//得到拖进来的路径
string path = paths[0];
//路径字符串长度不为空
if (path.Length > 1)
{
//判断是文件夹吗
FileInfo fil = new FileInfo(path);
if (fil.Attributes == FileAttributes.Directory)//文件夹
{
//鼠标图标链接
e.Effect = DragDropEffects.None;
}
else//文件
{
//鼠标图标禁止
e.Effect = DragDropEffects.Link;
}
}
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
private void btnGetPwd_Click(object sender, EventArgs e)
{
FormPwd f = new FormPwd();
f.Tag = txtFilePath.Text;
f.ShowDialog();
}
}
}
3.2 密码操作
private static string GetPassword(string file)
{ // 未加密的文件0x42开始至0x61之前的每间隔一字节的数值
byte[] baseByte = { 0xbe, 0xec, 0x65, 0x9c, 0xfe, 0x28, 0x2b, 0x8a, 0x6c, 0x7b, 0xcd, 0xdf, 0x4f, 0x13, 0xf7, 0xb1, };
byte flagByte = 0x0c; // 标志 0x62 处的数值
string password = "";
try
{
FileStream fs = File.OpenRead(file);
fs.Seek(0x14, SeekOrigin.Begin);
byte ver = (byte)fs.ReadByte(); // 取得版本, 1为Access2000, 0为Access97
fs.Seek(0x42, SeekOrigin.Begin);
byte[] bs = new byte[33];
if (fs.Read(bs, 0, 33) != 33) return "";
byte flag = (byte)(bs[32] ^ flagByte);
for (int i = 0; i < 16; i++)
{
byte b = (byte)(baseByte[i] ^ bs[i * 2]);
if (i % 2 == 0 && ver == 1) b ^= flag; //Access 2000
if (b > 0) password += (char)b;
}
fs.Dispose();
}
catch { }
return password;
}
private void UpdatePwd()
{
string filePath = Tag.ToString();
string strDBConn = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Persist Security Info=False;Mode=12;Jet OLEDB:Database Password={txtOld.Text}";
OleDbConnection OleConn = new OleDbConnection(strDBConn);
OleConn.Open();
string newPwd = txtNew.Text;
string oldPwd = txtOld.Text;
string strExe = $"ALTER DATABASE PASSWORD " + newPwd + " " + oldPwd;
OleDbCommand cmd = new OleDbCommand(strExe, OleConn);
int count = cmd.ExecuteNonQuery();//密码为文本类型
OleConn.Close();
}
四、你看有几分熟悉
五、下载评价
待审核
六、单线联系方式
gshuaijun@163.com,本邮箱只收不回,代码主回复信件用其他邮箱、只发不收。——反侦查连宣