吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 17349|回复: 32
收起左侧

[原创工具] 文件MD5批量修改工具及原理解析(附C#源码)

[复制链接]
你大锅 发表于 2019-6-28 10:43
本帖最后由 你大锅 于 2019-6-28 10:54 编辑

1.首先告诉大家怎么查看文件的MD5码,命令窗口中输入如下命令:
[Asm] 纯文本查看 复制代码
1
certutil -hashfile 文件名.后缀 MD5


2.原理剖析:
当某个文件的某段数据改变了,哪怕是变了一个字节,那么这个文件的MD5码就会跟着改变,我的做法非常简单,
就是在文件末尾写入一个UUID码,写入UUID码,这样就确保了这个世界上不会存在MD5一样的文件,除非你
把我这个UUID码拿走去生成这个文件.


关键代码:此处我采用的是边读编写,节省内存,读写完之后,我在末尾将UUID转成byte数组添加到流写入流中,已达到修改文件的目的
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public void CopyToNewFile(string oldFile, string newFile) {
    //1、创建一个负责读取的流
    using (FileStream fsRead = new FileStream(oldFile, FileMode.Open, FileAccess.Read)) {
        //2、创建一个写入流
        using (FileStream fsWrite = new FileStream(newFile, FileMode.OpenOrCreate, FileAccess.Write)) {
            //3、多媒体文件较大,循环读取
            byte[] buffer = new byte[1024 * 1024];
            int r = fsRead.Read(buffer, 0, buffer.Length);
            while (r != 0) {
                fsWrite.Write(buffer, 0, r);//写入
                //返回本次读取实际读取到的字节数
                r = fsRead.Read(buffer, 0, buffer.Length);
            }
            //通过往源文件末尾添加uuid二进制数据来改变原文件的MD5值
            buffer = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
            fsWrite.Write(buffer, 0, buffer.Length);
        }
    }
 
}


这种方法理论上支持所有的媒体文件,但不支持文本文件,虽然可以照常运行也可以达到修改MD5的目的,但是你文本内容却已经被我改变了
所以如果你要修改的是文本文件的话,那么这种方法 并不可取,如果是媒体文件,那么没毛病!


完整代码:

[C#] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
using System;
using System.Data;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
 
namespace UpdFileMD5 {
    public partial class HomeForm : Form {
        private DataTable dt;   //表格的数据源
        private bool runing;    //是否运行,用于停止运行的参数
        public HomeForm() {
            InitializeComponent();
            Init();
        }
 
        private void Init() {
            openFileDialog1.Multiselect = true;
            openFileDialog1.Title = "可以多选(框选)";
            //openFileDialog1.Filter = @"(*.jpg,*.png,*.jpeg,*.bmp,*.gif,*.mp4)|*.jgp;*.png;*.jpeg;*.bmp;*.gif;*.mp4|All files(*.*)|*.*";
 
            //初始化表格
            dt = new DataTable();
            dt.Columns.Add(new DataColumn("文件位置") { DataType = Type.GetType("System.String") });
            dt.Columns.Add(new DataColumn("状态"){DataType = Type.GetType("System.String")});
            dataGridView1.AllowUserToAddRows = false//解决用户点击最后一行老是弹出新行的问题
            dataGridView1.DataSource = dt;
            DoubleBuffered(dataGridView1, true);
            dataGridView1.Columns[1].FillWeight = 40;
        }
 
        /// <summary>
        /// 导入文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void importFile_button_Click(object sender, EventArgs e) {
            if (openFileDialog1.ShowDialog() == DialogResult.OK) {
                string[] absPaths = openFileDialog1.FileNames;  //绝对路径
                foreach (var absPath in absPaths) {
                    DataRow dr = dt.NewRow();
                    dr[0] = absPath;
                    dr[1] = "";
                    dt.Rows.Add(dr);
                }
            }
        }
 
        /// <summary>
        /// 表格序号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) {
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dataGridView1.RowHeadersWidth - 4, e.RowBounds.Height);
            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dataGridView1.RowHeadersDefaultCellStyle.Font, rectangle,
                dataGridView1.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }
 
        /// <summary>
        /// 解决行头闪烁问题
        /// </summary>
        /// <param name="dgv"></param>
        /// <param name="setting"></param>
        private new void DoubleBuffered(DataGridView dgv, bool setting) {
            Type dgvType = dgv.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
                BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(dgv, setting, null);
        }
 
        /// <summary>
        /// 开始执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void start_button_Click(object sender, EventArgs e) {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK){
                new Thread(() => {
                    try{
                        start_button.Invoke(new MethodInvoker(() => { start_button.Enabled = false; }));
                        importFile_button.Invoke(new MethodInvoker(() => { importFile_button.Enabled = false; }));
                        runing = true;
                        string savePath = folderBrowserDialog1.SelectedPath;
                        for (int i = 0; i < dt.Rows.Count; i++){
                            if (!runing){
                                break;
                            }
 
                            string absPath = dt.Rows[i][0].ToString();
                            if (!File.Exists(absPath)){
                                SetLog(i, "文件不存在");
                                continue;
                            }
 
                            if (!Directory.Exists(savePath)){
                                SetLog(i, "导出位置错误");
                                continue;
                            }
 
                            CopyToNewFile(absPath, savePath + @"\new_" + Path.GetFileName(absPath));
                            SetLog(i, "修改成功");
                        }
                    } catch (Exception e2){
                        MessageBox.Show(e2.Message);
                    } finally{
                        start_button.Invoke(new MethodInvoker(() => { start_button.Enabled = true; }));
                        importFile_button.Invoke(new MethodInvoker(() => { importFile_button.Enabled = true; }));
                        MessageBox.Show("修改完成");
                    }
                }).Start();
            }
        }
 
        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="index"></param>
        /// <param name="msg"></param>
        private void SetLog(int index,string msg) {
            dataGridView1.Invoke(new MethodInvoker(() => {
                dt.Rows[index][1] = msg;
            }));
        }
 
        /// <summary>
        /// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓关键代码:修改文件MD5码↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        public void CopyToNewFile(string oldFile, string newFile) {
            //1、创建一个负责读取的流
            using (FileStream fsRead = new FileStream(oldFile, FileMode.Open, FileAccess.Read)) {
                //2、创建一个写入流
                using (FileStream fsWrite = new FileStream(newFile, FileMode.OpenOrCreate, FileAccess.Write)) {
                    //3、多媒体文件较大,循环读取
                    byte[] buffer = new byte[1024 * 1024];
                    int r = fsRead.Read(buffer, 0, buffer.Length);
                    while (r != 0) {
                        fsWrite.Write(buffer, 0, r);//写入
                        //返回本次读取实际读取到的字节数
                        r = fsRead.Read(buffer, 0, buffer.Length);
                    }
                    //通过往源文件末尾添加uuid二进制数据来改变原文件的MD5值
                    buffer = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N"));
                    fsWrite.Write(buffer, 0, buffer.Length);
                }
            }
 
        }
 
        /// <summary>
        /// 停止运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stop_button_Click(object sender, EventArgs e) {
            runing = false;
        }
 
        private void 使用说明ToolStripMenuItem_Click(object sender, EventArgs e) {
            HelpForm hp = new HelpForm();
            hp.ShowDialog();
        }
 
        private void 关于ToolStripMenuItem1_Click(object sender, EventArgs e) {
            AboutForm af = new AboutForm();
            af.ShowDialog();
        }
 
        private void 退出ToolStripMenuItem1_Click(object sender, EventArgs e) {
            System.Environment.Exit(0);
        }
    }
}


-------------------------------------------业务代码都在这里,置于界面的话,自己用VS拖拽一下,控件的(Name)自己改一下就可以了-----------------------------------------------------------

蓝奏: https://www.lanzouj.com/nIDAguomd5tool
链接:https://pan.baidu.com/s/1cKfPp2VMyBYgULW18qU3Fw  提取码:z5q6

打开命令窗口

打开命令窗口

输入命令

输入命令

软件界面

软件界面

免费评分

参与人数 6吾爱币 +10 热心值 +4 收起 理由
Dicker + 1 + 1 用心讨论,共获提升!
15291037368 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
jianghaokun + 1 谢谢@Thanks!
落花看花落 + 1 我很赞同!
h45673 + 1 热心回复!
云在天 + 6 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 你大锅 发表于 2019-6-29 22:33
本帖最后由 你大锅 于 2019-6-29 22:45 编辑
onoffon 发表于 2019-6-29 11:28
这个关键看速度,其实在尾部加0或头部动一个字节都差不多

加头部不知道会不会造成文件识别错误,没试过,不建议加0或者某个固定字节,如果你使用的固定字节,那么下次呢?又要改?
至于修改速度,我看有的人说他的工具非常快,修改几个G的单个文件一秒都不到,但有时候又很慢,这个问题其实是你的那个文件是否有被加载到
缓存中的问题,有的话当然分分秒就搞定了,至于那些要花好几秒的,大部分都是你开机后从未运行过的文件,修改这样
的文件肯定慢些(超过1个G的)
 楼主| 你大锅 发表于 2019-7-10 01:46
本帖最后由 你大锅 于 2019-7-10 02:09 编辑
oymiss 发表于 2019-7-9 20:40
那可以用在淘宝去重复了

识别文件的身份,MD5只是其中一直方式,其他还有SHA1、CRC32、sha256等几种,关于淘宝它是否只识别MD5,这个我也不太清楚.百度一直好像都只识别MD5



补充:刚刚测试了一下,往源文件填充uuid是可以同时修改SHA1、sha256、SHA384等这些指纹的.CRC32还没试,试完在上来补充!



试过了,可以的!

 楼主| 你大锅 发表于 2019-6-28 10:55
为什么蓝奏地址中的ida这三个字母会变成大写的?
joiwet 发表于 2019-6-29 06:54
你大锅 发表于 2019-6-28 10:55
为什么蓝奏地址中的ida这三个字母会变成大写的?

怪不得打开来说取消分享,原来还大小写敏感
onoffon 发表于 2019-6-29 11:28
这个关键看速度,其实在尾部加0或头部动一个字节都差不多
头像被屏蔽
铁索横江 发表于 2019-6-29 19:32
提示: 作者被禁止或删除 内容自动屏蔽
yangcg8 发表于 2019-6-29 22:08
受教了,谢谢分享
RJROOT 发表于 2019-6-30 16:38
这样的软件值得保留!
andykeos 发表于 2019-6-30 18:42
多谢分享
错的是世界 发表于 2019-7-1 08:38
本帖最后由 错的是世界 于 2019-7-1 08:39 编辑

意义是什么?上传敏感资源到百度,避免河蟹吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-21 18:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表