C# 在ReadAllBytes中搜索特定值

C# 在ReadAllBytes中搜索特定值,c#,executable,definitions,C#,Executable,Definitions,我正在编写一个程序,读取“.exe”文件并将其十六进制值存储在字节数组中,以便与包含一系列值的数组进行比较。(就像一个非常简单的病毒扫描器) 然后,我使用BitConverter创建了这些值的单个字符串 string hex = BitConverter.ToString(buffer); 下一步是在该字符串中搜索一系列值(定义),并返回匹配的正值。这就是我遇到问题的地方。我的定义是十六进制值,但在记事本中创建并保存为definations.xyz string[] definitions =

我正在编写一个程序,读取“.exe”文件并将其十六进制值存储在字节数组中,以便与包含一系列值的数组进行比较。(就像一个非常简单的病毒扫描器)

然后,我使用BitConverter创建了这些值的单个字符串

string hex = BitConverter.ToString(buffer);
下一步是在该字符串中搜索一系列值(定义),并返回匹配的正值。这就是我遇到问题的地方。我的定义是十六进制值,但在记事本中创建并保存为definations.xyz

string[] definitions = File.ReadAllLines(@"C:\definitions.xyz");
我一直试图将它们读入字符串数组,并将数组的定义元素与字符串十六进制进行比较

bool[] test = new bool[currentDirectoryContents.Length];

test[j] = hex.Contains(definitions[i]);
这是一篇家庭作业的一部分,这就是为什么我没有发布我的整个程序代码的原因。在上周五之前我没有用过C#,所以我很可能在这一点上犯了愚蠢的错误


非常感谢您的任何建议:)

我希望您理解,这是一种非常低效的方法。但除此之外,你应该这样做:

bool[] test = new bool[currentDirectoryContents.Length];
for(int i=0;i<test.Length;i++){
  byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]);
  string hex = BitConverter.ToString(buffer);
  test[i] = ContainsAny(hex, definitions);
}

bool ContainsAny(string s, string[] values){
  foreach(string value in values){
    if(s.Contains(value){
      return true;
    }
  }
  return false;
}
var test = currentDirectoryContents.Select(
             file=>definitions.Any(
               definition => 
                 BitConverter.ToString(
                   File.ReadAllBytes(file)
                 ).Contains(definition)
             )
           ).ToArray();
此外,请确保定义文件的格式与
位转换器的输出相匹配。ToString()
:大写,用破折号分隔每个编码字节:

12-AB-F0-34
54-AC-FF-01-02 

目前还不清楚您使用的定义格式到底是什么。Base64是字节[]的良好编码,您可以使用convert.ToBase64String和convert.FromBase64String()快速来回转换。但是你的问题表明字节是用十六进制编码的。让我们假设一个新字节[]{1,2,3,4}看起来像“01020304”。然后,此帮助函数将此类字符串转换回字节[]:

    static byte[] Hex2Bytes(string hex) {
        if (hex.Length % 2 != 0) throw new ArgumentException();
        var retval = new byte[hex.Length / 2];
        for (int ix = 0; ix < hex.Length; ix += 2) {
            retval[ix / 2] = byte.Parse(hex.Substring(ix, 2), System.Globalization.NumberStyles.HexNumber);                
        }
        return retval;
    }
静态字节[]十六进制字节(字符串十六进制){
如果(hex.Length%2!=0)抛出新的ArgumentException();
var retval=新字节[hex.Length/2];
对于(int-ix=0;ix

现在,您可以使用类似Boyer Moore的算法进行快速模式搜索。

请发布定义文件的内容或部分内容。到底是什么问题?您的问题是什么?另一件重要的事情:将字节数组转换为字符串以进行进一步的十六进制比较实际上是无效的。您应该将字节与字节进行比较,而不要在此处使用字符串。您可以合理地概述您正在尝试的内容。。。但是:不清楚你被困在哪里了。发生了什么事?还是没有发生?(我个人同意ken2k的说法,我不会在这里使用十六进制字符串…但是:这是一个实现细节)Myles:定义文件包含我编的十六进制字符串,因为要扫描的.exe文件不是真正的.exe,而是我用exe扩展名保存的记事本文件。文件中的定义没有指定格式。我选择将每个定义都设置为一个位序列(十六进制)。这是对病毒扫描和确定特征码方法的研究。现在开始我的签名文件有一个定义:A6 7C FD 1B 45 82 90 1D 6F 3C 8A OF 96 18 A4 C3 4F FF 0F 1D one。文件夹中的exe将包含这一系列字节,因为它将在记事本中创建,并仅保存为exe。定义文件没有特定的文件格式。我现在正在使用一个随机扩展。嗯,有一个指定的格式是相当重要的。我发布的代码应该很接近,希望你需要使用3而不是2,因为空格。现在已经解决了,谢谢你花时间告诉我一个可能的解决方案!我确实理解代码的低效性,但我不是一个有经验的程序员,我对在考虑改进之前编写工作代码感到满意。我意识到我的整个代码都在工作,但我正在读取的exe文件中包含的代码已经是十六进制的了。所以我的代码只是将每个字节转换成不同的十六进制值。现在解决了。感谢大家的贡献和建议!
    static byte[] Hex2Bytes(string hex) {
        if (hex.Length % 2 != 0) throw new ArgumentException();
        var retval = new byte[hex.Length / 2];
        for (int ix = 0; ix < hex.Length; ix += 2) {
            retval[ix / 2] = byte.Parse(hex.Substring(ix, 2), System.Globalization.NumberStyles.HexNumber);                
        }
        return retval;
    }