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>
26 // see http://cvs.winehq.com/cvsweb/wine/dlls/imagehlp/modify.c
27 // starting from Revision 1.8
32 namespace Mono
.PEToolkit
{
34 public sealed class CheckSum
{
38 // Never instantiated.
42 public static uint Calc(string peFile
)
46 FileInfo pe
= new FileInfo(peFile
);
48 throw new Exception("CheckSum : Invalid file path.");
51 using (BinaryReader reader
= new BinaryReader(pe
.OpenRead())) {
52 if (!reader
.BaseStream
.CanSeek
) {
53 throw new Exception("Can't seek.");
56 DOSHeader dosHdr
= new DOSHeader();
57 COFFHeader coffHdr
= new COFFHeader();
58 PEHeader peHdr
= new PEHeader();
61 reader
.BaseStream
.Position
= dosHdr
.Lfanew
;
62 ExeSignature peSig
= (ExeSignature
) reader
.ReadUInt16();
63 if (peSig
!= ExeSignature
.NT
) {
64 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
67 peSig
= (ExeSignature
) reader
.ReadUInt16();
68 if (peSig
!= ExeSignature
.NT2
) {
69 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
75 uint oldSum
= peHdr
.CheckSum
;
76 reader
.BaseStream
.Position
= 0;
78 long whole
= len
>> 1;
81 for (long i
= whole
; --i
>= 0;) {
82 sum
+= reader
.ReadUInt16();
85 sum
= hi
+ (sum
& 0xFFFF);
88 if ((len
& 1L) != 0) {
89 sum
+= (uint) reader
.ReadByte();
92 sum
= hi
+ (sum
& 0xFFFF);
96 // fix low word of checksum
98 if ((sum
& 0xFFFF) >= lo
) {
101 sum
= (((sum
& 0xFFFF) - lo
) & 0xFFFF) - 1;
104 // fix high word of checksum
106 if ((sum
& 0xFFFF) >= hi
) {
109 sum
= (((sum
& 0xFFFF) - hi
) & 0xFFFF) - 1;