// Author: SkyOut // Website: http://wired-security.net // Date: September 2008 // Version: 1.0 Beta // Contact: skyout[-at-]wired-security[-dot-]net // // For additional help check README.txt // // Important: To use this program you need the Console Application // "patch.exe" being in the same folder! using System; using System.IO; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Diagnostics; namespace WindowsFormsApplication1 { public partial class EXE_PATCHER_MAIN : Form { // Declare the arrays to store the information saved in // the DIF file generated by IDA string[] offset = new string[255]; string[] bytes = new string[255]; public EXE_PATCHER_MAIN() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void b_patch_Click(object sender, EventArgs e) { // All the variables the user gives us: // What file to patch? (FileInput) // What file to generate? (FileOutput) // What file to parse through? (FileDIF) string FileInput; string FileInput_Short; string FileOutput; string FileOutput_Short; string FileDIF; string cwd = Directory.GetCurrentDirectory(); FileInput = cwd + "\\" + tb_filename_original.Text; FileInput_Short = tb_filename_original.Text; FileOutput = cwd + "\\" + tb_filename_generated.Text; FileOutput_Short = tb_filename_generated.Text; FileDIF = cwd + "\\" + tb_filename_dif.Text; // Make sure the file to be patched exists if (!File.Exists(FileInput)) { MessageBox.Show("Please specify the EXE to be patched!"); this.Close(); } // Make sure the user writes a name for the file to generate if (FileOutput_Short == "") { MessageBox.Show("Please specify the EXE, that shall be generated!"); this.Close(); } // Make sure the DIF file exists if (!File.Exists(FileDIF)) { MessageBox.Show("Please specify the DIF file generated by IDA!"); this.Close(); } // Open a stream on the DIF file StreamReader FileToDifFrom = new StreamReader(FileDIF); string line; int i = 0; while ((line = FileToDifFrom.ReadLine()) != null) { i++; } // Make sure the DIF file is not to big (because of our arrays size!) // If it is anyway, prompt the user to split it apart if (i > 250) { MessageBox.Show("The DIF file you used is more then 250 lines long.\r\nPlease split it into smaller parts!"); this.Close(); } // Close the stream again FileToDifFrom.Close(); // Open another stream on the same file StreamReader FileToDifFrom2 = new StreamReader(FileDIF); string[] line_; string[] bytes_; // Go through the DIF file and fill the arrays i = 0; while ((line = FileToDifFrom2.ReadLine()) != null) { line_ = line.Split(':'); bytes_ = line_[1].Split(' '); // Make sure it is a valid offset value if (line_[0].Length != 8) { MessageBox.Show("There was an error splitting the line %s!\r\nPlease check the offsets value!", line); this.Close(); } // Make sure it is a valid byte value if (bytes_[2].Length != 2) { MessageBox.Show("There was an error splitting the line %s!\r\nPlease check the second bytes value!", line); this.Close(); } // Write the information into the arrays bytes.SetValue(bytes_[2], i); offset.SetValue(line_[0], i); i++; } // Close the stream again FileToDifFrom2.Close(); // And now: The patching begins! int i2; for (i2 = 0; i2 < i; i2++) { // If it the first time the loop runs patch from FileInput_Short (e.g. crackme.exe) to tmp.exe if (i2 == 0) { Process patchexe = Process.Start("patch.exe", FileInput_Short + " tmp.exe " + offset[i2] + " " + bytes[i2]); patchexe.WaitForExit(); patchexe.Close(); } // If the loop runs the 2nd, 4th and so on (round numbers!) time... patch from tmp.exe to tmp2.exe else if (i2 % 2 != 0) { Process patchexe = Process.Start("patch.exe", "tmp.exe tmp2.exe " + offset[i2] + " " + bytes[i2]); patchexe.WaitForExit(); patchexe.Close(); } // If it is the 3rd, 5th and so on (non-round numbers!) time... patch from tmp2.exe to tmp.exe else { Process patchexe = Process.Start("patch.exe", "tmp2.exe tmp.exe " + offset[i2] + " " + bytes[i2]); patchexe.WaitForExit(); patchexe.Close(); } } // Finally clean the temporary generated files and generate the final output if (i2 % 2 != 0) { // For the RARE case the user only patched one byte check if the tmp2.exe // has ever been generated if (File.Exists("tmp2.exe")) { File.Delete("tmp2.exe"); } File.Move("tmp.exe", FileOutput); } else { File.Delete("tmp.exe"); File.Move("tmp2.exe", FileOutput); } // Success! MessageBox.Show("!!!SUCCESS!!!\r\n\r\nThe file has been patched.\r\nThe original file has not been changed."); } // Some help dialogues for the user... private void b_help_Click(object sender, EventArgs e) { MessageBox.Show("Author: SkyOut\r\nWebsite: http://wired-security.net\r\nDate: September 2008\r\nVersion: 1.0 Beta\r\nContact: skyout[-at-]wired-security[-dot-]net\r\n\r\nFor additional help check README.txt"); } private void b_exit_Click(object sender, EventArgs e) { this.Close(); } private void b_help_original_Click(object sender, EventArgs e) { MessageBox.Show("Put the EXE in the same directory as the patcher and write the name without(!) the absolute path!\r\nFor example: crackme.exe"); } private void b_help_generated_Click(object sender, EventArgs e) { MessageBox.Show("Write the name of the EXE, that will be generated. Warning: It won't work if you use the same name as above!\r\nFor example: crackme_cracked.exe"); } private void b_help_dif_Click(object sender, EventArgs e) { MessageBox.Show("Put the DIF file in the same directory as the patcher and write the name without(!) the absolute path!\r\nFor example: patch.dif"); } } }