二进制检查器






4.94/5 (14投票s)
一个可以以简单方式打开、查看和编辑二进制文件的 Windows 窗体应用程序
引言
Binary Inspector 是一个简单的 Windows 窗体应用程序,可以打开二进制文件并以清晰的方式显示其内容。它还允许编辑二进制文件。由于它不是为大文件设计的,因此它仅限于读取大小不超过 10KB 的文件。我见过类似的工具通过查找文本并提供翻译旧电子游戏模拟器 ROM 文件的方法来实现这一点。我认为这个应用程序可能会成为这样一个工具。
下载它! 或获取 源代码。
要求:Windows Vista*、Seven、Eight、10。
* 必须安装 .NET Framework 4.5。
背景
五年前,我写了一篇关于 多基数编辑器组件 的文章。我很快就开发了这个应用程序。当时,我被要求打开和读取一个二进制文件,但我找不到一个免费的工具能够如此简单地做到这一点。我还想要我想要检查的每个字节的地址。最后,如果我能以不同的视图打开和检查文件,为什么不允许编辑它呢?我可以在其中添加我的多基数编辑器并使其发挥作用。
我很遗憾没有早点写这个。最近,我决定恢复我的旧代码和项目,并让它们复活。该项目最初使用 Visual Studio 2010 Express、Windows Forms 和 .NET Framework 3.5 开发,现在我正在使用 Visual Studio 2015 Community 将其更新到 .NET Framework 4.0。我想重点介绍我使用的一些有趣的片段。完整的源代码可供下载。下图 1 展示了它的外观
最初的想法是保持简单易用。现在我看到有其他工具可以做到这一点,我会提到 HexEdit。我认为它是一个功能齐全的工具。
Using the Code
核心功能是将字节列表显示为数字(十进制、十六进制、二进制或八进制)。要做到这一点,首先要做的是打开一个文件。任何类型的文件都可以,它可以是图像文件或文本文件。下面的代码片段描述了文件是如何打开的。文件内容存储在我称之为 bytes
的数组变量中,然后调用 displayBytes()
方法。每当需要将二进制数据渲染到文本框时,就会调用 displayBytes()
。
if (dialogResult == DialogResult.OK) {
if (File.Exists(openFileDialog1.FileName)) {
fileStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
// Limits the size of files this application can open and display.
if (fileStream.Length < 10000) {
bytes = ReadFully(fileStream);
displayBytes();
// ...
}
else
txtBinary.Text = "File is too large";
}
}
通过一些数学和逻辑,我在文本框中显示二进制数据。用户可以设置一些选项,包括:以十六进制显示字节、显示提示、使用换行符、尝试转换为 ASCII 字符、鼠标移过时显示信息以及鼠标移过时自动选择。为了进行渲染,下面的代码完成了所有魔法。
private void displayBytes() {
char validChar;
int padlef = cbHexadecimal.Checked ? 2 : 3;
txtBinary.Clear();
if (bytes == null)
return;
StringBuilder text = new StringBuilder();
for (int i = 0; i < bytes.Length; i++) {
if (UseBytesPerLine && i != 0 && (i % options.BytesPerLine == 0))
text.AppendLine();
if (options.ConvertCharacter)
if (tryGetChar(bytes[i], out validChar)) {
text.Append(validChar.ToString().PadLeft(padlef));
text.Append(" ");
continue;
}
if (cbHexadecimal.Checked) {
text.Append(bytes[i].ToString("X").PadLeft(2, '0'));
}
else
text.Append(bytes[i].ToString().PadLeft(3, ' '));
text.Append(" ");
}
txtBinary.Text = text.ToString();
updateAddress();
}
之后,调用 updateAddress()
来填充每行的第一个字节地址位置。这一切都是根据用户设置的选项计算的。查看下面的代码是如何完成的。
private void updateAddress() {
txtAddress.Clear();
int height;
height = 0;
int charIndex = txtBinary.GetCharIndexFromPosition(new Point(0, height));
int charIndexFromLastLine = txtBinary.GetCharIndexFromPosition
(new Point(0, txtBinary.Height - 2));
int lastLine = txtBinary.GetLineFromCharIndex(charIndexFromLastLine);
int breaklineCount = Environment.NewLine.Length;
StringBuilder addresses = new StringBuilder();
for(int i = 0; i < lastLine - 1; i++) {
height = txtBinary.Font.Height * i + 1;
charIndex = txtBinary.GetCharIndexFromPosition(new Point(1, height));
if(options.UseBreakLine)
charIndex -= breaklineCount * i; // Do not count the breakline characters
int calculatedByteIndex = -1;
if (options.DisplayHexadecimal) {
// When displaying hexadecimal every byte occupy up to 2 characters 0 - FF.
// Between every byte there is a space. Based on this information,
// the index on the byte array for the char index from the text area will be:
calculatedByteIndex = charIndex / 3;
}
else {
calculatedByteIndex = charIndex / 4;
}
addresses.AppendLine((calculatedByteIndex).ToString("X"));
} // for
txtAddress.Text = addresses.ToString();
}
文本框的 GetCharIndexFromPosition
方法用于给定屏幕相对点获取当前字符位置。请注意,GetCharIndexFromPosition
方法将换行符视为字符,因此需要调整 charIndex
值。文本框的字体高度用于定义每行的高度。地址仅针对可见文本计算。如果查看器显示十六进制值,它会计算每个字节使用 3 个字符,否则使用 4 个字符。然后可以计算字节数,如果我获取每行的第一个字节的位置(charIndex
)并除以 3
或 4
(取决于它显示的是十进制还是十六进制值),我就可以获得每行的地址。
除此之外,我还使用了一些资源来添加改进 GUI 的功能。我认为在这里详细介绍所有这些会过于冗长。我只在下面指出它们。如果你是一名学生,并且正在尝试学习如何做这些事情,请查看源代码以了解其实现方式。如果你有任何疑问,请随时与我联系。
关注点
- 我添加了
model.Options
以便使用用户控件的DataBindings
。这些选项定义了应用程序的行为和数据呈现方式。用户可以在名为OptionsView
的窗体中更改这些选项。 - 这些选项被加载并存储到位于特殊文件夹 Application.LocalUserAppDataPath 的用户设置文件中。
- 为大多数 GUI 组件添加了工具提示,用户可以打开或关闭它们。
- 有一个选项可以在鼠标指针悬停的字节的
StatusTrip
中显示当前字节信息。 - 双击字节位置会显示
EditByte
窗体,该窗体使用多基数编辑器组件,并允许用户更改所选字节。 - 使用 Doxygen 工具生成了文档。
未来工作
- 升级到 .NET Framework 4.6.1
- 添加用户帮助工具(问号)
- 使用资源文件添加多语言支持
- 为 Web 应用程序创建类似的控件
历史
- 2010 - 该代码首次编写
- 2016 - 我决定更新、发布并撰写有关它的文章