mirror of
https://github.com/atom0s/Steamless.git
synced 2024-12-19 23:07:41 +01:00
PE32: Replace manual PE checksum calculations with Win32 API call instead.
PE64: Replace manual PE checksum calculations with Win32 API call instead. I was trying to avoid using Win32 API calls in this project for the most part, however, this calculation has multiple conditions that can alter its result. Steamless was only producing proper checksums about 40% of the time as a result of this. Instead, the project will now use the system API call 'MapFileAndCheckSum' to calculate the checksum properly.
This commit is contained in:
parent
51be8ca795
commit
411f4f711c
3 changed files with 16 additions and 106 deletions
|
@ -90,49 +90,6 @@ namespace Steamless.API.PE32
|
|||
return GetStructure<NativeApi32.ImageSectionHeader32>(rawData, dataOffset + (index * sectionSize));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the PE checksum of the opened file. (OptionalHeader.Checksum should be 0 before calling this!)
|
||||
/// </summary>
|
||||
/// <param name="fStream"></param>
|
||||
/// <returns></returns>
|
||||
private static byte[] CalculateChecksum(FileStream fStream)
|
||||
{
|
||||
fStream.Position = 0;
|
||||
|
||||
var dataSize = fStream.Length;
|
||||
var totalWords = dataSize / 2;
|
||||
var sumTotal = 0;
|
||||
|
||||
// Process the file data in uint16_t chunks..
|
||||
while (totalWords > 0)
|
||||
{
|
||||
var sumChunk = 0;
|
||||
var chunkWords = totalWords;
|
||||
|
||||
// Prepare next chunk size..
|
||||
if (chunkWords > UInt16.MaxValue)
|
||||
chunkWords = UInt16.MaxValue;
|
||||
|
||||
totalWords -= chunkWords;
|
||||
|
||||
do
|
||||
{
|
||||
var data = new byte[2];
|
||||
fStream.Read(data, 0, 2);
|
||||
sumChunk += BitConverter.ToUInt16(data, 0);
|
||||
} while (--chunkWords != 0);
|
||||
|
||||
sumTotal += (sumChunk >> 16) + (sumChunk & 0xFFFF);
|
||||
}
|
||||
|
||||
if ((dataSize % 2) != 0)
|
||||
sumTotal += fStream.ReadByte();
|
||||
|
||||
var checksum = (uint)(((sumTotal >> 16) + (sumTotal & 0xFFFF)) + dataSize);
|
||||
|
||||
return BitConverter.GetBytes(checksum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the given files PE checksum value. (Path is assumed to be a 32bit PE file.)
|
||||
/// </summary>
|
||||
|
@ -140,6 +97,11 @@ namespace Steamless.API.PE32
|
|||
/// <returns></returns>
|
||||
public static bool UpdateFileChecksum(string path)
|
||||
{
|
||||
// Obtain the proper checksum for the file..
|
||||
var ret = NativeApi32.MapFileAndCheckSum(path, out uint HeaderSum, out uint Checksum);
|
||||
if (ret != 0)
|
||||
return false;
|
||||
|
||||
FileStream fStream = null;
|
||||
var data = new byte[4];
|
||||
|
||||
|
@ -158,17 +120,10 @@ namespace Steamless.API.PE32
|
|||
offset += 4 + (uint)Marshal.SizeOf(typeof(NativeApi32.ImageFileHeader32)) + (uint)Marshal.OffsetOf(typeof(NativeApi32.ImageOptionalHeader32), "CheckSum").ToInt32();
|
||||
fStream.Position = offset;
|
||||
|
||||
// Ensure the checksum is 0 to start..
|
||||
data = new byte[4] { 0, 0, 0, 0 };
|
||||
// Overwrite the file checksum..
|
||||
data = BitConverter.GetBytes(Checksum);
|
||||
fStream.Write(data, 0, 4);
|
||||
|
||||
// Calculate the new checksum..
|
||||
var checksum = CalculateChecksum(fStream);
|
||||
|
||||
// Update the checksum value..
|
||||
fStream.Position = offset;
|
||||
fStream.Write(checksum, 0, 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -90,49 +90,6 @@ namespace Steamless.API.PE64
|
|||
return GetStructure<NativeApi64.ImageSectionHeader64>(rawData, (int)dataOffset + (index * sectionSize));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the PE checksum of the opened file. (OptionalHeader.Checksum should be 0 before calling this!)
|
||||
/// </summary>
|
||||
/// <param name="fStream"></param>
|
||||
/// <returns></returns>
|
||||
private static byte[] CalculateChecksum(FileStream fStream)
|
||||
{
|
||||
fStream.Position = 0;
|
||||
|
||||
var dataSize = fStream.Length;
|
||||
var totalWords = dataSize / 2;
|
||||
var sumTotal = 0;
|
||||
|
||||
// Process the file data in uint16_t chunks..
|
||||
while (totalWords > 0)
|
||||
{
|
||||
var sumChunk = 0;
|
||||
var chunkWords = totalWords;
|
||||
|
||||
// Prepare next chunk size..
|
||||
if (chunkWords > UInt16.MaxValue)
|
||||
chunkWords = UInt16.MaxValue;
|
||||
|
||||
totalWords -= chunkWords;
|
||||
|
||||
do
|
||||
{
|
||||
var data = new byte[2];
|
||||
fStream.Read(data, 0, 2);
|
||||
sumChunk += BitConverter.ToUInt16(data, 0);
|
||||
} while (--chunkWords != 0);
|
||||
|
||||
sumTotal += (sumChunk >> 16) + (sumChunk & 0xFFFF);
|
||||
}
|
||||
|
||||
if ((dataSize % 2) != 0)
|
||||
sumTotal += fStream.ReadByte();
|
||||
|
||||
var checksum = (uint)(((sumTotal >> 16) + (sumTotal & 0xFFFF)) + dataSize);
|
||||
|
||||
return BitConverter.GetBytes(checksum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the given files PE checksum value. (Path is assumed to be a 32bit PE file.)
|
||||
/// </summary>
|
||||
|
@ -140,6 +97,11 @@ namespace Steamless.API.PE64
|
|||
/// <returns></returns>
|
||||
public static bool UpdateFileChecksum(string path)
|
||||
{
|
||||
// Obtain the proper checksum for the file..
|
||||
var ret = NativeApi64.MapFileAndCheckSum(path, out uint HeaderSum, out uint Checksum);
|
||||
if (ret != 0)
|
||||
return false;
|
||||
|
||||
FileStream fStream = null;
|
||||
var data = new byte[4];
|
||||
|
||||
|
@ -158,17 +120,10 @@ namespace Steamless.API.PE64
|
|||
offset += 4 + (uint)Marshal.SizeOf(typeof(NativeApi64.ImageFileHeader64)) + (uint)Marshal.OffsetOf(typeof(NativeApi64.ImageOptionalHeader64), "CheckSum").ToInt32();
|
||||
fStream.Position = offset;
|
||||
|
||||
// Ensure the checksum is 0 to start..
|
||||
data = new byte[4] { 0, 0, 0, 0 };
|
||||
// Overwrite the file checksum..
|
||||
data = BitConverter.GetBytes(Checksum);
|
||||
fStream.Write(data, 0, 4);
|
||||
|
||||
// Calculate the new checksum..
|
||||
var checksum = CalculateChecksum(fStream);
|
||||
|
||||
// Update the checksum value..
|
||||
fStream.Position = offset;
|
||||
fStream.Write(checksum, 0, 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -36,5 +36,5 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: Guid("56c95629-3b34-47fe-b988-04274409294f")]
|
||||
[assembly: AssemblyVersion("1.0.0.5")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.5")]
|
||||
[assembly: AssemblyVersion("1.0.0.6")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.6")]
|
Loading…
Reference in a new issue