Displaying a file if hexadecimal format.  
Author Message
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

I am a beginner at BASIC and I am using Visual Basic 2005 Express.

This is what I am trying to do:

I want to open a file, the file can be any format or size. I want to open it kind of like a hex editor would, except I want to be able to read the values of certain addresses in decimal format.

Here is an example:
I have 3 textbox controls: txt1,txt2,txt3. When I open the file I want to take three values from it.
The first value is from address 10 and I want it to be 8-bits.
The second value is from address 14 and I want it to be 16-bits.
The third value is from address 26 and I want it to be 32-bits.

Value 1 will go in txt1, value 2 in txt2 and value 3 in txt3.

I also want to be able to edit the file I opened. Say the three values above are: 100, 50000, 100000.
I want to be able to change those numbers in their respective text boxes and have the changes saved to my opened file.

Also, Say I change value three from 100000 to 23. I want the value to still be saved as a 32-bit value.

I have no clue how to do any of this. I have looked through help for the past 4 days. I may have missed it but I am sure it's not there. Thank you in advance for any help that is provided.




Visual Basic4  
 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

It's really, really easy.

read everything in bytes.

Use System.BitConverter to do your conversions. The object broweser is a good reference source for this.

I'd convert the fields that are supposed to be the integer and work on it as an integer when you have it like you want it, use system.Bitconverted to write the bytes back out into the buffer. Then you can just write the buffer back out to the file.

Good Luck.



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Thank you for the help. But I understood very little of what you said. As I said in my original post, I am a beginner. I need to know how to read the values for certain addresses, like a hex editor does, and put the value for the address into a textbox in decimal form.

If this helps, I am trying to make a save game editor for some of my computer games. If anybody has done this or knows how, then I would be enticed to learn how (in Visual Basic 2005, of course).

If this post is as vague as the first, then I apologize. I am having trouble explaining this.


 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Troy,

You have two offline friends with vs2005. The first is the object browser... it's a little icon with pink in it at the top. It shows all of the classes, and their properties and methods.

system.bitconverter and system.text.convert are described in there.

The second is the HELP menu. Use the help menu. Look up binaryreader and file reader.

Let says that you have a 1000 byte file. you want to diddle with bytes the seventh byte as a byte the fiftieth byte as a short (Two bytes) and the and the hundredth as and integer (4 bytes). I remember that bytes arrays begin at the zeroith byte so these will all be off by one. Since you are a beginner I’d make constants describing offsets like this:

Const cSeventh as short = 7 – 1 ‘ I do this for two reasons – To document what I’ve and make the code readable in the future
Const cfiftieth as short = 50 -1
Const cOneHundreth as short = 100 – 1

First find out how to open a file and read it in bytes . I went to the object browser and and entered readbytes for the fun of it. This is what popped up:

System.IO.BinaryReader.ReadBytes(Integer) As Byte()

You can get brief information, there and more in Help. Googling that exact thread will also. But this time I went to Help and entered in Binaryreader and I find that I can read on the class and it has good examples:

Option Explicit On

Option Strict On

Imports System

Imports System.IO

Class MyStream

Private Const FILE_NAME As String = "Test.data"

Public Shared Sub Main()

' Create the new, empty data file.

If File.Exists(FILE_NAME) Then

Console.WriteLine("{0} already exists!", FILE_NAME)

Return

End If

Dim fs As New FileStream(FILE_NAME, FileMode.CreateNew)

' Create the writer for data.

Dim w As New BinaryWriter(fs)

' Write data to Test.data.

Dim i As Integer

For i = 0 To 10

w.Write(CInt(i))

Next i

w.Close()

fs.Close()

' Create the reader for data.

fs = New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read)

Dim r As New BinaryReader(fs)

' Read data from Test.data.

For i = 0 To 10

Console.WriteLine(r.ReadInt32())

Next i

r.Close()

fs.Close()

End Sub

End Class

First of all the imports must be included at the top of your form which is a class.

Imports System

Imports System.IO ‘These bring classes and namespaces into your class (form)

Hmmmmm from thing I see I have a lot of options. Since this is going to be a sort quick program, I’m going to make functions for reading and a writing bytes to a file

They’ll look like this

Private Function ReadBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean

ReadBytes = False ' status return

If Not File.Exists(FileName) Then

MsgBox("File" + FileName + " doesn’t exist!", MsgBoxStyle.Information, "ReadBytes")

Exit Function

End If

Dim fi As New FileInfo(FileName)

Dim bytecount As Integer = fi.Length

If bytecount > MaxBufSize Then bytecount = MaxBufSize ' don't read any more than you need

If bytecount < cOneHundreth + 4 Then

MsgBox(FileName + "is smaller than minimum number of bytes", _

MsgBoxStyle.Information, "ReadBytes")

Exit Function

End If

ReDim Buffer(bytecount)

Try

Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Read)

Using r As New BinaryReader(fs)

Try

Buffer = r.ReadBytes(bytecount)

Catch e As Exception

MsgBox("Cannot Read " + FileName + " doesn’t exist!", MsgBoxStyle.Information, _

"ReadBytes" + e.Message)

Exit Function

Finally

r.Close() ' We're going to leave fs open

fs.Close()

fs.Dispose()

End Try

End Using

End Using

Catch e As Exception

MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _

"ReadBytes" + e.Message)

Exit Function

End Try

Return True

End Function

When this completes.... your buffer is full of the necessary number of bytes.

Its companion routine would look like this:

Private Function WriteBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean

WriteBytes = False

Try

Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Write)

Using w As New BinaryWriter(fs)

Try

w.Write(Buffer, 0, Buffer.Length - 1)

Catch e As Exception

MsgBox(e.Message, MsgBoxStyle.Exclamation, "Error writing file")

Finally

w.Close() ' Impeach rather

End Try

w.Close()

End Using

fs.Close()

fs.Dispose()

End Using

Catch e As Exception

MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _

"WriteBytes" + e.Message)

Exit Function

End Try

Return True

End Function

This is what you can do with HELP. It’s a good reference. When you don’t understand a Keyword like Using, it’s right there in help.

Ok so let’s do some mild bit twiddling …. And I’m going to leave the user interface up to you.

How do we get those bytes of concern into something readable

The first is a byte and we are already in bytes so

Here’s a main routine which is the event handler of a “Go” button

Private Sub cbGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbGo.Click

Dim b() As Byte = Nothing

ReadBytes(fName, b)

TextBox1.Text = "Seventh Byte: " + Hex(b(cSeventh)) + vbCrLf

Dim fifthieth As UShort = System.BitConverter.ToUInt16(b, cfifthieth)

TextBox1.Text += "Fifthiest+ as Ushort: " + Hex(fifthieth) + vbCrLf

Dim Onehundreth As UInt32 = System.BitConverter.ToUInt32(b, Onehundreth)

TextBox1.Text += "Onehundreth+ as Uint32: " + Hex(Onehundreth) + vbCrLf

' I'm going to leave the rest to you

'do your user interface stuff

' and then write it out.

WriteBytes(fName, b)

End Sub

Here’s the whole program so far… enjoy

Imports System

Imports System.IO 'These bring classes and namespaces into your class (form)

Public Class Form1

Protected Const cSeventh As Short = 7 - 1 ' I do this for two reasons – To document what I’ve done

' and to make the code readable in the future

Protected Const cfifthieth As Short = 50 - 1

Protected Const cOneHundreth As Short = 100 - 1

Protected Const MaxBufSize As Short = 1000

Protected Const fName As String = "c:\temp\code.doc"

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

TextBox1.Multiline = True

End Sub

Private Sub cbGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbGo.Click

Dim b() As Byte = Nothing

ReadBytes(fName, b)

TextBox1.Text = "Seventh Byte: " + Hex(b(cSeventh)) + vbCrLf

Dim fifthieth As UShort = System.BitConverter.ToUInt16(b, cfifthieth)

TextBox1.Text += "Fifthiest+ as Ushort: " + Hex(fifthieth) + vbCrLf

Dim Onehundreth As UInt32 = System.BitConverter.ToUInt32(b, Onehundreth)

TextBox1.Text += "Onehundreth+ as Uint32: " + Hex(Onehundreth) + vbCrLf

' I'm going to leave the rest to you

'do your user interface stuff

' and then write it out.

WriteBytes(fName, b)

End Sub

Private Function ReadBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean

ReadBytes = False ' status return

If Not File.Exists(FileName) Then

MsgBox("File" + FileName + " doesn’t exist!", MsgBoxStyle.Information, "ReadBytes")

Exit Function

End If

Dim fi As New FileInfo(FileName)

Dim bytecount As Integer = fi.Length

If bytecount > MaxBufSize Then bytecount = MaxBufSize ' don't read any more than you need

If bytecount < cOneHundreth + 4 Then

MsgBox(FileName + "is smaller than minimum number of bytes", _

MsgBoxStyle.Information, "ReadBytes")

Exit Function

End If

ReDim Buffer(bytecount)

Try

Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Read)

Using r As New BinaryReader(fs)

Try

Buffer = r.ReadBytes(bytecount)

Catch e As Exception

MsgBox("Cannot Read " + FileName + " doesn’t exist!", MsgBoxStyle.Information, _

"ReadBytes" + e.Message)

Exit Function

Finally

r.Close() ' We're going to leave fs open

fs.Close()

fs.Dispose()

End Try

End Using

End Using

Catch e As Exception

MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _

"ReadBytes" + e.Message)

Exit Function

End Try

Return True

End Function

Private Function WriteBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean

WriteBytes = False

Try

Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Write)

Using w As New BinaryWriter(fs)

Try

w.Write(Buffer, 0, Buffer.Length - 1)

Catch e As Exception

MsgBox(e.Message, MsgBoxStyle.Exclamation, "Error writing file")

Finally

w.Close() ' Impeach rather

End Try

w.Close()

End Using

fs.Close()

fs.Dispose()

End Using

Catch e As Exception

MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _

"WriteBytes" + e.Message)

Exit Function

End Try

Return True

End Function

Private Sub cbExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbExit.Click

End

End Sub

End Class

Please note that the board editor can make one line appear to be two or more lines. This compiles and runs flawlessly. It’s really irritating for a new person who doesn’t know syntax to complain that there are compile errors. I hold you responsible for knowing syntax.

There is a test file in my directory c:\temp\ you’ll have to pick your own.

Oh Yes, I forgot… here’s the output from textbox1

Seventh Byte: 1A

Fifthiest+ as Ushort: 0

Onehundreth+ as Uint32: E011CFD0

Goodluck....



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

It worked perfectly. I had to tweak it a bit of course. It took me awhile to get the numbers to show as decimal format in the box instead of hex. Oh yeah, and since it is zero based then I want the addresses to be zero based also. I didn't need to minus 1 from the address. That would have messed me up when I was looking for addresses in a hex editor.

Excellent job though. You sure knew what you were doing. I'm surprised you got so much code out of what I asked. I was amazed. Anyway thanks for your help. I'll definately be back to these forums later, since I know there are people that know what they are doing.

tml



 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Oooooh. I'm sorry. I thought you wanted the numbers in hex.

I'm glad things worked out for you !!!!



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

I have a new question now.
I took the line WriteBytes(fName, b) and added it to the following Event:

Private Sub cbSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbSave.Click
Dim b() As Byte = Nothing
WriteBytes(fName, b)
End Sub

When I run the program and click the button it gives me an error that says "Object reference not set to an instance of an object. I don't know what this means. The function works when it was in the original spot and it should work here. I can post the whole code in needed.



 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

where in the code does the error occur What line

 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Imports System

Imports System.IO 'These bring classes and namespaces into your class (form)

Public Class Form1

Protected Const MaxBufSize As Integer = 65536
Protected Const fName As String = "C:\Documents and Settings\Troy Lundin\Desktop\Files\Final Fantasy I & II - Dawn of Souls.sav"

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


End Sub

Private Sub cbGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbGo.Click
CurrentFile.Text = fName
Dim b() As Byte = Nothing
ReadBytes(fName, b)
HP.Value = CDec(b(31))
'Dim fifthieth As UShort = System.BitConverter.ToUInt16(b, 50)
'TextBox1.Text += Hex(fifthieth) + vbCrLf
'Dim Onehundreth As UInt32 = System.BitConverter.ToUInt32(b, 100)
'TextBox1.Text += Hex(Onehundreth) + vbCrLf
' I'm going to leave the rest to you
'do your user interface stuff
' and then write it out.
End Sub



Private Function ReadBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean
ReadBytes = False ' status return
If Not File.Exists(FileName) Then
MsgBox("File" + FileName + " doesn’t exist!", MsgBoxStyle.Information, "ReadBytes")
Exit Function
End If

Dim fi As New FileInfo(FileName)
Dim bytecount As Integer = fi.Length
If bytecount > MaxBufSize Then bytecount = MaxBufSize ' don't read any more than you need
If bytecount < 100 + 4 Then
MsgBox(FileName + "is smaller than minimum number of bytes", _
MsgBoxStyle.Information, "ReadBytes")
Exit Function
End If

ReDim Buffer(bytecount)

Try
Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Read)
Using r As New BinaryReader(fs)
Try
Buffer = r.ReadBytes(bytecount)
Catch e As Exception
MsgBox("Cannot Read " + FileName + " doesn’t exist!", MsgBoxStyle.Information, _
"ReadBytes" + e.Message)
Exit Function
Finally
r.Close() ' We're going to leave fs open
fs.Close()
fs.Dispose()
End Try
End Using
End Using
Catch e As Exception
MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _
"ReadBytes" + e.Message)
Exit Function
End Try
Return True
End Function

Private Function WriteBytes(ByVal FileName As String, ByRef Buffer As Byte()) As Boolean
WriteBytes = False
Try
Using fs As New FileStream(FileName, FileMode.Open, FileAccess.Write)
Using w As New BinaryWriter(fs)
Try
w.Write(Buffer, 0, Buffer.Length - 1)
Catch e As Exception
MsgBox(e.Message, MsgBoxStyle.Exclamation, "Error writing file")
Finally
w.Close() ' Impeach rather
End Try
w.Close()
End Using
fs.Close()
fs.Dispose()
End Using
Catch e As Exception
MsgBox("Cannot Open " + FileName, MsgBoxStyle.Information, _
"WriteBytes" + e.Message)
Exit Function
End Try
Return True
End Function

Private Sub cbExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbExit.Click
End
End Sub

Private Sub cbSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbSave.Click
Dim b() As Byte = Nothing
WriteBytes(fName, b)
End Sub
End Class



The bold font in my code above is the spot it shows the exception. The program errors out right after that. I have tried some things, moving things around and redoing some things but to no avail.
I would post an image of the error but I cannot figure out how to post images on these forums.


 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Troy,

I just cut and pasted the file. I commented out HP becuase it wasn't defined and changed the file name and it ran fine for me with no errors.

The exception where you showed means that the file reader can't open open and additional information will be in that exception message.

 



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

System.NullReferenceException was caught
Message="Object reference not set to an instance of an object."
Source="WindowsApplication1"
StackTrace:
at WindowsApplication1.Form1.WriteBytes(String FileName, Byte[]& Buffer) in C:\Documents and Settings\Troy Lundin\My Documents\Visual Studio 2005\Projects\WindowsApplication1\WindowsApplication1\Form1.vb:line 80

That is the exception details I am getting when I step through my program.

Does this mean that the Object that needs a new instance is Write
I'm trying to understand this all, and seems a little harder than I expected.



 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

I'm really confused by this because it works here. Does this file have any strange protections Is it read only

Without a failure I can't do much.



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

It is weird that it does work on your system and not mine.

If you want I can send my project to you through email or IM or whatever.

I'm really interested in why it doesn't work. I must be doing something wrong in some other part of my file. Lemme know if you want to take a look at the project or not.

Also, thanks for all your help thus far. It has not gone unappreciated.


 
 
ReneeC





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

Troy,

Please leave you email address in your profile suitably protected from spam miners and I'll write.

Renee



 
 
Troy Lundin





PostPosted: Visual Basic General, Displaying a file if hexadecimal format. Top

OK, I have updated my profile. Send away.