|
概述
我想谈一谈软件水印技术,应为我想在我的软件项目中使用这种技术。这种技术在最底层次提供数字水印从而保护软件的知识产权。如果你想开源的你软件或者包含一些机密信息,这个或许对你有些帮助。我曾今在一些恶意软件中看到这种东西,而且我也能给软件嵌入水印。详细过程后面会讲述。这里我要说的是关于在汇编语言基础上如何给软件嵌入水印。水印技术将会提供一种安全的机制独一无二的标识软件开发商或者软件用户的身份。
汇编代码水印
软件水印技术意思是在程序代码中能够通过数字标识或验证水印。实现这个的最好的方式是在最底层即汇编代码层嵌入水印。这里并不推介使用C++,不同平台和编译器生成的代码也不尽相同。相比起来,汇编语言是最低层的语言。当然,这里指的是向一个工程中添加汇编代码或者修改本身就是汇编语言编写的工程。为了添加特有的水印我们可以利用以下技术:
添加垃圾代码
修改代码使其符合特定样式,并且程序能够正常执行
第一种方法在其它文章中就已经被提及,参考[1]。意思是通过添加垃圾代码来标识软件来源。让我们看看下面的例子:
代码:
push eax
mov eax,12
pop eax
上面的代码就是所谓的垃圾代码,因为当这三行程序执行后EAX的值并没有改变。然而,从上面的代码中却可以提取出软件使用者的身份标识(12)。这个标识现在可以用来查看授权用户或者一些其它信息。这样的水印(更像一个签名)很容易嵌入,当然也很容易被检测并去除。显然,有许多插件供享有的调试器使用来检测并去除垃圾代码,所以这种水印签名技术并不是很安全。
第二种方法是在软件能够正常执行的基础上修改代码使其符合特定的样式。看看下面的代码:
代码:
xor eax,eax -> mov eax,0
inc eax -> add eax,1
上面的代码并不是完全相同,当然构造出这样的水印算法并不容易(找到可以等效替换的代码),但是对于那些想去除水印的人来说检测水印也变得比较困难了。如果知道你想要找的一个特定的汇编指令那就很容易找到,但是黑客并不知道找什么指令。
笔者推介构造超过三段大小(48 bytes)的转换代码作为水印,就不易被发现了。如果软件是用汇编语言编写的,可以在源代码的基础上构造代码水印。这对于保护开源软件知识产权来说是非常有帮助的。
文件水印
正如参考[1]提及的使用水印文件与用户身份标识联系起来作为水印。水印文件包含如何修改代码使其能够符合特定的样式并能被识别的信息。水印文件中应包含不同的水印构造方式以确保安全性。水印将包含用户的身份标识,以便开发商可以从中提取。
相对于上面提到的第一个例子,水印文件因该包含一些垃圾代码,而用户的标识信息将通过指令"mov eax %id"的形式被存储。对于第二个例子,水印文件应该包含如何构造代码水印的信息,以达到符合特定的水印。这里必须要注意严格保密水印文件,在公司内部要限制水印文件的访问(即使是开发人员)。
对于第一种方法,这里给出一些想法和例子:
代码:
Adding junk code - this can also be junk instructions
like adding mov ecx,1984 somewhere in the code where ecx is unused
xor ebx,0
nop
nop
add eax,12
sub eax,12
对于第二种方法的例子:
代码:
Assembler Instruction Transformations which are equal in execution:
xor eax,eax -> mov eax,0 -> sub eax,eax -> and eax,0
inc eax -> add eax,1
shl edx,1 -> imul edx,2
rol eax,16 -> ror eax,16
xchg eax,eax = nop
当然可以更进一步的转换汇编指令。为了使其更难被发现,第二种方法有必要增加更多的运算。可以将简单的汇编指令转换为多条复杂的汇编指令(如push、loop、stosd)。但是这样做带来的弊端是代码的体积越来越大,运行效率也越来越低。
结束语
通过汇编代码实现软件水印技术是保护知识产权的一种安全的方式。它给予软件代码独一无二的标识。对于防止软件抄袭有很大的帮助。而且给软件嵌入水印的工作量也相当小。
参考
[1] http://www.cs.sjsu.edu/faculty/stamp...eportSmita.pdf |
|
|
|
|
|
|