1.

Solve : [Help] Search for sequence of bytes in file.?

Answer»

So im using a binaryreader to try and search a file for an array of bytes like so:

Code: [Select] void MapSearcher()
{
byte[] SearchBytes = new byte[] { 0x00, 0x00, 0x00, 0x70, 0x72, 0x6F, 0x6A };
long SearchPosition = 0x00;

BinaryReader br = new BinaryReader(File.OpenRead(MapFile));
br.BaseStream.Position = SearchPosition;

for (var i = SearchPosition; i <= br.BaseStream.Length; )
{
try
{
if (br.ReadByte() == 0x00)
{
if (br.ReadByte() == 0x00)
{
if (br.ReadByte() == 0x00)
{
if (br.ReadByte() == 0x70)
{
if (br.ReadByte() == 0x72)
{
if (br.ReadByte() == 0x6F)
{
if (br.ReadByte() == 0x6A)
{
byte[] Position = BitConverter.GetBytes(br.BaseStream.Position - 4); //-4 Because ive searched past my start mark and this is the position i NEED
Array.Reverse(Position);

output.AppendText("0x" + BitConverter.ToString(Position).Replace("00-00-00-00-0", "").Replace("-", "") + "\n"); //Offset Position Found
}
}
}
}
}
}
}
}
CATCH { break; }
}
MessageBox.Show("The application is done searching your file.", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
br.Close();
}

This works and all but i need it to be usable for searching different things. I cant REALLY find any helpful info and i can figure it out for myself so im asking for your help.Alright so i came up with a new method of searching but the old one is like 4 times faster because it only needs to search up until something is invalid and doesn't have to track back, if you have a better way of doing this then let me know.
Code: [Select] void ByteArraySearcher()
{
byte[] SearchBytes = new byte[] { 0x00, 0x00, 0x00, 0x70, 0x72, 0x6F, 0x6A };
long SearchPosition = 0x00;

BinaryReader br = new BinaryReader(File.OpenRead(MapFile));
br.BaseStream.Position = SearchPosition;

for (var i = SearchPosition; i <= br.BaseStream.Length; i++)
{
byte[] ReadBytes = br.ReadBytes(SearchBytes.Length);
if (BitConverter.ToString(ReadBytes) == BitConverter.ToString(SearchBytes)) //Must convert both byte arrays to STRING to COMPARE correctly for some odd reason
{
byte[] Position = BitConverter.GetBytes(br.BaseStream.Position - SearchBytes);
Array.Reverse(Position);
output.AppendText(BitConverter.ToString(Position).Replace("00-00-00-00-0", "").Replace("-", "") + "\n");
}
else
{
br.BaseStream.Position = br.BaseStream.Position - SearchBytes.Length + 1; //Go forward 1 byte and search again
}
}
br.Close();
if (ShowMessage == true)
{
MessageBox.Show("The application is done searching your file.", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Code: [Select] /// <summary>
/// Retrieves the first location of the specified sequence of bytes in the given stream.
/// </summary>
/// <param name="source">Stream to search.</param>
/// <param name="sequence">Sequence to look for.</param>
/// <returns>Byte position of the start of the first sequence.</returns>
private static long FindInStream(Stream source, byte[] sequence)
{
int byteposition;
if (sequence.Length == 0) return -1;
using (BinaryReader br = new BinaryReader(source))
{
try
{
while (true)
{
byte readbyte = br.ReadByte();
if (readbyte == sequence[0])
{
bool foundmatch = true;
for (int i = 1; i < sequence.Length; i++)
{
if (sequence[i] != br.ReadByte())
{
foundmatch = false;
break;
}
}
if (foundmatch) return br.BaseStream.Position - sequence.Length;
}
}
}
catch (EndOfStreamException exx)
{
return -1;
}
}
}
Quote from: BC_Programmer on April 17, 2014, 11:02:20 PM

Code: [Select] /// <summary>
/// Retrieves the first location of the specified sequence of bytes in the given stream.
/// </summary>
/// <param name="source">Stream to search.</param>
/// <param name="sequence">Sequence to look for.</param>
/// <returns>Byte position of the start of the first sequence.</returns>
private static long FindInStream(Stream source, byte[] sequence)
{
int byteposition;
if (sequence.Length == 0) return -1;
using (BinaryReader br = new BinaryReader(source))
{
try
{
while (true)
{
byte readbyte = br.ReadByte();
if (readbyte == sequence[0])
{
bool foundmatch = true;
for (int i = 1; i < sequence.Length; i++)
{
if (sequence[i] != br.ReadByte())
{
foundmatch = false;
break;
}
}
if (foundmatch) return br.BaseStream.Position - sequence.Length;
}
}
}
catch (EndOfStreamException exx)
{
return -1;
}
}
}
Why thank you good sir, while extremely fast, im finding myself sort from what im getting from my second method. There are 2 occurrences that this and my 1st post were not catching towards the end of my file and im not really sure why.Quote from: DaftHacker on April 18, 2014, 02:56:03 AM
Why thank you good sir, while extremely fast, im finding myself sort from what im getting from my second method. There are 2 occurrences that this and my 1st post were not catching towards the end of my file and im not really sure why.

"Retrieves the first location"

The one I wrote only finds the first location of the given byte sequence. You would have to seek in the stream before calling it to change the position that it starts the search from.


Discussion

No Comment Found