【问题标题】:Making a hack proof game in Javascript [closed]用Javascript制作防黑客游戏[关闭]
【发布时间】:2011-03-11 06:11:36
【问题描述】:

假设您使用 HTML5/JavaScript 创建了一个在线游戏。所有代码都将下载到用户的浏览器中,然后他们将运行游戏。

你如何阻止某人将游戏复制到他们的计算机上,并注入函数和模块来作弊?例如,他们可以编写一个自动瞄准最近的敌人精灵的函数。

有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

【问题讨论】:

  • 我认为这是不可能的。 JS 都是客户端,这意味着客户端几乎可以为所欲为。
  • 在线多人游戏规则 #1:永远不要相信客户。
  • 我回滚是因为我喜欢这张照片,这张照片有助于表达我的感受
  • 我们需要更多这样的问题,我所说的这样的意思是更多的问题,带有非常合适的图片,真正让我们明白这一点。
  • @Seanizer,没问题!她是一位女士,她在电脑上想知道如何保护她的 Javascript 代码。

标签: javascript security game-engine


【解决方案1】:

理论上,您是在与黑客进行游戏。你不能赢得这场比赛,但你让它具有挑战性。

我的建议是尽可能多地使用服务器端逻辑,并使用 Javascript 混淆。

Javascript 混淆会使代码难以理解,但更好的是,它可以让您发布数千个版本的代码,同时保持相同的代码库。

我曾经使用过JScrambler 来执行此操作。黑客不必破解一款游戏的代码,而是必须破解数千个版本的代码! :)

【讨论】:

    【解决方案2】:

    他们可以编写一个自动瞄准的函数 例如在最近的敌方精灵。

    即使对于大多数处理发生在服务器端的游戏,您也可以这样做!您只需要足够快地分析显示即可。

    您甚至可以重新实现部分游戏 AI 来尝试预测机器人将如何移动。如果您无法访问游戏的源代码,这不是一件容易的事,但如果您记录大量游戏时间,则可以应用机器学习技术。

    有什么基本的方法可以 保护人们不做这种 通过在 某种方式?

    不要忘记您可以改变游戏本身,而不仅仅是它的实现方式。例如,使用随机生成的关卡而不是静态关卡,使用人类玩家而不是机器人,使您的艺术/精灵更复杂,更多地使用音频,限制光标移动的速度,增加冷却时间武器,添加隐藏的危险,等等。

    【讨论】:

      【解决方案3】:

      这就是为什么大多数 JavaScript 游戏大量依赖服务器状态来防止作弊。

      【讨论】:

      • 出于兴趣,您是指“中继”还是“依赖”?它们都有意义,但每个似乎都暗示着一些稍微不同的东西。 =)
      • 所有其他答案都说无法完成, 这当然是错误的。可以做到——只需在服务器上进行所有计算。这引入了延迟,这使得实时游戏变得困难。您想要的实时性越高,您必须牺牲的安全性就越多(所有游戏都是如此,而不仅仅是 javascript 游戏)
      • BlueRaja:那如何禁止人们编写一个自动瞄准最近的精灵的函数?好的,它使墙黑客之类的事情变得更加困难,但仍然可以伪造用户输入,并且仍然可以解析输出并以不同方式显示。
      【解决方案4】:

      我认为要走的路是编写客户端,以便您动态更改客户端代码并验证在服务器上使用由此创建的代码。

      例如有这样的命名空间

      window.mynamespace = {
      
          foo : function(){
              // some stuff here
          },
      
          bar : function(){
              // some more stuff here
          } 
      }
      

      其中包含您的所有客户端代码,并使您的所有服务器方法都需要一个令牌,该令牌是先前对代码库进行动态评估的结果。通过重新定义方法和更改方法名称使这变得更加困难。以下是一些示例挑战(这仅在挑战是动态创建且不可预测的情况下才有意义)。所有这些都首先包含一个任务,然后是一个质询,该质询将用于为下一个请求创建授权令牌。 (这些是来自 ajax 调用的响应对象)。基本上,任务将被评估,评估挑战的结果将是下一个令牌。

      {
          task: "mynamespace.baz=mynamespace.foo;mynamespace.foo=undefined;",
          challenge: "mynamespace[11].toString().substr(10,22)"
                  // get part of a well-known functions source code
      }
      
      {
          task: "mynamespace.bar=function(){ /* new code here */ }",
          challenge: "var xy=0;mynamespace.each(function(item){xy+=item.toString().lastIndexOf(';')}); xy"
                  // accumulate the last index of a semicolon in all elements
                  // of the namespace
      }
      

      为了克服这个问题并仍然获得有效的授权令牌,客户端必须编写一个完整的 javascript 仿真层。虽然可以做到,但我会尝试经常以基本方式更改服务器代码,以使这种技术几乎不可能实现(因此模拟层不知道要模拟什么)。

      【讨论】:

      • 投票者是否愿意详细说明?
      • 你的帖子让我头晕 O_o .. 仍然是一个很棒的方法.. 可以为它制作一个完全可重复使用的包装器。
      • 您知道这方面的任何实际实现吗?这是一个很棒的主意,但 AFAIK 没有人这样做。
      【解决方案5】:

      travian(http://www.travian.us/) 是在 DHTML 中运行的大型游戏的一个很好的例子,它存在大量客户端滥用问题。仅仅在 Firefox 中安装油脂猴子就为各种剥削行为打开了一扇相当大的大门。也就是说,它们似乎使游戏保持了一定的功能,因为大多数漏洞利用似乎都围绕着常见的游戏内任务的自动化,而不是直接违反游戏的内部域逻辑。 请记住,此示例远非仅使用 JS 运行,而是很大程度上依赖于服务器端控件。

      【讨论】:

        【解决方案6】:

        一些想法

        服务器端:

        • 在服务器端存储游戏内部状态,并在服务器端检查客户端发送的输入。

        • 自动瞄准:创建普通玩家看不到的假精灵,如果他们经常被击中,你有一个机器人。 (并不总是有效,因为机器人可能会更新以检查隐身)

        • 检查客户端对服务器更改的反应时间,检查是否有太多太快的反应。 (在做出反应之前必须接受大量快速响应,因为人类可以快速做出反应,并且时间必须考虑到网络延迟才能捕捉到任何东西)。给玩家某种验证码,普通玩家永远看不到。

        客户端:

        • 使用混淆来增加与代码交互的难度

        • 检查您所知道的 hack 中定义的函数。必须经常修改/更新,因为此类黑客的创建者可以解决这些问题。

        • 游戏设计:减少游戏的重复性,这使得为其编写工具/机器人变得更加困难。

        • 不时更新客户端以更改其部分结构。虽然这不会阻止机器人,但需要努力让它们保持运行。要么让它对用户透明,要么用新功能伪装。

        重要提示:确保您的服务器界面检查用户输入,混淆和客户端检查不会帮助防止有人编写自己的客户端。

        【讨论】:

          【解决方案7】:

          您可以将代码调用的所有内容放入闭包中:

          (function() {
            var cantSeeMe = function() {
              // do some game stuff!
            };
          
          })();
          

          在闭包之外,非常很难获得“注入黑客”的代码(例如覆盖控制台上的函数)。这不会阻止某人重写您的代码,但通过打包程序传递东西,甚至 closure compiler 会使您的代码很难阅读/修改......(看看jQuery min

          总而言之,任何运行客户端的游戏都是可破解的。

          【讨论】:

            【解决方案8】:

            免责声明:这是一种糟糕的方法,而且可能付出的努力太多。

            假设您在发送之前有一个处理 javascript 代码的方法。

            首先,每个方法都有一个 ident 变量,它附加到每个函数的结果(即每个函数都会返回 {ident:"special code",result:"actual useful function result"})。您还有一个testIdent() 函数,该函数将接受要调用的函数名称以及提供它的“测试数据”(如果需要)。 testIdent() 的目的是将上述函数返回的 ident 发送到服务器进行验证(这个想法是服务器可以在您认为合适的时候请求测试)。每个函数的ident在发送前应为指定用户随机记录。

            其次,在将代码发送到客户端之前,函数顺序是随机的,函数名称会以某种随机方式进行混淆。这样黑客就无法在函数 x() 中查找某个变量 ident,因为它会被随机命名。此外,如果每个变量名称也被随机混淆,那将是另一个加分项,只是为了给......每个人的复杂性和头痛增加一个步骤(我告诉过你这是一种糟糕的方法)。

            现在,假设采取了适当的步骤来确保代码始终正确运行,那么黑客是非常聪明的人,如果他们有足够的决心,仍然有办法跟踪此代码。至少一种方法是搜索关键代码结构,例如具有一定数量元素的 switch 语句,或具有 x 条语句的 for 循环等。虽然这些中的每一个可以通过在开关中添加虚拟的case 语句或在代码中随机添加几个if(true) 位来进行反击,反击黑客将始终是一场持续的(并且可能是一场失败的)战斗。

            希望这能给你一些想法。我不知道有人会如何准确地实现这一点,但这至少是一个想法。

            祝你好运!

            【讨论】:

              【解决方案9】:

              有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

              唯一明智的方法是将关键代码片段保留在您控制的服务器上,并且永远不要将其提供给用户的计算机。困难的部分是让游戏保持足够快的速度以使其可玩。

              【讨论】:

                【解决方案10】:

                我喜欢这个问题,虽然可能有更好的答案,但这里有一些可能(或可能不)有效的想法:

                • 混淆。是的,这并不能保证,最终有人可以做到,但有时处理起来很麻烦。
                • 每次使用新的临时令牌生成 JS。您可以将运行代码的 .js 模板化,并插入一个服务器生成的令牌,每个实例都不同。令牌可能是临时的,它可能是验证代码真实性的一种方式
                • 可能有一些方法可以确定正在运行的脚本的正确位置 - 但这可能是伪造的

                一般来说,这很难,并且上述所有建议都可以解决。我想关键是要让他们难以作弊,但鉴于即使是安全的在线模式游戏也有作弊者,所以很难防止 JS 游戏也容易受到这种影响。

                【讨论】:

                  【解决方案11】:

                  你正在尝试做不可能的事。我能给你的最好建议是,如果你打算保留任何数据,如硬币/金钱/黄金、级别等,请确保永远不信任客户端,并尽可能多地在服务器端进行逻辑处理。

                  【讨论】:

                    【解决方案12】:

                    简而言之,不。但是,您可以obfuscate Javascript 使其变得更加困难。

                    对于诸如分数之类的东西,理论上用户可以将任何分数发布到您的处理程序脚本中。在这种情况下,您可以使用会话并通过 AJAX 定期回发到服务器。

                    【讨论】:

                    • 即使有最严重的混淆,他们也可以使用 Firebug 即时解释它并找出哪个做了什么。
                    • @Kim Jong Woo:是的,但仍然不简单。
                    • 对于那些打算破解或欺骗浏览器多人游戏的人来说足够直截了当,我认为这是 OP 所关心的。
                    【解决方案13】:

                    是什么阻止了别人抄袭 游戏到他们的电脑上,并且 注入函数和模块 作弊?

                    什么都没有。

                    有什么基本的方法可以 保护人们不做这种 通过在 某种方式?

                    没有。

                    【讨论】:

                    • 谷歌在几周前做了一些有趣的工作来保护他们的吃豆人游戏。
                    • 您可以投入大量精力来混淆您的代码以使其更难,但正如@js-bangs 所指出的,在功能上没有办法完全阻止它。如果是客户端操作,客户端有,可以修改。
                    • @JS Bangs:你的回答太错误了,而且没有受过教育,会伤害阅读。与您相反,我确实在(商业)计算机游戏行业工作。像暴雪的重磅炸弹魔兽争霸III这样的游戏正在服务器端复制整个游戏状态,并且只传输玩家所做的输入。发送无效的游戏状态是不可能在战网上玩的。除此之外,如果“机器人”伪造输入,则有 很多 的启发式方法可以捕获机器人,并且经常会有因 busted“机器人”而失效的许可证密钥目的。你只是SO错了。
                    • @Webinator - 你暗示自己人们知道如何制作机器人,对我来说,这只会强化 JS Bang 答案的第一部分。你接着说有“很多启发式”用来捕捉机器人,这让我觉得难以置信的是特定领域的,而不是游戏本身设计的基础。你所证明的只是阻止作弊是可能的,并且通过大量的开发投资,作弊可以被最小化。
                    • @Webinator,我还假设我们谈论的是一个主要或完全是客户端 JavaScript 游戏。显然,如果您将整个游戏状态放在服务器上并回传每个用户操作,则可以最大程度地减少作弊,但这不是我认为 OP 所描述的情况。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多