VB.Net Get Offset Address

2019-08-14 11:37发布

问题:

In VB.Net I open a file with BinaryReader..

I need to find on the file for some Hex values and if they are found, it return the offset address of the first Byte..

It is possible? and how can achieve this? Thank you

EDIT:

My current code:

Private Function findOffset()
    Using reader As New BinaryReader(File.Open(filename, FileMode.Open))
        ' Loop through length of file.
        Dim pos As Integer = 0 ' <== THIS IS THE OFFSET
        Dim length As Integer = reader.BaseStream.Length
        Do While pos < length
            ' Read the integer.
            Dim value As Byte = reader.ReadByte()
            If value = CByte(&H41) Then
                Return pos
                Exit Do
            End If
            ' Add length of integer in bytes to position.
            pos += 1
        Loop
    End Using
End Function

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    MsgBox(Hex(findOffset()).ToString.PadLeft(6, "0"c))
End Sub

What i'm trying to do is:

For example i open a file and in that file opened with a Hex editor i see there are some Hex values, 41,42,43,44. I need to Find that values and then return the Offset address where they are found.

With my current code it works, but i can only find 1Byte, and i need to find more than 1.. May i need to find 1kb of data or more!

I'm making this to find free space in some bin files. So for example i need 10Byte of free space. that would be FF,FF,FF,FF,FF,FF,FF,FF,FF,FF inside a Hex heditor, and i need to find that and return the offset addres of the first empty byte.

EDIT 2

Here the first lines of code.

Private Function findOffset(query as Byte())
        Using reader As New BinaryReader(File.Open(filename, FileMode.Open))
            Dim startOffset = 80
            Dim length As Integer = reader.BaseStream.Length - startOffset
            reader.BaseStream.Position = startOffset
            If query.Length <= length Then
            ...

But doesn't work.. It tell me that free space start from decimal offset 00000047

I did something wrong here, i didn't understand well what you mean by

modify the "length" variable "length = length - startOffset"

回答1:

Using reader As New BinaryReader(File.Open("file.bin", FileMode.Open))
    ' Loop through length of file.
    Dim pos As Integer = 0 ' <== THIS IS THE OFFSET
    Dim length As Integer = reader.BaseStream.Length
    While pos < length
    ' Read the integer.
    Dim value As Byte = reader.ReadByte()
            If value == 123 Then
                return pos
            End If
    ' Write to screen.
    Console.WriteLine(value)
    ' Add length of integer in bytes to position.
    pos += 1
    End While
End Using

Slightly modified from http://www.dotnetperls.com/binaryreader-vbnet

EDIT To search for an array of values you have to loop through that array inside of your function.

Private Function findOffset(query as Byte())
    Using reader As New BinaryReader(File.Open(filename, FileMode.Open))
        Dim length As Integer = reader.BaseStream.Length
        If query.Length <= length Then
            ' process initial (first) search
            Dim values As Byte() = reader.ReadBytes(query.Length)
            Dim found As Boolean = False
            For fnd = 0 To query.Length - 1
                If values(fnd) <> query(fnd) Then
                    found = False
                    Exit For
                End If
                found = True
            Next fnd
            If found = True Then 
                Return 0
            Else ' keep searching the rest of the binary stream
                For pos = query.Length To length - 1
                    ' shift values over 1, [1,2,3,4] => [2,3,4,4]
                    Array.Copy(values, 1, values, 0, values.Length - 1)
                    ' put the next new byte at the end
                    values(values.Length - 1) = reader.ReadByte()
                    For fnd = 0 To query.Length - 1
                        If values(fnd) <> query(fnd) Then
                            found = False
                            Exit For
                        End If
                        found = True
                    Next fnd
                    If found = True Then
                        Return pos - (query.Length - 1)
                    End If
                Next pos
            End If
        End If
    End Using
    Return -1 ' not found
End Function

Note: I haven't tested the above code so there may be syntax errors.