Getting offset from index in binary

I am looking for a value in a binary file and its location is in the binary index. I use the following code and it does not return me the correct bytes from the binary.

long offset = 0; //Open read stream Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); BinaryReader brFile = new BinaryReader(fileStream); //Read index to find start position fileStream.Seek(0xC, SeekOrigin.Begin); byte[] b = brFile.ReadBytes(4); //Convert to long value for (int x = 0; x < byErr.Length; x++) offset = System.Convert.ToInt64(b[x].ToString()); //I'm assuming this is the problem //Cleanup fileStream.Flush(); b = null; //Read needed value fileStream.Position = offset; fileStream.Seek(-0x60, SeekOrigin.Current); //The value I need is 0x60 BEFORE the index location b = brFile.ReadBytes(4); //Cleanup fileStream.Flush(); fileStream.Close(); brFile.Close(); 

I get the correct value from the first read at 0xC , but I do not convert the offset to the right. I tried to convert it to a string first and get the correct string value, but at the moment when I try to get it to look for it in the wrong area for a long time. Also note that the data I need is actually ox60 BEFORE the pointer that I specified in binary format.

+4
source share
2 answers

Yes, this is definitely a problem:

 for (int x = 0; x < byErr.Length; x++) { offset = System.Convert.ToInt64(b[x].ToString()); } 

You convert each byte of the index individually into a string, then parse it and assign it offset . Thus, only the last byte will actually be used.

You can try:

 long offset = br.ReadInt32(); 

instead of calling ReadBytes(4) to start. If this uses the wrong orientation, you can use my EndianBinaryReader class from MiscUtil .

You need to register some diagnostic information to show which index you read and compare it with what you expect.

I also advise you to change the search code:

 fileStream.Position = offset - 60; 

for simplicity. In addition, flushing the stream of the files you are reading and setting b to null is unnecessary, and you must use the using statement for your FileStream , after which you do not need to manually close anything.

+4
source

Well, I found this using google, http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ab831d92-14ad-437e-9b03-102d90f44d22/ and got it to work for what I needed. I go from byte to string to long, so it seems like this is definitely not the most efficient way, but it works just fine. I also realized that .Position and .Seek asked for a decimal value when I tried to give it a hexadecimal offset.

  public static string HexStr(byte[] p) { char[] c = new char[p.Length * 2 + 2]; byte b; c[0] = '0'; c[1] = 'x'; for (int y = 0, x = 2; y < p.Length; ++y, ++x) { b = ((byte)(p[y] >> 4)); c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); b = ((byte)(p[y] & 0xF)); c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); } return new string(c); } 

So now my code looks like this ....

  using (Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { BinaryReader brFile = new BinaryReader(fileStream); //Read index to find start position fileStream.Position = 0xC; byte[] offsetByte = brFile.ReadBytes(4); string offsetString = HexStr(offsetByte); long offset = System.Convert.ToInt64(offsetString, 16); //Read needed value fileStream.Position = offset - 96; //-0x60 translates to -96 byte[] byVal = brFile.ReadBytes(4); } 
0
source

All Articles