How can I tell whether two .NET DLLs are the same? -


i have source dll , have compiled version of lying around somewhere.

if compile source have different date already-compiled version.

how can tell whether in fact same , have merely been compiled @ different times?

to compare 2 .dll files can use ildasm or other tool geting il code. have created sample embedded ildasm in dll file can use on every machine. when disassemble assembly check if ildasm.exe file exists in executing assembly folder , if not file extracted there our dll file. using ildasm file il code , save temporary file. need remove following 3 rows:

mvid - wrote before unique guid generated every build

image base (the image base tells program loaded in memory windows loader.) - different every build well

time-date stamp - time , date when ildasm run

so read temp file content, remove these rows using regexes, , save file content same file. here disassembler class:

using system; using system.io; using system.linq; using system.reflection; using system.diagnostics; using system.text.regularexpressions;  namespace filehasher {     public class disassembler     {         public static regex regexmvid = new regex("//\\s*mvid\\:\\s*\\{[a-za-z0-9\\-]+\\}", regexoptions.multiline | regexoptions.compiled);         public static regex regeximagebase = new regex("//\\s*image\\s+base\\:\\s0x[0-9a-fa-f]*", regexoptions.multiline | regexoptions.compiled);         public static regex regextimestamp = new regex("//\\s*time-date\\s+stamp\\:\\s*0x[0-9a-fa-f]*", regexoptions.multiline | regexoptions.compiled);          private static readonly lazy<assembly> currentassembly = new lazy<assembly>(() =>         {             return methodbase.getcurrentmethod().declaringtype.assembly;         });          private static readonly lazy<string> executingassemblypath = new lazy<string>(() =>         {             return path.getdirectoryname(assembly.getexecutingassembly().location);         });          private static readonly lazy<string> currentassemblyfolder = new lazy<string>(() =>         {             return path.getdirectoryname(currentassembly.value.location);         });          private static readonly lazy<string[]> arrresources = new lazy<string[]>(() =>         {             return currentassembly.value.getmanifestresourcenames();         });          private const string ildasmarguments = "/all /text \"{0}\"";          public static string ildasmfilelocation         {                         {                 return path.combine(executingassemblypath.value, "ildasm.exe");             }         }          static disassembler()         {             //extract ildasm file executing assembly location             extractfiletolocation("ildasm.exe", ildasmfilelocation);         }          /// <summary>         /// saves file embedded resource given location.         /// </summary>         /// <param name="embeddedresourcename">name of embedded resource.</param>         /// <param name="filename">name of file.</param>         protected static void savefilefromembeddedresource(string embeddedresourcename, string filename)         {             if (file.exists(filename))             {                 //the file exists, can add deletion here if want change version of 7zip                 return;             }             fileinfo fileinfooutputfile = new fileinfo(filename);              using (filestream streamtooutputfile = fileinfooutputfile.openwrite())             using (stream streamtoresourcefile = currentassembly.value.getmanifestresourcestream(embeddedresourcename))             {                 const int size = 4096;                 byte[] bytes = new byte[4096];                 int numbytes;                 while ((numbytes = streamtoresourcefile.read(bytes, 0, size)) > 0)                 {                     streamtooutputfile.write(bytes, 0, numbytes);                 }                  streamtooutputfile.close();                 streamtoresourcefile.close();             }         }          /// <summary>         /// searches embedded resource , extracts given location.         /// </summary>         /// <param name="filenameindll">the file name in dll.</param>         /// <param name="outfilename">name of out file.</param>         protected static void extractfiletolocation(string filenameindll, string outfilename)         {             string resourcepath = arrresources.value.where(resource => resource.endswith(filenameindll, stringcomparison.invariantcultureignorecase)).firstordefault();             if (resourcepath == null)             {                 throw new exception(string.format("cannot find {0} in embedded resources of {1}", filenameindll, currentassembly.value.fullname));             }             savefilefromembeddedresource(resourcepath, outfilename);         }          public static string getdisassembledfile(string assemblyfilepath)         {             if (!file.exists(assemblyfilepath))             {                 throw new invalidoperationexception(string.format("the file {0} not exist!", assemblyfilepath));             }              string tempfilename = path.gettempfilename();             var startinfo = new processstartinfo(ildasmfilelocation, string.format(ildasmarguments, assemblyfilepath));             startinfo.windowstyle = processwindowstyle.hidden;             startinfo.createnowindow = true;             startinfo.useshellexecute = false;             startinfo.redirectstandardoutput = true;              using (var process = system.diagnostics.process.start(startinfo))             {                 string output = process.standardoutput.readtoend();                 process.waitforexit();                  if (process.exitcode > 0)                 {                     throw new invalidoperationexception(                         string.format("generating il code file {0} failed exit code - {1}. log: {2}",                         assemblyfilepath, process.exitcode, output));                 }                  file.writealltext(tempfilename, output);             }              removeunnededrows(tempfilename);             return tempfilename;         }          private static void removeunnededrows(string filename)         {             string filecontent = file.readalltext(filename);             //remove mvid             filecontent = regexmvid.replace(filecontent, string.empty);             //remove image base             filecontent = regeximagebase.replace(filecontent, string.empty);             //remove time stamp             filecontent = regextimestamp.replace(filecontent, string.empty);             file.writealltext(filename, filecontent);         }          public static string disassemblefile(string assemblyfilepath)         {             string disassembledfile = getdisassembledfile(assemblyfilepath);             try             {                 return file.readalltext(disassembledfile);             }                         {                 if (file.exists(disassembledfile))                 {                     file.delete(disassembledfile);                 }             }         }     } } 

now can compare contents of these 2 il codes. option generate hash codes of these files , compare them. hese hashcalculator class: using system; using system.io; using system.reflection;

namespace filehasher {     public class hashcalculator     {         public string filename { get; private set; }          public hashcalculator(string filename)         {             this.filename = filename;         }          public string calculatefilehash()         {             if (path.getextension(this.filename).equals(".dll", system.stringcomparison.invariantcultureignorecase)                 || path.getextension(this.filename).equals(".exe", system.stringcomparison.invariantcultureignorecase))             {                 return getassemblyfilehash();             }             else             {                 return getfilehash();             }         }          private string getfilehash()         {             return calculatehashfromstream(file.openread(this.filename));         }          private string getassemblyfilehash()         {             string tempfilename = null;             try             {                 //try open assembly check if .net 1                 var assembly = assembly.loadfile(this.filename);                 tempfilename = disassembler.getdisassembledfile(this.filename);                 return calculatehashfromstream(file.openread(tempfilename));             }             catch(badimageformatexception)             {                 return getfilehash();             }                         {                 if (file.exists(tempfilename))                 {                     file.delete(tempfilename);                 }             }         }          private string calculatehashfromstream(stream stream)         {             using (var readersource = new system.io.bufferedstream(stream, 1200000))             {                 using (var md51 = new system.security.cryptography.md5cryptoserviceprovider())                 {                     md51.computehash(readersource);                     return convert.tobase64string(md51.hash);                 }             }         }     } } 

you can find full application source code on blog here - compare 2 dll files programmatically


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -