gpt4 book ai didi

c# - 任何人都可以定义 Windows PE 校验和算法吗?

转载 作者:太空狗 更新时间:2023-10-29 21:14:33 56 4
gpt4 key购买 nike

我想用C#实现这个

我看过这里: http://www.codeproject.com/KB/cpp/PEChecksum.aspx

并且知道 ImageHlp.dll MapFileAndCheckSum 函数。

但是,由于种种原因,我想自己实现这个。

我发现的最好的是在这里: http://forum.sysinternals.com/optional-header-checksum-calculation_topic24214.html

但是,我不明白这个解释。谁能解释一下校验和是如何计算的?

谢谢!

更新

我从代码示例中,我不明白这是什么意思,以及如何将其翻译成 C#

sum -= sum < low 16 bits of CheckSum in file // 16-bit borrow 
sum -= low 16 bits of CheckSum in file
sum -= sum < high 16 bits of CheckSum in file
sum -= high 16 bits of CheckSum in file

更新 #2

谢谢,遇到了一些类似的 Python 代码 here

    def generate_checksum(self):

# This will make sure that the data representing the PE image
# is updated with any changes that might have been made by
# assigning values to header fields as those are not automatically
# updated upon assignment.
#
self.__data__ = self.write()

# Get the offset to the CheckSum field in the OptionalHeader
#
checksum_offset = self.OPTIONAL_HEADER.__file_offset__ + 0x40 # 64

checksum = 0

# Verify the data is dword-aligned. Add padding if needed
#
remainder = len(self.__data__) % 4
data = self.__data__ + ( '\0' * ((4-remainder) * ( remainder != 0 )) )

for i in range( len( data ) / 4 ):

# Skip the checksum field
#
if i == checksum_offset / 4:
continue

dword = struct.unpack('I', data[ i*4 : i*4+4 ])[0]
checksum = (checksum & 0xffffffff) + dword + (checksum>>32)
if checksum > 2**32:
checksum = (checksum & 0xffffffff) + (checksum >> 32)

checksum = (checksum & 0xffff) + (checksum >> 16)
checksum = (checksum) + (checksum >> 16)
checksum = checksum & 0xffff

# The length is the one of the original data, not the padded one
#
return checksum + len(self.__data__)

但是,它仍然不适合我 - 这是我对这段代码的转换:

using System;
using System.IO;

namespace CheckSumTest
{
class Program
{
static void Main(string[] args)
{
var data = File.ReadAllBytes(@"c:\Windows\notepad.exe");

var PEStart = BitConverter.ToInt32(data, 0x3c);
var PECoffStart = PEStart + 4;
var PEOptionalStart = PECoffStart + 20;
var PECheckSum = PEOptionalStart + 64;
var checkSumInFile = BitConverter.ToInt32(data, PECheckSum);
Console.WriteLine(string.Format("{0:x}", checkSumInFile));

long checksum = 0;

var remainder = data.Length % 4;
if (remainder > 0)
{
Array.Resize(ref data, data.Length + (4 - remainder));
}

var top = Math.Pow(2, 32);

for (int i = 0; i < data.Length / 4; i++)
{
if (i == PECheckSum / 4)
{
continue;
}
var dword = BitConverter.ToInt32(data, i * 4);
checksum = (checksum & 0xffffffff) + dword + (checksum >> 32);
if (checksum > top)
{
checksum = (checksum & 0xffffffff) + (checksum >> 32);
}
}

checksum = (checksum & 0xffff) + (checksum >> 16);
checksum = (checksum) + (checksum >> 16);
checksum = checksum & 0xffff;

checksum += (uint)data.Length;
Console.WriteLine(string.Format("{0:x}", checksum));

Console.ReadKey();
}
}
}

谁能告诉我我哪里蠢了?

最佳答案

好的,终于让它正常工作了...我的问题是我使用的是整数而不是单位!!!所以,这段代码有效(假设数据是 4 字节对齐的,否则你必须将它填充一点)- PECheckSum 是 PE 中 CheckSum 值的位置(计算校验和时显然不使用它! !!!)

static uint CalcCheckSum(byte[] data, int PECheckSum)
{
long checksum = 0;
var top = Math.Pow(2, 32);

for (var i = 0; i < data.Length / 4; i++)
{
if (i == PECheckSum / 4)
{
continue;
}
var dword = BitConverter.ToUInt32(data, i * 4);
checksum = (checksum & 0xffffffff) + dword + (checksum >> 32);
if (checksum > top)
{
checksum = (checksum & 0xffffffff) + (checksum >> 32);
}
}

checksum = (checksum & 0xffff) + (checksum >> 16);
checksum = (checksum) + (checksum >> 16);
checksum = checksum & 0xffff;

checksum += (uint)data.Length;
return (uint)checksum;

}

关于c# - 任何人都可以定义 Windows PE 校验和算法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6429779/

56 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com