2006年7月上旬,FDT的电脑爆发病毒,趋势杀毒后,所有的EXE文件都不能执行。双击后会弹出DOS窗口,一闪及过。我也没有能幸免。
索性先研究一下:
用Ultra Edit等工具打开正常的EXE文件会发现EXE文件均是以十六进制4D开头。
EXE文件被修改以后,大家会发现文件大小并未改变或者只增加了1K。
用Ultra Edit打开被修改后的EXE文件,发现头被修改为00 00 00 00 00 00 00 00 00,把这部分去掉,保存文件。EXE文件就恢复了以前的面貌。
因此可以确定,只要将文件修改后即可恢复正常使用。无需重新安装或拷贝正常的EXE文件。
自己索性写了个小东西:
//修复列表框里的exe文件
private void button1_Click(object sender, EventArgs e)
{
int nFile = this.listBox1.Items.Count;
int rFile = 0;
if (this.listBox1.Items.Count < 1)
{
MessageBox.Show("请添加需要修复的exe文件");
return;
}
for (int i = 0; i < this.listBox1.Items.Count; i++)
{
bool succ = repairFile(this.listBox1.Items[i].ToString());
if (succ == true)
{
this.listBox1.Items.RemoveAt(i);
rFile++;
}
}
if (rFile == nFile)
{
MessageBox.Show("修复完成");
}
else
{
MessageBox.Show("修复过程中发生错误,有几项并未修复完成,如右侧列表所示");
}
}
/// <summary>
/// 修复文件
/// </summary>
/// <param name="fileName">文件名称及详细路径</param>
/// <returns>false失败 false 成功</returns>
private bool repairFile(string fileName)
{
if (File.Exists(fileName) == false)
{
MessageBox.Show("指定的文件不存在");
return false;
}
string bkfile = fileName.Substring(0, fileName.LastIndexOf(@"/")) + fileName.Substring(fileName.LastIndexOf(@"/")) + ".bak";
if (File.Exists(bkfile)==true)
{
File.Delete(bkfile);
}
try
{
File.Copy(fileName, bkfile);
}
catch(Exception ex)
{
MessageBox.Show("发生错误:" + ex.Message);
return false;
}
byte[] tmp = new byte[1024];
bool flag = false;
FileStream fs = new FileStream(bkfile, FileMode.Open);
FileStream fs2 = new FileStream(fileName, FileMode.Open);
int time = 0;
int lng = 1024;
while (time * 1024 <= fs.Length)
{
if (time == 0 && tmp[0].ToString("X") == "4D")
{
return true;
}
fs.Read(tmp, 0, lng);
time = time + 1;
if (flag == true)
{
fs2.Write(tmp, 0, tmp.Length);
continue;
}
for (int i = 0; i < tmp.Length; i++)
{
string t = tmp[i].ToString("X");
if (t == "4D")
{
fs2.Write(tmp, i, 1024 - i);
flag = true;
break;
}
Console.WriteLine(t);
}
}
fs.Close();
fs2.Close();
return true;
}
//添加要修复的文件到列表框
private void button2_Click(object sender, EventArgs e)
{
this.openFileDialog1.ShowDialog();
bool flag = false;
for (int i = 0; i < this.listBox1.Items.Count; i++)
{
if (this.listBox1.Items[i].ToString() == this.openFileDialog1.FileName.ToString())
{
flag = true;
}
}
if (flag == true)
{
MessageBox.Show("已经添加了这个文件");
}
else
{
this.listBox1.Items.Add(this.openFileDialog1.FileName.ToString());
}
}
//选择要修复的目录
private void button3_Click(object sender, EventArgs e)
{
this.folderBrowserDialog1.ShowDialog();
this.textBox1.Text = this.folderBrowserDialog1.SelectedPath.ToString();
}
//修复整个文件夹的文件
private void button4_Click(object sender, EventArgs e)
{
if (Directory.Exists(this.textBox1.Text) == false)
{
MessageBox.Show("选择的目录不存在,请重新选择");
return;
}
repFoFile(this.textBox1.Text);
MessageBox.Show("修复完成,不能修复的EXE文件如列表");
}
//遍历文件夹进行修复
private void repFoFile(string folder)
{
DirectoryInfo myFolder = new DirectoryInfo(folder);
foreach (FileInfo NextFile in myFolder.GetFiles("*.exe"))
{
bool succ = repairFile(NextFile.FullName);
if (succ == false)
{
this.listBox2.Items.Add(NextFile.Name);
}
}
foreach (DirectoryInfo NextDir in myFolder.GetDirectories())
{
repFoFile(NextDir.FullName);
}
}