如何防止SWF文件被反编译-程序员宅基地

技术标签: ViewUI  开发工具  javascript  

这篇文章的标题所提出的问题的答案是“不可能”。至少对我来说是不可能的。借助适当的工具,我们可以反编译任何SWF文件。所以,不要将重要的信息置于SWF文件中。SWF文件中不要包含个人的帐号或者密码。

  我将简要的论述“保护”技术的历史,和他们是如何失败的,接着我将说明我们能尽的最大努力。中国古语有云,“规则只能防君子,不能仿小人”。

  公开的文件格式

  在讨论之前,我们先要知道,SWF的文件格式是公开的。公开的文件格式,意味着SWF文件并不是只能由Flash生成。其他公司也能制作可以在SWF播放器上播放的SWF文件。公开的文件格式意味着从什么位置获取什么信息是众所周知的,也就意味着每个字节都是众所周知的。因此,如果我有时间来一个字节一个字节的检查SWF文件,我可以了解所有的细节。

  当然,对于一个2M大小的SWF文件,我没有时间来逐个字节的检查。因此,我就借助软件来完成这个工作。如果软件遇到问题,我会暂时接管这个工作,检查发生问题的字节。修正它,然后继续。所以,没有什么东西能够掩藏的住,其限制只是我的时间和我的耐性。如果反编译一个SWF文件的酬劳是数百美元的话,我想我会花上数年时间来逐个字节的读取它。

  好了,以下是反编译和保护技术之间的战争历史。

  防止被导入

  伴随着Flash的出现,Macromedia提供给开发者一个“防止导入的口令保护”功能。如果你给SWF文件加上导入口令的话,这个SWF文件就不能被导入了(知道倒入密码除外)。SWF文件不加保护的话,其中的矢量图形可以被导入到fla文件中。这种保护没有什么用处,仅仅是假想的安全。

  试想一下,你的SWF被用户的播放器来播放的,你不可能利用用户的播放器来保护你的SWF文件。因此,它是如何来保护SWF文件的呢?很简单,这种保护存在于你所买的Flash开发工具中。Flash开发工具不能导入有(导入)密码的SWF文件。没关系,对吧?我可以用十六进制编辑打开那个SWF文件,删除保护密码,从而也就移除了保护功能。

  如此简单,所以忘记导入保护功能吧。

  转换成放映机文件并且压缩

  如果我将它转化成exe格式的放映机文件,还可以被反编译吗?答案:是的,SWF文件仍然存在其中。借助软件可以很容易的将SWF文件从exe文件中释放出来。压缩可以使SWF文件不能被十六进制编辑器读取,压缩是一种保护措施吗?压缩算法类似于zip算法,很容易被破解。

  FLASM AND THE P-CODE

  在flash5的时代,出现了两种流行的工具,免费的“Flasm”和商业的“ASV 2.0”。Flasm就是“Flash asm”,它将SWF中的字节码解释成可理解的简短代码(p-codes)。比如“a=3”显示为"push 'a', 3", "setVariable";SWF中的字节码是:"96 08 00 00 61 00 07 03 00 00 00 1D".如果想学习“SWF格式结构”的话,这是个非常有价值的工具。

  程序员喜欢用高级语言(比如:C、C++)来开发软件,但是当讲求效率的时候,他们会在其中混合使用低级的汇编语言。因此,有时候开发者会利用Flasm编写低级别的p-codes来增加效率。所以,Flasm编辑SWF中的actionscript是强有力的。你可以参考例子,了解如何利用这种技术来优化3D代码,但是怀有恶意的用户能够“编辑”SWF文件,SWF中的任何保护措施都可以不费力的移除。我们不需要知道密码就可以移除保护措施。

  这儿有个通用、知名的技术来保护我们的影片不被偷窃并在其它的范围内显示。我们编辑脚本来检查_url属性,如果_url不是我们(合法)的范围,就使功能失效并显示一条“You are thief”的消息。可是,借助Flasm可以很容易删除这条脚本语句。不需要1分钟便可以破解这种保护措施。

  ACTIONSCRIPT VIEWER AND "void (a)<=b>"c" || 0(!1 && !0)"

  ASV(ActionScript Viewer)能够从SWF中提取出角色,例如::声音、形状和位图等都可以被窃取。

  它同样可以提取actionscript字节码,ASV 2尝试将p-codes匹配成高级别的actionscript.当遇到"push 'a', 3", "setVariable";时显示"a=3"这样的等同于actionscript的语言。然而我们能够创造没有任何模式来匹配的代码,从而破坏ASV的解析。利用Flasm,可以容易的编写不同于标准模式的代码,从而使ASV不能进行匹配工作。扰乱ASV 2工作的一句有名的代码是“;”,这是一条jung代码。它不做任何事,但是能搞乱ASV 2的工作。

  但是,当保护脚本众所周知时,ASV的作者(Burakk)当然不会放过它。这种保护技术对于ASV 3来说就失效了。

  飞速发展的反编译工具

  之后是MX时代的到来,许多反编译工具的出现,加快了Flash厄运的速度。

  现行版本的ASV 4除了显示得到匹配的actionscript代码,得不到匹配的代码以p-codes形式显示。如果解释成p-codes发生问题,将显示SWF中的字节码。它同样能够显示代码在SWF文件中所处的偏移量,这意味着它不会失效。你不可能扰乱它的工作,因为,至少它能显示SWF文件中的“字节码”。

  更甚的是,Flash MX2004提供通过JavaScript API来生成“fla”文件。那使它能够建立发布成SWF格式的fla文件。此刻,所有的东西都在那边了。

  更不用说声音、形状和位图了,偷窃者不喜欢这些东西,因为它们套容易取得了。偷窃者喜欢切的actionscript,因为其中隐藏着密码,因为其中有阻止此影片正常播放的脚本代码,

  如果ASV只能将脚本反编译成字节码,那么它对于大多数偷窃者是没有用处的。因此很多人进他们的最大努力来阻止ASV 4将脚本反编译成actionscript或者p-codes.实际上,对于大多数反编译者来说,脚本得不到匹配,反编译工具就无用了。

  这是曾经用过的一些技术,当它们在因特网上发布并且被反编译组织揭示之后,每种技术的保护效果最终都会变得非常薄弱和气数将尽。

  依据数据尺寸(句子)分块反编译

  大多数之所以能够成功的迷惑或者破坏反编译器,原因在于播放器和反编译器的不同行为。播放器逐个的执行字节码,就像现实世界中的读书一样,一个单词,接着下一个单词。然而反编译器通常将字节链分成有意义的片断,犹如现实世界中的读书一样,一个句子,接着下一个句子。

  反编译器的行为如此简单的原因在于大多数的p-code都是遵循数据大小规律的。对于字节码("96 08 00 00 61 00 07 03 00 00 00 1D"),反编译器遇到代表"push"操作的0x96时会想“push什么呢”?下个字节(0x0008)指示的内容:接下去8个字节中的内容压入堆栈,即把("00 61 00 07 03 00 00 00")压入堆栈。所以,通常反编译器依据数据大小将简短的片断切成一块一块的,这样便会解释成“push something”。因此,("96 08 00 00 61 00 07 03 00 00 00")就成为一个句子。下一个字节是下一个句子的开始,就是代表"setVariable"的0x1D.这样8个字节的"something",将被更进一步解释成一个字符串“a”和一个数字“3”。

  让我们来看一下字节码:("99 02 00 05 00 96")。0x99意味着分支(或者跳转),在哪里分支呢?接下去的是(0002),因此数据存储在机下去的两个字节中,将它在下面两个字节处截断。总之,我们知道"99 02 00 05 00"是个句子。接下去的是0x96,代表下个句子的开始。

  再看第三个例子,字节码:("88 08 00 03 00 63 00 62 00 61 00 96 07 00")。0x88代表定义常数,定义的常数内容是什么呢?后续字节(0008),表明常数内容存储在后继的8个字节中。所以,句子就是:("88 08 00 03 00 63 00 62 00 61 00")。代表下个句子开始的("96 07 00 ……),意味着将7个字节的数据压入堆栈。

  因此,字节码砍成单独的句子。每个句子由命令和数据组成,并且以命令打头。因此,每个句子都是一个基本的单元。理论上来说,对于这种方法没有什么错误。

  使播放器从句子中间开始读数据

  让我们开始讨论“是播放器从句子中间读数据”的破坏反编译器的技术。

  首先,我举一个现实世界的例子:

  John says good morning. Mary says thank you.现在生成SWF文件:

  skip 9 words Tom says John says good morning. skip 3 words back 7 wordsMary says thank you.如果逐个字读的话,结果和原来一样,然而反编译器按句子来读取,自然发生错误。第一,它知道Tom说了什么,但语法不对,汇报出错;第二,它没有看到第二个“skip”命令,因为它处于句子中间;第三,当它被迫退回7个字后,感到迷惑,认为应该从“Tom said”开始执行整个句子;第四,这个错误使它在第二行和第三行之间陷入无限循环之中。

  总之,我们增加了“Tom said”这句垃圾代码,并提供整个句子长度的错误数据大小信息。这个错误的长度覆盖了“skip”命令。

  来看个真实的例子,请注意,这些技术需要操作字节码,纯actionscript不能够实现。

  例1 :

  向前跳转的包含无效尺寸数据的死代码。

  push True branchifTrue label2 constants ''label2:push 'a',3setVariable你仔细看的话,会发现"constants ''"这行是垃圾代码,它不可能被执行到。然而,理论上,当第二行的结果为"not True"时,它将被执行。因此,反编译器尝试对它进行反编译。

  让我们来增大"0x88 - constants"后面的"sentence size",从而包括知道脚本结尾的所有字节。你知道,反编译器将把字节码砍成像这样的3个句子:

  push True branchifTrue label2 constants label2: push 'a',3 setVariable如果你试图反编译此SWF文件,根据我前面提到的4个错误,一些反编译器将碰壁。仍旧有些反编译器幸存,但只是显示:"if(false){};".ASV 3也不能显示此脚本,但是ASV 4能够显示。为了破解这个SWF,我们移除死代码"constant xxxx", (0x88和随后两个字节),然后所有的东西都得到反编译。

  这儿是zip格式的文件,将详细解释怎样制作这样的受保护文件。

  例2:

  先后跳转的包含无效尺寸数据的死代码。

  push 'b' label1:push 'a',3 setVariable branch label2 branch label1

  label2:push 'b'是句垃圾代码,我们将修改它,用来使ASV 4碰壁。让我们来修改push 'b'的"length of sentence".修改"0x96"后面的2个字节的数据,使句子的长度增长到分支Label1之前。这样,反编译器将把字节码作为3个句子:

  push label1: push 'a',3 setVariable branch label2 branch label1 label2:

  现在,反编译器不知道将把什么压入堆栈,同样它将在第一个句子和第二个句子之间形成死循环。这种技术将使大部分反编译器碰壁。Flasm、ASV 4同样也无效。为了破解这个SWF,我们手工删除"push b" (0x96和后随的2个字节),这样所有的东西都可反编译了。

  当这个技术流传后,burakk将修改ASV 4,使它能正确处理死循环。这样下个版本的ASV就可对付这种技术了。

  这儿是zip格式的文件,将详细解释怎样制作这样的受保护文件

  

  非显示字符和混淆器

  除了阻碍反编译器的技术之外,我们还可以使反编译的结果不容易读。你可以浏览关于混淆器的网站。

  基本上,它是对变量和函数的名字进行重命名。

  function -3(-4){trace(-4);} function -1(0,-2){ if(0<-2){-3(1);} }

  肯定的是,偷窃者不能仅仅是拷贝、粘贴就能使用这些代码。编译器不允许你对一个函数进行这样的命名。

  混淆器的局限是改变函数的名字可能给下面的脚本代码带来麻烦。

  function myFun(){trace("myFun");} a="my";b="Fun";this[a+b]();

  另一个技术是使函数的名字不可显示。比如,用汉字作为函数名,反编译器可能就会不能很好的显示它。然后,我们便会看到:

  function ?(){?,?){?。?=?;}

  ASV 4使用unicode编码显示不可显示字符,所以,结果是易读的,只不过增加了点轻微的难度。

  自我保护

  如果你找到一个很好的方法来保护自己的SWF不备反编译,不要与别人分享这个方法,至少不要再因特网上公开它。当然,它不能过100%的防反编译,至少对我来说是这样。但是,不是所有的人都对SWF的格式了如指掌。许多,偷窃者仅仅只会借助软件来反编译SWF.因此,如果你的目的是尽可能少的偷窃者能够偷窃你的SWF,那么请保护好你的(白虎SWF的)秘密方法。

  只是在此提醒你,你的SWF是无保护的。对于熟悉SWF格式的人来说,所有东西都是毫无遮掩的。如果你的目标只是保护“一些函数”的话,它应该是安全的。他们未必会窃取你的函数,他们会编写自己的函数。

  通用保护措施

  我们在网站上放了个联机游戏,不幸的是,许多访问者只是访问我们的站点仅仅一次而已,然后利用下载的版本来离线玩。有时,我们甚至发现我们的游戏出现在其他的站点上。

  为了避免这种情况发生,下面是可采取的保护措施:

  1. 所属领域检查

  编写脚本检查_url,如果_url是""就播放影片,否则不播放或者退出。当离线播放的时候,_url应该像"file://C| someSub/game.SWF";但它在其它domain中时,_url就形如"".因此,这个技术可以恰当的加上一些保护。当然,对于心存不良的反编译者来说是无用的。那些脚本可以借助Flasm来删除或者修改为不检查。尽管在其它公开场合未必能看到被破解的SWF文件,但是离线也能够播放的SWF就可能发生上述情况。

  2. 服务端口令验证

  编写脚本,并且在开始游戏时从服务端加载密码。如果密码为空,则停止游戏或者退出游戏。这很容易被怀有恶意的用户破解,他们只要编辑SWF文件,将那些脚本删除即可。哪些脚本不可以被删除呢?当开始游戏时,从服务端加载的地图数据是进行游戏必须的,所以心存不良的用户不可能删除这些脚本。为了进行游戏,它必须提供这些地图数据。当然,它可以从缓存在临时文件夹中的数据中挑选地图数据,提供给SWF,从而激活游戏。

  3.将SWF或者变量置于服务端

  这是第二种技术的扩展、延伸,该技术已经广泛的使用着。起初的游戏(SWF)文件只是个装载器,当单击播放(或开始)按钮后,将加载另一个SWF文件。当需要地图文件的时候,便从服务端加载地图数据。当加载数据遇到阻碍时,将从服务段再次加载受到阻碍的SWF文件。新层上的数据也是从服务端传过来。

  从这儿。我们可以看到一个原则:防止反编译的最好方法是“不给”。

  如果一些愚蠢的窃贼只下载game.SWF文件,他不可能玩这个游戏。 他需要在缓存中挑选出所有的SWF文件和变量。打开所有的SWF文件,编辑这些变量的名字,使它与缓存中的变量的名字一致。

  如果我们的地图由CGI随机产生,那么窃贼只可能拥有一份地图,他没有随机产生地图的权力。如果是个迷宫游戏的话,充其量,他只能玩一个迷宫,他没有“动态产生迷宫”的功能。如果心存不良的用户玩这个游戏将碰到一个新的阻碍,因为在他的缓存中没有这个新的受到阻碍的SWF文件,所以将无法进行游戏。

  因此,许多算法和功能都放在服务端,那个SWF文件只是个界面而已。这是个完美的保护措施,但是缺陷是这件产生一个转为游戏工作的CGI,而不是Flash.我们正在讨论关于SWF的保护问题,这个解决方案是不妥当的,因为SWF文件自身得不到保护

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34239169/article/details/85817895

智能推荐

基于改进注意力机制的U-Net模型实现及应用(keras框架实现)_u-net注意力机制-程序员宅基地

文章浏览阅读9.3k次,点赞13次,收藏120次。1.摘要上节我们基于U-Net模型设计并实现了在医学细胞分割上的应用(ISBI 挑战数据集),并给出了模型的详细代码解释,在上个博客中,我们为了快速训练U-Net模型对其进行了缩减,将庞大的U-Net的转换为很小&的结构,导致其准确率才达到75%左右。为了进一步提高U-Net模型在细胞分割上的准确率,本文将主要研究两个方面:一是基于U-Net的原始模型结构进行改进,引入卷积注意力机制模块(CBAM)和FocalTversky损失函数;二是引入深监督方法(DEEP SUPERVISION)及多尺._u-net注意力机制

学习SqlSugar的基本用法(增删改查)-程序员宅基地

文章浏览阅读2.4k次。学习并测试SqlSugar中最基本的增删改查函数的用法,_sqlsugar

VMware下安装Ubuntu过程与可能遇到的问题_用vm安装ubuntu一安装就关机-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏6次。虚拟机安装ubuntu详细教程·_用vm安装ubuntu一安装就关机

OCP12C题库,62数据库备份与恢复(admin,install and upgrade accelerated, backup and recovery workshop -62)(新增)_lgwr might write redo generated by the insert stat-程序员宅基地

文章浏览阅读1.2k次。01 which two statements are ture about using SQLLoader?关于使用SQLLoader,哪两条语句是正确的A、it can generate unique sequential key values in sppecified columns它可以在指定的列中生成惟一的顺序键值 E、it can load data into multiple tables using thesame load statement 它可以使用相同的load语句将数据._lgwr might write redo generated by the insert statement to the redo log befo

代码已提交 但未push前如何撤回_git 取消未push到远程仓库的代码-程序员宅基地

文章浏览阅读610次,点赞8次,收藏11次。已经在 Git 中提交,但还没有将这些提交推送(push)到远程仓库,可以使用 git reset 命令来撤销最近的提交。这个命令将会撤销最后一次提交,但会保留暂存区和工作区的更改,使得你可以重新提交这些更改或者修改后再提交。_git 取消未push到远程仓库的代码

centos中安装和配置mysql-程序员宅基地

文章浏览阅读130次。直接上干货,1、使用wget命令下载安装包,[root@priseapp1 ~]# wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm2、安装mysql源码[root@priseapp1 ~]# yum localinstall mysql57-community-release-el7-8.n...

随便推点

panabit安装和默认密码_panabit ssh密码-程序员宅基地

文章浏览阅读8.8k次。panabit安装和默认密码我使用的版本1、在VMware里新建一个虚拟机2、选择 free BFD3、给虚拟机命名5、给虚拟机配置如下6、下面的地址按照自己的ip来设置7、登录界面啊啊在这里卡了好久,看肖哥视频说登录账号和密码是 root 和 root ,一直以为是我操作有问题,重新进了n遍。后面跑论坛才搜索到,帖子地址:http://forum.panabit.com/thread-22321-2-1.htmlpanabit或 free bfd 登录密码login_panabit ssh密码

计算机毕业设计 jsp毕业生管理系统ssh 毕设-程序员宅基地

文章浏览阅读186次,点赞7次,收藏5次。E-R模型法的构成元素有:实体、属性、联系,E-R模型可以用E-R图来表示,是对用户工作环境中所相关的事物给予提示,对实体特性的描述就是属性。数据库概念模型是为了将现实世界中信息进行抽象而设计的,从而实现信息世界的建模,因此,概念模型是进行数据库设计的重要工具。在概念模式的设计中,E-R模型法是最常见的设计方法。设计概念就是在数据分析的基础上自下而上的对整个系统的数据库概念结构进行设计。数据库的设计一般要可以分为个步骤:分别是分析需求、设计概念、设计逻辑、设计物理。图3-1系统功能模块图。

Java基础-面向对象_面向对象 java-程序员宅基地

文章浏览阅读158次。类(Class)和对象(Object)是面向对象的核心概念。类是对一类事物的描述,是抽象的、概念上的定义对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。可以理解为:类 = 抽象概念的人;对象 = 实实在在的某个人面向对象程序设计的重点是类的设计类的设计,其实就是类的成员的设计。_面向对象 java

h5面试题总结-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏43次。导航的解析流程1.导航被触发。2.在失活的组件里调用beforeRouteLeave守卫3.调用全局的 beforeEach 守卫4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)5.在路由配置里调用 beforeEnter6.解析异步路由组件7.在被激活的组件里调用 beforeRouteEnter8.调用全局的 beforeResolve 守卫 (2.5+)9.导航被确认10.调用全局的 afterEach 钩子11.触发 DOM 更新12.调用bef_h5面试题

【转载】Tensorflow[源码安装时bazel行为解析]_bazel使用的是gcc还是nvcc-程序员宅基地

文章浏览阅读390次。【转载】Tensorflow[源码安装时bazel行为解析]https://www.cnblogs.com/shouhuxianjian/p/9416934.html0. 引言通过源码方式安装,并进行一定程度的解读,有助于理解tensorflow源码,本文主要基于tensorflow v1.8源码,并借鉴于如何阅读TensorFlow源码.首先,自然是需要去bazel官网了解下必备知识,如(1)什么是bazel; (2)bazel如何对cpp项目进行构建的; (3)bazel构建时候的函数大_bazel使用的是gcc还是nvcc

《所长林超跨学科通识课》模型 整理&笔记&导图_所长林超跨学科百度网盘-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏10次。思维&模式 工具箱_所长林超跨学科百度网盘