没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
介绍
没有一个理想的方法来保护软件免受未经授权的使用和分发。任何现有的系统都不能提供
绝对的安全性,并防止潜在的黑客破坏它。然而,使用高质量和高效的保护可能会使软件
的破解变得极其困难,以至于在时间和精力上都无法完全打破保护。虽然软件保护可以追
求不同的目标,但任何保护系统的基础都是从分析中保护应用程序,因为正是对逆向工程
的抵制塑造了保护系统的整体效率。
词汇表
软件的分析、破解与保护
什么是 VMProtect?
关于保护应用程序的建议
另请参见
本手册的最新版本在我们的网站上
词汇表
如果你不知道特定于相应主题的术语,你就不能有效地使用工具。下面的词汇表解释了
VMProtect 中使用的术语。术语表并非详尽无遗,因此有些术语可能提供不同于经典术语
的含义。
字节码—将实际处理器的命令转换为虚拟机的命令后收到的代码。
虚拟化—将应用程序可执行代码的一部分转换为虚拟机命令的过程,虚拟机具有潜在黑客
未知的命令系统、体系结构和操作逻辑。虚拟化的代码片段由虚拟机的解释器执行,而不
将它们转换为物理处理器的机器语言代码。一般来说,虚拟化片段的逆向工程可以归结为
构建一个与虚拟机模拟的处理器具有相同体系结构的反汇编程序,并分析由此产生的反汇
编代码。
虚拟机—直接在受保护的应用程序中执行字节码的程序代码。
水印-每个用户一个唯一的字节数组,允许明确确定一个合法所有者的黑客副本的程序。
突变-用模拟命令或产生相同结果的特定命令集替换原始命令
混淆-一组方法和技术,旨在使程序代码的分析复杂化。根据编写受保护程序的编程语言,
使用不同的模糊处理类型。用解释语言(Perl、PHP 等)编写的应用程序的混淆是通过修
改源代码来实现的:注释被删除,变量被赋予毫无意义的名称,字符串常量被加密等等 。
Java/.NET 应用程序的模糊处理是通过转换虚拟机处理的字节码来执行的。编译程序的混
淆依赖于修改机器语言代码:混淆器添加各种“垃圾”命令、“死代码”、随机跳转。此外,原
始命令会发生变化,一部分操作被移动到堆栈中,并进行一些结构(或不太频繁的数学)
转换。对模糊代码片段的反向工程试图将片段恢复到原始状态,只要正确地进行模糊处理
这是一项耗时的任务。
保护程序-旨在保护其他程序免受黑客攻击的软件。今天的大多数保护程序不会修改应用程
序的源代码,而是打包或加密应用程序。重点是保护解包/解密程序或过程。
入口点—加载到内存中的应用程序的初始地址执行从开始。
打包—通过使用非典型算法压缩程序和/或库的可执行文件来保护程序代码的一种方法。受
保护的代码片段由打包机压缩,并在执行应用程序时在用户端完全或部分解包。
加密使用强大的加密算法保护应用程序代码的一部分。受加密保护的软件要求最终用户输
入激活码,以消除开发人员为未注册版本的程序设置的限制。
软件的分析、破解与保护
软件产品可以通过静态或动态分析进行分析。静态分析意味着保护破解算法是基于反汇编
结果分析或受保护应用程序的反编译。动态分析是破解加密或动态变化的可执行文件所必
需的,因为这类程序的静态分析被证明是困难的。
对于动态分析,被破解的程序在调试器框架中执行。这样,程序运行期间发生的一切都可
以由调试器控制。在动态分析期间,破解程序使用调试模式逐个绕过程序的所有保护算法
特别是注册密钥生成和检查过程。动态分析经常使用的另一个工具是跟踪被破解程序查询
的文件、系统服务、端口和外部设备。
保护应用程序不被破解的主要工具是软件保护器。大多数保护程序提供的保护是基于原始
可执行文件的打包和/或加密,重点放在保护解包/解密过程上。
这种算法通常不足以提供可靠的保护。如果应用程序受到打包保护,那么黑客在解包程序
完成工作后立即进行内存转储,就可以很容易地获得原始解包文件。此外,还有多种自动
化工具来破解最流行的保护器。加密也是如此:在获得适当的许可证密钥(通常是合法购
买的)之后,破解程序可以解密代码中受保护的部分。
一些软件保护器使用一些反调试技术。然而,它们中的每一个都会显著地影响受保护程序
的性能。而且,反调试方法只对动态分析有效,对静态分析完全无效。更重要的是,现代
保护器使用的所有反调试方法都是众所周知和研究的,而且破解程序已经编写了许多实用
程序来避免或绕过它们。活动监视器完全不受内置反调试保护的影响。
更有效的保护应用程序的方法是模糊化和虚拟化,这会使受保护应用程序代码的分析复杂
化。一般来说,这些保护方法的高效率是基于人为因素的:代码越复杂,应用程序使用的
资源越多,破解者就越难理解程序逻辑,从而破解保护。
模糊处理通过向应用程序中添加过多的指令来“纠缠”应用程序的代码。虚拟化将源代码转
换为由一个特殊的解释器执行的字节码,这个解释器用一组特定的命令模拟虚拟机。因此
虚拟化会导致生成代码的高度复杂性和不可还原性,如果应用得当,受这种方法保护的代
码不会包含显式还原原始代码的方法。因此,虚拟化的主要优势在于,虚拟化的代码片段
在执行过程中不会转换为机器语言命令,这反过来又会阻止破解程序获取应用程序的原始
代码。
将虚拟化片段的逆向工程归结为对虚拟机体系结构的分析、对虚拟机所模仿的处理器的相
应体系结构构建反汇编程序以及对反汇编代码的分析。一个正确实现的虚拟机使得为其创
建反汇编程序变得相当困难。虚拟化的唯一缺点是执行速度相对较低,因此这种方法应该
只应用于对执行速度不重要的部分代码。
今天的大多数保护器都不太重视模糊化和虚拟化,或者它们的实现很差。这使得饼干删除
自动或半自动模式这种保护。现代保护程序的另一个瓶颈是使用未记录的 Windows 函数,
这会导致受保护的应用程序在较新版本的操作系统中的操作受到限制,或者如果启用了
DEP。
什么是 VMProtect?
VMProtect 是 新 一 代 的 软 件 保 护 实 用 程 序 。 VMGuilder 支 持 Delphi 、 Borland C
Builder、Visual C/C++、Visual Basic(NEATH)、Virtual Pascal 和 XCODEL 编译
器。同时,VMProtect 有一个内置的反汇编程序,可用于 Windows 和 Mac OS X 可执行
文件,还可以链接编译器创建的映射文件,以快速选择代码片段进行保护。为了方便应用
程序保护任务的自动化,VMProtect 实现了一种内置脚本语言。VMProtect 从 Windows
2000 开始完全支持 Windows 系列的 32/64 位操作系统,从版本 10.6 开始完全支持
Mac OS X。重要的是,无论目标平台是什么,VMProtect 都支持所有范围的可执行文件,
也就是说,Windows 版本可以处理 Mac OS X 版本的文件,反之亦然。
VMProtect 的基本原理是通过使应用程序代码和逻辑变得非常复杂,以便进一步分析和破
解,从而有效地保护应用程序代码免受检查。VMProtect 应用的主要软件代码保护机制有:
虚拟化、变异以及涉及应用程序代码变异和后续虚拟化的组合保护。
VMProtect 中使用的虚拟化方法的关键优势在于,执行虚拟化代码片段的虚拟机被嵌入到
受保护应用程序的结果代码中。因此,受 VMProtect 保护的应用程序不需要第三方库或模
块来运行。VMProtect 允许使用多个不同的虚拟机来保护同一应用程序的不同代码片段,
从而导致更复杂的破解过程,因为黑客现在必须分析多个虚拟机的体系结构。
VMProtect 中应用的应用程序代码变异方法是基于模糊处理的,模糊处理是在应用程序代
码中添加各种过多的“垃圾”命令、“死”代码部分、随机条件跳转的过程。它还改变原始命令,
并将某些操作的执行转移到堆栈中。
VMProtect 与其他软件保护器的关键区别在于它能够用不同的方法保护代码的不同部分:
一部分代码可以虚拟化,另一部分代码可以模糊化,关键片段可以用组合方法保护。
为了防止病毒的误报,VMProtect 的注册版本使用 Taggant 库,该库使用许可所有者的
证书对受保护的文件进行签名。
VMProtect 的另一个独特特性是在应用程序的代码中嵌入水印。水印允许明确地识别程序
被黑客拷贝的官方所有者,并因此对其采取一定的措施。
VMProtect 有 3 个版本:
Lite;
Professional;
Ultimate;
下表列出了某些 VMProtect 版本的功能差异:
关于保护应用程序的建议
VMProtect 是一种可靠的工具,可以保护应用程序代码不受分析和破解,但是只有在正
确构建应用程序保护机制的情况下,才可能使用最有效的保护机制,而不会出现可能破
坏整个保护的典型错误。让我们回顾一下开发一个好的程序保护的关键要素。
登记程序
许多开发人员在设计自己的应用程序注册过程时犯的一个典型错误是将整个注册密钥检
查包在单个函数中,该函数还返回一个易于理解的值:
function CheckRegistration(const RegNumber: String): Boolean;
begin
if RegNumber='123' then
Result:=True
else
Result:=False;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
...
if not CheckRegistration(RegNumber) then
exit;
Application.CreateForm(TForm2, Form2);
Form2.ShowModal;
...
end;
使用这种方法,入侵者甚至不需要了解密钥检查算法。他只需在检查过程开始时修改代码
使其始终返回正确的注册键值:
function CheckRegistration(const RegNumber: String): Boolean;
begin
Result:=True;
exit;
...
end;
一种更有效的检查密钥的方法是将校验嵌入程序的主操作逻辑中,使注册密钥检查算法与
调用过程的算法分离。我们还建议将操作逻辑与注册表项检查程序“混合”,以使程序在绕
过检查时失败。对于上述示例,可以如下所示:
function CheckRegistration(const RegNumber: String): Boolean;
begin
if RegNumber='123' then
begin
Application.CreateForm(TForm2, Form2);
Result:=True
end
else
Result:=False;
end;
剩余24页未读,继续阅读
资源评论
weixin_44619670
- 粉丝: 0
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功