3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>
\r
26 // see http://cvs.winehq.com/cvsweb/wine/dlls/imagehlp/modify.c
\r
27 // starting from Revision 1.8
\r
32 namespace Mono.PEToolkit {
\r
34 public sealed class CheckSum {
\r
38 // Never instantiated.
\r
42 public static uint Calc(string peFile)
\r
46 FileInfo pe = new FileInfo(peFile);
\r
48 throw new Exception("CheckSum : Invalid file path.");
\r
51 using (BinaryReader reader = new BinaryReader(pe.OpenRead())) {
\r
52 if (!reader.BaseStream.CanSeek) {
\r
53 throw new Exception("Can't seek.");
\r
56 DOSHeader dosHdr = new DOSHeader();
\r
57 COFFHeader coffHdr = new COFFHeader();
\r
58 PEHeader peHdr = new PEHeader();
\r
60 dosHdr.Read (reader);
\r
61 reader.BaseStream.Position = dosHdr.Lfanew;
\r
62 ExeSignature peSig = (ExeSignature) reader.ReadUInt16();
\r
63 if (peSig != ExeSignature.NT) {
\r
64 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
\r
67 peSig = (ExeSignature) reader.ReadUInt16();
\r
68 if (peSig != ExeSignature.NT2) {
\r
69 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
\r
72 coffHdr.Read(reader);
\r
75 uint oldSum = peHdr.CheckSum;
\r
76 reader.BaseStream.Position = 0;
\r
77 long len = pe.Length;
\r
78 long whole = len >> 1;
\r
81 for (long i = whole; --i >= 0;) {
\r
82 sum += reader.ReadUInt16();
\r
85 sum = hi + (sum & 0xFFFF);
\r
88 if ((len & 1L) != 0) {
\r
89 sum += (uint) reader.ReadByte();
\r
92 sum = hi + (sum & 0xFFFF);
\r
96 // fix low word of checksum
\r
97 lo = oldSum & 0xFFFF;
\r
98 if ((sum & 0xFFFF) >= lo) {
\r
101 sum = (((sum & 0xFFFF) - lo) & 0xFFFF) - 1;
\r
104 // fix high word of checksum
\r
106 if ((sum & 0xFFFF) >= hi) {
\r
109 sum = (((sum & 0xFFFF) - hi) & 0xFFFF) - 1;
\r