VBReFormer Desktop 手册
VBReFormer Desktop 用户手册:安装、激活许可证、读懂七个视图、分析二进制文件、导出可在 IDE 中重新打开的 VB6 工程。
更新于 2026/9/2014 章
安装在您 Windows 计算机上的应用程序。它打开您的 Visual Basic 5 和 6 可执行文件,重建其源代码,并交还给您一个 VB6 IDE 可以重新打开的工程——并附带完整的工作台:字节、资源、设计器、图形、交叉引用和二进制补丁。
关于翻译的说明。 桌面应用程序的界面提供英语、法语和西班牙语版本。本手册中,菜单和视图的名称均按应用程序中显示的英文原文引用,首次出现时在括号内附上中文释义。
1. 安装
VBReFormer Desktop 以 MSI 安装包的形式发布,每种界面语言一个。软件包是自包含的:它内嵌所需的一切,无需事先安装任何框架。
| 要求 | |
|---|---|
| 系统 | Windows 10 版本 1607 或更高,或 Windows 11 |
| 架构 | x64 |
| 框架 | 无——软件包自包含 |
| 网络连接 | 反编译和许可证验证时需要 |
| 界面语言 | 英语、法语、西班牙语 |
不支持 Windows XP、Vista、7 和 8。 应用程序所依赖的平台至少需要 Windows 10。如果您的计算机更旧,VBReFormer Online 可在任何浏览器、任何系统上运行——这种情况下推荐使用它。
引擎在哪里运行
应用程序在本地运行;但代码重建在我们的服务器上进行。这正是版本名称 Desktop + Cloud 的含义。凡是从文件中读取的内容(格式、字节、反汇编、资源)都在您的计算机上计算;凡是重建的内容都经由服务完成。
Help ▸ About(帮助 ▸ 关于)对话框随时告诉您所连接引擎的版本、契约的版本,以及所提供功能(Capabilities served)的列表——当某项功能没有出现时很有用:如果它不在该列表中,那么拒绝它的并不是界面。
2. 激活许可证
没有许可证,应用程序同样可以打开并工作:您可以浏览二进制文件,完整阅读反汇编、字节、资源和设计器。许可证解锁的是 VB6 代码的重建和工程导出。
同一时间一台工作站
一份 VBReFormer 许可证同一时间只开放一台工作站。如果您已在别处使用它,应用程序会明确告知,并提供两条出路:从您的账户将许可证转移到这台计算机,或添加一个工作站。
这是一种温和的拒绝:您已经付费,什么都不缺。消息以这种方式表达,而不是返回一个技术错误。
打开着 VBReFormer Online 的浏览器同样算作一台工作站:在线工作室和桌面应用程序消耗的是同一份许可证。
3. 窗口
- 打开二进制文件。 File ▸ Open a VB6 binary(文件 ▸ 打开 VB6 二进制文件,
Ctrl+O)。接受的格式为.exe、.dll、.ocx和.scr。状态栏显示正在进行的分析,随后显示文件名及其编译形式——本机代码或 P-code。 - 浏览 PROJECT 面板。 左侧以 VB6 当年看到的方式呈现二进制文件:窗体、类、模块及其过程。树按需填充——展开一个节点才会请求其子节点;不会预先计算任何内容,因此即使是大型可执行文件也能快速打开。
- 选择一个过程。 该节点的视图出现在右侧。如果某个节点没有可提供的视图,屏幕上会写明原因,而不是显示一个空面板。
底部面板
| 标签页 | 用途 |
|---|---|
| Output | 操作日志。即使您更改界面语言,它也保留每一行写入时所用的语言——日志是记录,不是显示。 |
| Diagnostics | 引擎拒绝执行的操作及其原因。 一旦结果令您意外,首先就该看这里。 |
| Analyser | 交叉引用:过程的调用方、符号的出现位置。结果可以点击。 |
成员可见性
树中的每个成员都带有二进制文件所声明的可见性——(Public)、(Private)、(Friend)。这些是 VB6 关键字:不予翻译。可见性无法读取的成员不带任何标记:我们不写下我们不知道的东西。
4. 七个视图
它们分为三个系列,这一划分告诉您所读内容来自何处。这是最值得理解的一点。
“Code”系列——通过分析重建
| 视图 | 显示内容 | 何时查看 |
|---|---|---|
| Visual Basic 6 | 重建后的结构化源代码 | 默认——这正是您要找的 |
| IR | 中间表示 | 查看引擎理解了什么 |
| Disassembly | x86 机器指令 | 查看处理器执行什么 |
| P-code | VB6 虚拟机的操作码 | 仅限 P-code 二进制文件 |
沿此列表向下,就是向机器靠近。对某一行有疑问时:Visual Basic 6 说的是意图,Disassembly 说的是事实。
“Project files”系列——读取而非推断
Designer (.frm)、Project (.vbp) 和 Structure。这里没有任何内容经过代码重建:一切都是从二进制文件中的表读取的,无法读取的部分会以明文写出,而不是被补全。这是产品中最可靠的系列,也是不依赖任何推断的系列。
“Resources”系列
参见第 9 章。
5. 编译保留了什么,丢弃了什么
本章解释为什么您的代码有些部分几乎原样回来,而另一些部分带着技术名称回来。规则很简单:
Visual Basic 在运行时需要的东西,它写进了文件:VBReFormer 会把它找回来。编译后不再需要的东西,它丢弃了——没有人能把它找回来。
保留下来的: 窗体、类和模块的名称 · 控件的名称 · 事件处理程序 · 类的公共成员 · 每一个界面属性 · 对 VB 运行时的调用(635 个函数) · Win32 API(15,680 个签名) · 代码的结构 · 字符串。
不在文件中的: 注释 · 局部变量的名称 · 参数的名称 · 被其值替换的命名常量 · .bas 模块中过程的名称 · 原始缩进 · Option Explicit 和 Enum。
实际后果。 您的窗体回来时非常易读。您的
.bas模块回来时是正确的,但带着技术名称(proc_42C506)。Rename(重命名)功能(F2)正是为此而设,它会把新名称传播到工程中的每一个调用位置——参见第 7 章。
两个可验证的示例
下面的摘录来自 SETUP1.EXE,即随 Visual Basic 6 一起发布的安装向导。Microsoft 在同一文件夹中分发了它的源代码——因此您可以自己重做这一比较。
一个 .bas 模块过程
原始源代码,COMMON.BAS:
Sub AddDirSep(strPathName As String)
If Right(Trim(strPathName), Len(gstrSEP_URLDIR)) <> gstrSEP_URLDIR And _
Right(Trim(strPathName), Len(gstrSEP_DIR)) <> gstrSEP_DIR Then
strPathName = RTrim$(strPathName) & gstrSEP_DIR
End If
End Sub
VBReFormer 的输出:
Public Sub proc_42C506(ByRef arg_8 As String)
If ((Right(Trim(arg_8), Len("/")) <> "/") And (Right(Trim(arg_8), Len("\")) <> "\")) <> 0 Then
arg_8 = (RTrim$(arg_8) & "\")
End If
End Sub
逻辑逐行相同。 Right、Trim、Len、RTrim$ 都有名称;ByRef 传递被正确推断。另一方面,过程的名称和参数的名称丢失了,常量以其值的形式出现——替换它们的是编译器,不是 VBReFormer。
一个事件处理程序
原始源代码,BEGIN.FRM:
Private Sub cmdExit_Click()
ExitSetup Me, gintRET_EXIT
End Sub
VBReFormer 的输出:
Private Sub cmdExit_Click()
Set var_18 = Me
basSetup1.proc_41CE2D var_18, var_1C
End Sub
窗体的名称、按钮的名称和处理程序的名称完好无损;Me 被识别;被调用的模块有名称,这告诉您该去哪里。只有位于 .bas 中的被调用过程保留着地址名称。
标记
VBReFormer 从不猜测。无法确定的值会被标记,而不是被编造——一个看似合理却错误的值,是反编译器所能产生的最糟糕的结果。
| 标记 | 含义 | 处理方法 |
|---|---|---|
proc_42C506 |
以地址指代的过程 | 重命名(F2) |
var_18、arg_8 |
局部变量或参数 | 先读懂其用法,再重命名 |
vtbl_3C |
未解析的虚表调用 | Object Browser 通常能说出它属于哪个库 |
? |
未能确定的值 | 在 Disassembly 视图中查看同一位置 |
含有
?的文件会被 VB6 IDE 拒绝。标记是留给您决定的,不是用来原样重新编译的。
6. 分析工具
这是桌面版差异最大的地方:它提供一个完整的工作台,而在线工作室专注于阅读、反编译和导出。
| 工具 | 快捷键 | 它给您什么 |
|---|---|---|
| Analyse references(分析引用) | Shift+F12 |
过程的调用方、符号的出现位置——结果可点击,并且覆盖率经过量化:分析没有看到的部分会被计数,而不是被隐瞒 |
| Symbol list(符号列表) | Ctrl+Shift+S |
完整清单,可按种类和作用域筛选——它区分读取的名称与合成的名称 |
| Call graph(调用图) | Ctrl+Shift+A |
谁调用了什么,三种尺度,带调用方/被调用方筛选 |
| Control-flow graph(控制流图) | Ctrl+Shift+G |
过程的形状:基本块、循环、回边、不可达块 |
| Object Browser(对象浏览器) | Ctrl+Shift+B |
当答案在二进制文件之外时的“这是在哪里定义的?” |
| API Browser(API 浏览器) | Ctrl+Shift+P |
Win32 声明的原型、别名和注记 |
| Cited libraries(引用的库) | Ctrl+K |
二进制文件所依赖的内容 |
| Find VB programs(查找 VB 程序) | Ctrl+L |
查找某个文件夹中的 VB 可执行文件 |
| Find(查找) | Ctrl+Shift+F |
在所提供的视图中进行文本搜索 |
| Bookmarks(书签) | Ctrl+F2 |
标记位置,再回到那里(F8 / Shift+F8) |
| Back / forward navigation(后退/前进) | Alt+← Alt+→ |
与浏览器一样 |
为什么覆盖率经过量化。 本机调用图看到的是直接调用;它看不到经由虚表的调用,也看不到函数指针。VBReFormer 不会把一份不完整的列表当作完整的来呈现,而是显示它所省略的内容,并计数。这样您就知道该在多大程度上信任结果。
7. 重命名
这是处理二进制文件时的核心动作:反编译器交还给您逻辑,您交还给它名称。在符号上按 F2,或从符号列表进行。
对话框显示反编译器通常隐藏的三件事:
- 当前名称的来源——由您给出、由反编译器推断,还是重建得到;
- 反编译器的建议,每条都带有优先级及其出处;
- 原始名称,您随时可以回到它。
重命名是全局的。 将一个过程重命名一次,其他模块中的调用位置随之更新——包括您尚未打开的那些。
被拒绝的重命名总是附带原因。两种常见情况:引擎没有在此文档上宣告重命名功能,或者当前视图只携带词法片段——足以给文本着色,不足以指代一个实体。在这两种情况下,消息都会说明,而不是什么都不做。
8. 字节与二进制补丁
Navigate ▸ Show bytes(导航 ▸ 显示字节,Ctrl+Shift+H)打开带注释的十六进制视图:它不仅显示字节,还说明每个区域代表什么。Go to address(转到地址,Ctrl+G)直接把您带到那里。
修改可执行文件
“raw”模式允许您写入字节并生成修改后的可执行文件。它由四项拒绝所框定,每一项都在保护某样东西:
| 拒绝 | 原因 |
|---|---|
| 被分析的文件绝不会成为写入目标 | 引擎从不以写入方式打开它;界面不会取消这一保证 |
| 覆盖现有文件需要确认 | “此操作无法撤销” |
| Authenticode 签名将被移除 | 事先征求您的同意;您可以用自己的证书重新签名 |
| 被拒绝的补丁什么都不写 | 不会留下写了一半的文件 |
在线工作室不提供二进制补丁和十六进制视图:这是桌面版特有的两项功能。
9. 资源与设计器
二进制文件的资源
图标、光标、位图、字符串表、版本信息:.res 文件本会携带的一切。每个条目显示其类型、大小以及可以对它做什么,并且可以逐条提取或整体提取。
产品不知道如何绘制的资源仍会列出,并以字节形式显示:它绝不会被隐藏。而如果目录中的某些条目无法跟踪,会有警告说明——您由此知道列表短于二进制文件实际携带的内容。
窗体设计器
窗体的表面按照 VB6 当年的显示方式绘制,依据从二进制文件中读取的属性,按正确的绘制顺序。窗体的图像可以导出(Ctrl+I)。
属性是只读的:VBReFormer 知道如何读取窗体的表面,但还不知道如何把它改写回已编译的可执行文件中。参见第 13 章。
10. 导出工程
- 先检查 Diagnostics 面板。 它说明了哪些事没能做到。在导出之前读一读,可以免去事后寻找某个元素为何缺失的功夫。
- File ▸ Export the VB6 project(文件 ▸ 导出 VB6 工程)。选择一个空的目标文件夹。
- 阅读导出说明。 VBReFormer 写下它未能恢复的内容及其原因。有些信息——外部引用、编译选项、启动模式——不在二进制文件的任何结构中:它们不是被抹去了,而是从来就不在那里。它们会被标出,而不是被编造。
- 在 Visual Basic 6 中打开
.vbp。 IDE 所要求的头部(VERSION、Attribute VB_Name)已经写入。如果缺少某个引用,请通过 Project ▸ References(工程 ▸ 引用)添加。
两项保护您的写入拒绝。 VB6 文件以 ANSI 1252 写入。如果该字符集在计算机上不可用——用另一种字符集写入会悄无声息地生成错误的文件——或者您代码中的某个字符在该字符集中不存在,VBReFormer 都会拒绝写入;对于后一种情况,它会告诉您是哪个字符及其码位。
11. 选项
| 设置 | 作用 |
|---|---|
| Indentation width(缩进宽度) | 仅适用于重建的代码:反汇编、IR、P-code、设计器块和 .vbp 不由此编辑器格式化。 |
| Code page (designer)(设计器代码页) | 读取设计器标题和文本所用的代码页。VB6 二进制文件在任何地方都不声明自己的代码页——在 236 个二进制文件上测得。如果窗体的标签显示为杂乱的字符,要改的就是这个设置。 |
Group under With…End With(归入 With…End With) |
默认关闭。 输出是完全限定的(Frame1.Caption),因为编译器消解了 With 块,重建它们将是一种猜测。如果您偏好可读性胜过忠实性,请打开它。 |
| Syntax colouring(语法着色) | 一种角色,一种颜色——角色来自引擎,引擎说明每个片段是什么。#RRGGBB 记法;无效的调色板不会被应用一半。 |
| Interface language(界面语言) | 英语、法语、西班牙语——更改立即生效。 |
渲染设置随每次显示请求一起发送;它们从不作为会话状态保存。因此更改缩进不会重新分析任何内容。
12. 快捷键
| 快捷键 | 操作 |
|---|---|
Ctrl+O |
打开 VB6 二进制文件 |
F2 |
重命名光标下的符号 |
Shift+F12 |
分析引用 |
Ctrl+Shift+F |
在工程中查找 |
Ctrl+G |
转到地址 |
Ctrl+Shift+H |
显示字节 |
Ctrl+Shift+S |
符号列表 |
Ctrl+Shift+B |
Object Browser |
Ctrl+Shift+P |
API Browser |
Ctrl+Shift+G |
控制流图 |
Ctrl+Shift+A |
调用图 |
Ctrl+K |
引用的库 |
Ctrl+L |
文件夹中的 VB 程序 |
Ctrl+F2 |
切换书签 |
F8 / Shift+F8 |
下一个/上一个书签 |
Ctrl+Shift+F2 |
书签列表 |
Alt+← / Alt+→ |
后退/前进 |
Ctrl+I |
保存窗体图像 |
13. 已知限制
修改已编译可执行文件的界面
VBReFormer 读取窗体的表面及其全部属性——它还不知道如何把它们改写回可执行文件中。替换嵌入的资源、在不重新编译的情况下添加隐藏属性,这些都不可用。二进制补丁——在某个地址写入字节——则可用(第 8 章)。
UserControl 的 .ctx 资源
导出时不会写入任何 .ctx 文件。如果您的工程包含带有持久化资源的 UserControl,这部分需要重建。
Windows 10 之前的版本
请使用 VBReFormer Online:有一个浏览器就够了,无论什么系统。
任何反编译器都无法逾越的
注释、局部变量的名称、命名常量:它们不在文件中。参见第 5 章。
14. 常见问题
某个菜单功能没有反应。为什么? 打开 Help ▸ About,查看所提供功能的列表。如果该功能不在其中,拒绝它的不是界面:是引擎没有为此文档提供它。应用程序的消息也会明确说明这一点。
导出的代码能原样重新编译吗? 通常可以:在一个包含 149 个工程的测试集上,121 个无需改动即可重新编译。其余的需要添加引用,或处理几个标记。
我的窗体标签无法阅读。 这是代码页的问题。VB6 二进制文件在任何地方都不声明其设计器文本的代码页——请在选项中设置(第 11 章)。
为什么我的窗体比模块更易读? 因为 VB6 为了运行需要保留控件和事件的名称,而模块过程则被解析为纯地址。参见第 5 章。
我的可执行文件被加壳了。这有问题吗? 有:必须先脱壳,否则文件中看不到 VB6 结构。
.ocx 或 ActiveX .dll 可以反编译吗?
可以,而且那里的公共成员清单通常更丰富,因为 COM 要求为它们命名。
我的二进制文件会被发送到某处吗? 格式读取、字节、反汇编和资源都在您的计算机上处理。代码重建在我们的服务器上运行——这就是 Desktop + Cloud 版本的含义。
这合法吗? 这取决于您所在的司法管辖区以及您对该二进制文件所拥有的权利。预期用途是找回您自己的代码,或您拥有权利或授权的代码。