【问题标题】:C# put date into program when compiledC#编译时将日期放入程序中
【发布时间】:2008-11-26 14:32:11
【问题描述】:

我正在考虑如何创建一个仅在 X 时间段内有效的程序(在 C# 应用程序中)。

我当时的想法是,您可以在程序中将当前日期作为常量,它会检查它是否比该日期大 X 天。当然,我不想将日期或 X 存储在程序之外,因为它可以被篡改。

我也不想定期手动更改它并重新编译和部署它。那么有没有办法将变量设置为编译时的当前日期?

我可以有一个批处理文件来编译它并将新的 exe 部署到分发服务器。

谢谢

【问题讨论】:

    标签: c#


    【解决方案1】:

    预编译指令是您的关键。您可以在应用程序中创建一个常量并在编译时设置它。

    不过,请务必混淆您的代码。有人可以轻松拆卸它并篡改常数。另一种解决方案是让您的软件“打电话回家”进行自我注册。这样,注册信息就会存储在您的服务器上,而不是他们的机器上。也有第三方软件包可以提供与您所寻找的相同的安全性,但它们昂贵

    【讨论】:

    • 好主意。混淆是必须的(不是我知道怎么做!:p)..谢谢
    • 您对反汇编问题的看法也是正确的,但在 C# 中不确定是否有避免这种情况的好方法。
    【解决方案2】:

    查看项目中 Properties 文件夹中的 AssemblyInfo.cs 文件:

    // You can specify all the values or you can default the Build and Revision Numbers 
    // by using the '*' as shown below:
    // [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]
    

    将其更改为:

    [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyFileVersion("1.0.0.0")]
    

    然后,在程序集的其他地方,使用这个:

    System.Version MyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
    
    // MyVersion.Build = days after 2000-01-01
    // MyVersion.Revision*2 = seconds after 0-hour  (NEVER daylight saving time)
    DateTime MyTime = new DateTime(2000, 1, 1).AddDays(MyVersion.Build).AddSeconds(MyVersion.Revision * 2);
    return string.Format("Version:{0}  Compiled:{1:s}", MyVersion, MyTime);
    

    【讨论】:

    • 这是一个很容易找到程序集何时编译的好方法;然而,它怀疑同样的反编译/重新编译问题,所有其他这样做的方法也有......
    • 如果他们正在反编译您的代码以获取您的日期...他们可以反编译您的代码以调用您的代码。掩盖这个日期是一种错误的措施,不能提供任何保护。
    • 这就是我推荐“电话回家”方法的原因
    • phonehome不就是换问题吗?现在,您必须管理他们可以修改的身份。
    • 他们还可以修改他们正在打电话的家庭。
    【解决方案3】:

    我会选择“电话回家”的变体。并让这个电话变得重要。 ;) 我的意思是,您程序中的一些重要功能(可能是一些计算?)将在服务器上进行。因此,如果用户反编译程序并删除该“回电”,它将使程序无用。

    我知道并非所有程序都具有使这成为可能的规范,但比您通常想象的要多。

    【讨论】:

    • 打电话回家是个好主意。但从你们所说的来看,我意识到这根本不是一个简单的答案。谢谢
    【解决方案4】:

    在您的自动化构建过程中(您确实使用了自动化构建过程,对吗?),有一个简单的应用程序可以生成一个单行 C# 类

     public struct TimeLimit { public DateTime Date = new DateTime(2009,1,1); }
    

    自动更改日期,然后编译。

    然后只需在您的应用中引用 TimeLimit.Date。

    【讨论】:

    • ...但可能会混淆,而不是称之为 TimeLimit! ;)
    【解决方案5】:

    我知道这是一个 3 年前的问题,但只是为了增加我的 2 美分。我们使用 James Curran 建议的结构中硬编码的“DateLimit”。

    但我们也使用相同的“日期”作为“加密”和“解密”(更多代码和解码)所有字符串、标签、消息的简单密钥。如果某些人(我们称他们为作弊者)想要更改过期日期,他们将不得不通过整个程序集重新正确输入所有这些字符串以获取新的过期日期。这并不完美,但我们的成本现在接近于零,而作弊者的成本很高。

    【讨论】:

      【解决方案6】:

      我建议您将日期放在一个单独的、强命名的程序集中 - 这样至少恶意用户会发现很难反汇编、编辑和让您的程序使用它。有没有办法让两个程序集根据强名称相互验证?

      我们将此作为我们其中一个组件的许可控制的第一步。如果调用程序集与受许可证控制的程序集具有相同的指纹,我们假设它正在我们自己的软件中使用并且许可被绕过。如果调用程序集有不同的指纹或根本没有打印,则执行正常的许可证检查。当我想到它时,我们的用户可能可以在没有强命名和绕过许可的情况下反汇编、编译。但话又说回来,我们所有的程序集都是作为 x86 而不是 CIL 交付的——这会改变什么吗?

      我们的经验是,如果您与企业客户打交道,没有人可以承担篡改您的东西的麻烦,尤其是因为存在被抓的风险。有一点很长的路要走,我们当前的许可解决方案已经过时了(该软件包包括 VC5 的示例!)但到目前为止已经是一个足够高的障碍。另一方面,对于消费者,我可以想象这是一个更大的威胁。

      我最初的建议似乎产生了更多可以回答的问题——也许毕竟没有那么有用。 :)

      【讨论】:

        【解决方案7】:

        .Net 的问题在于它很容易反编译和更改您想要使用的日期是恒定的。您可能需要考虑其他事情。

        您可以将其写入注册表,但随后人们将编辑此值。

        它们不是一个完美的解决方案,但拥有一个通过外部(网络)服务器验证的帐户是个好主意。

        【讨论】:

          猜你喜欢
          • 2011-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多