Search code examples
c#bytebinary-search

C# - Reading Sequence of Hex Bytes in Binary


So I've been googling & googling for this, but I can't find a solution for my case. I could find things about byte arrays. but I hope there's also a simpler solution for my case. Maybe it's just me using the wrong search terms, don't know.

Anyways, I already have a kinda working code which is:

    static void Main(string[] args)
    {
        // Open the file to search in
        BinaryReader br = new BinaryReader(File.OpenRead("D:/Users/Joey/Desktop/prod"));
        for (int i = 0; i <= br.BaseStream.Length; i++)
        {
            // Search the file for the given byte
            if (br.BaseStream.ReadByte() == (byte)0xC0)
            {
                Console.WriteLine("Found the byte at offset " + i); //write to the console on which offset it has been found
            }
        }
    }

This example works. However, I need it to be able to search for more than just one byte. For example: C0035FD6

I feel like I'm missing something so simple, but I just can't seem to figure it out.

If anyone has gotten a solution for me, that would be great :D


Solution

  • You can use this extension to search for AOB:

    public static class StreamExtensions
    {
        public static IEnumerable<long> ScanAOB(this Stream stream, params byte[] aob)
        {
            long position;
            byte[] buffer = new byte[aob.Length - 1];
    
            while ((position = stream.Position) < stream.Length)
            {
                if (stream.ReadByte() != aob[0]) continue;
                if (stream.Read(buffer, 0, aob.Length - 1) == 0) continue;
    
                if (buffer.SequenceEqual(aob.Skip(1)))
                {
                    yield return position;
                }
            }
        }
    
        public static IEnumerable<long> ScanAOB(this Stream stream, params byte?[] aob)
        {
            long position;
            byte[] buffer = new byte[aob.Length - 1];
    
            while ((position = stream.Position) < stream.Length)
            {
                if (stream.ReadByte() != aob[0]) continue;
                if (stream.Read(buffer, 0, aob.Length - 1) == 0) continue;
    
                if (buffer.Cast<byte?>().SequenceEqual(aob.Skip(1), new AobComparer()))
                {
                    yield return position;
                }
            }
        }
    
        private class AobComparer : IEqualityComparer<byte?>
        {
            public bool Equals(byte? x, byte? y) => x == null || y == null || x == y;
            public int GetHashCode(byte? obj) => obj?.GetHashCode() ?? 0;
        }
    }
    

    Example:

    void Main()
    {
        using (var stream = new MemoryStream(FakeData().ToArray()))
        {
            stream.ScanAOB(0x1, 0x2).Dump("Addresses of: 01 02");
            stream.Position = 0;
            stream.ScanAOB(0x03, 0x12).Dump("Addresses of: 03 12");
            stream.Position = 0;
            stream.ScanAOB(0x04, null, 0x06).Dump("Addresses of: 04 ?? 06");
        }
    }
    
    // Define other methods and classes here
    IEnumerable<byte> FakeData()
    {
        return Enumerable.Range(0, 2)
            .SelectMany(_ => Enumerable.Range(0, 255))
            .Select(x => (byte)x);
    }