【发布时间】:2009-08-14 04:06:45
【问题描述】:
是否可以知道 const 变量在 exe 中的位置?我们正在考虑为我们的程序添加水印,以便从我们的服务器下载程序的每个用户都将在代码中嵌入一些唯一的密钥。
还有其他方法吗?
【问题讨论】:
标签: c# .net security compiler-construction watermark
是否可以知道 const 变量在 exe 中的位置?我们正在考虑为我们的程序添加水印,以便从我们的服务器下载程序的每个用户都将在代码中嵌入一些唯一的密钥。
还有其他方法吗?
【问题讨论】:
标签: c# .net security compiler-construction watermark
您可以构建带有水印的二进制文件,该水印是 .net 类型中 GUID 的字符串表示形式,作为常量。构建后,在二进制文件中搜索 GUID 字符串以检查其位置。您可以将此 GUID 值更改为另一个 GUID 值,然后运行二进制文件并在代码输出中实际看到更改后的值。
注意:格式很重要,因为长度非常重要,因为您正在处理已编译的二进制文件。例如,您需要保留 GUID 的前导零,以便所有实例在转换为字符串时具有相同的字符长度。
我实际上已经用 Win32 DLL 甚至 Sql Server 2000 Desktop exe 做过这种事情。 (有一个 hack,您可以通过翻转二进制文件中的开关将桌面版切换到完整的 SQL 服务器。)
然后,这个过程可以自动化,一个新的 DLL 副本将由一个小的服务器端实用程序以编程方式为每个客户端下载进行更改。
也看看这个:link
它讨论了在 .Net DLL 中存储设置的使用,并使用基于类的方法并嵌入应用程序设置文件并在编译后可配置。
【讨论】:
关键考虑因素 #1:大会签署
由于您正在分发您的应用程序,显然您正在签署它。因此,由于您正在修改二进制内容,因此您必须将签名过程直接集成到下载过程中。
关键考虑因素 #2:const 或 readonly
const 和 readonly 变量之间存在许多人不知道的关键区别。特别是,如果我执行以下操作:
private readonly int SomeValue = 3;
...
if (SomeValue > 0)
...
然后它会编译成如下的字节码:
ldsfld [SomeValue]
ldc.i4.0
ble.s
如果您进行以下操作:
private const int SomeValue = 3;
...
if (SomeValue > 0)
...
然后它会编译成如下的字节码:
{contents of if block here}
const 变量[允许] 由编译器替换和评估,而不是在运行时进行评估,其中readonly 变量总是在运行时评估。当您将字段公开给其他程序集时,这会产生很大的不同,因为对 const 变量的更改是一个重大更改,会强制重新编译所有相关程序集。
我的建议
我看到两个相当简单的水印选项,虽然我不是该领域的专家,所以不知道它们总体上有多“好”。
最后,Google 报告了以下article on watermarking software,您可能想看看。
【讨论】:
在 C++ 中(例如):
#define GUID_TO_REPLACE "CC7839EB7EC047B290D686C65F98E0F4"
printf(GUID_TO_REPLACE);
在 PHP 中:
<?php
exec("sed -e 's/CC7839EB7EC047B290D686C65F98E0F4/replacedreplacedreplacedreplaced/g' TestApp.exe > TestAppTagged.exe");
?>
如果您将编译后的二进制文件粘贴到服务器上,请访问 php 脚本,下载标记的 exe,然后运行它...您会看到它现在打印“替换”字符串而不是 GUID :)
请注意,替换字符串的长度必须与原始字符串的长度相同(在本例中为 32),因此如果您想用更短的内容标记它,则需要填充长度。
【讨论】:
我不确定你所说的 const 值的“位置”是什么意思。您当然可以使用反射之类的项目来访问特定类型的 const 字段。常量字段与具有相同可访问性的任何其他非实例字段一样绑定。我不知道这是否符合您对位置的定义。
【讨论】: