如何隐藏C++源代码不让客户看到

3

我希望向我的客户发送一些组件。我想要发送源代码的原因是:

1)我的类是模板化的。客户可能使用任何模板参数,所以我无法预编译并发送.o文件。

2)客户可能使用不同于我的gcc编译器版本。因此我希望他在自己的环境中进行编译。

现在,出于明显的原因,我不能透露我的源代码。我最多只能透露.h文件。有什么办法可以实现这一点吗?我正在考虑一些钩子,支持在编译之前进行解密等操作。这是可能的吗?

简而言之,我希望他能够编译这段代码,同时又不能窥视其内部。


3
现在,由于明显的原因,我不能透露我的源代码。但你计划发送源代码进行编译,这对我来说并不完全明显,请详细说明一下? - shuttle87
6
你必须下定决心。要么提供源代码,要么不提供。你不能没有提供源代码就提供源代码。源代码的整个意义在于它可以被阅读和编译。你可以将其加密并与解密密钥一起提供(就像商业 DVD 一样),但基本上它必须能够被你的客户(或他的编译器)阅读。 - CB Bailey
2
你可以删除所有的注释。 - Paul R
2
由于原因并不明显,请您详细阐述一下? - Bill
2
@deeJ:啊,你不想公开你的源代码,因为你错误地认为这样可以保护你的代码秘密。这一点并不明显。祝你好运! - Bill
显示剩余7条评论
7个回答

11

合约=好,混淆=不好。

话虽如此,你总是可以使用一种PIMPL惯用语法为客户提供二进制文件和头文件中的模板包装器。其思想是使用一个“非类型化”的分别编译的实现,其中模板包装器仅为客户端代码提供类型安全性。在编译器开始理解如何优化模板之前,这通常是人们处理事物的方式,即避免机器码层面的代码膨胀,但它仅提供了一些保护措施,防止简单的复制和粘贴盗窃,而不是任何针对愿意深入研究机器代码的人的保护。

但也许这样做的工作量比重新发明功能还要大呢?


3
谢谢你花费时间写出如此详细的答案!+1 - Vinzenz
在我这种情况下,您说反向工程的努力会比重新发明更大,这一点是正确的。话虽如此,您能否详细说明您的解决方案,并可能附带一个示例链接? - deeJ
1
感谢@paul_71(请参见他在其他线程中的评论),您可以简单地在Google上搜索“薄模板惯用语”。祝好! - Cheers and hth. - Alf

5

在Alf的回答中,只是加入了一些术语:你可能会看到Thin模板习惯。它基本上模拟了通用功能。不要被谷歌搜索出来的维基百科文章所混淆,您不必使用void* ...

当然,这并不能保证二进制兼容性。通常情况下,“本地”c++需要为客户平台自己编译组件并部署二进制文件,或者提供给他们您的代码...与纯通用组件代码的区别在于您可以完成前者。


4

3
选择C++模板肯定已经是混淆的好开始了,是吧? - JUST MY correct OPINION

3
首先,如果你打算提供源代码,那么你必须提供完整的源代码。当然,你可以加密它,但即使GCC有一个“解密编译”选项,它也需要解密代码,而如果GCC能够解密代码,那么你的客户也可以。
你所要求的是不可能的。(如果你找到了一种方法,我相信电影业可能会与你签订数百万合同。他们目前只能使用昂贵的定制硬件来防止人们复制内容,而这只能在有限的程度上起作用)
至于你所谓的“显而易见的原因”,为什么你不想提供源代码,我不明白为什么它们显而易见。如果你提供源代码会发生什么?
你有两个选择:
- 提供完整的源代码;或者 - 将所有可以预编译的内容编译成(静态或动态)库,并向客户提供该库以及头文件。

"that only works to a limited degree" 的意思是“只能在有限的程度上起作用”,对吗? - JUST MY correct OPINION

1

关于 pimpl,有什么想法吗?


1
好的备注。我认为它有效。你必须将实现结构体和工作类都进行模板化。 - Benoit

1
1)我的类是模板化的。客户可能使用任何模板参数,因此我无法预编译并发送.o文件。 2)客户可能会使用不同于我的gcc编译器版本。因此,我希望他在自己的端上进行编译。 现在,由于明显的原因,我不能透露我的源代码。我能做的最多就是透露.h文件。有什么想法可以实现这一点吗?我正在考虑一些钩子,在gcc中支持解密编译之前等等。这可行吗? 简而言之,我希望他能够编译此代码,而无需能够窥视内部。
考虑上述第2点包括A)ABI差异,即在同一平台上使用不同编译器版本/供应商编译的相同代码不兼容,以及B)代码可能依赖的系统库、内核版本等的差异。唯一的通用解决方案是在特定平台上进行编译。要么您为所有平台都这样做,要么您将所有源代码都提供给他们,让他们这样做。这不仅仅是头文件和模板实现,还包括您的外部函数。您可以通过构建更具互操作性的extern "C"函数墙来缓解A),但是当涉及到B)时,您基本上是被卡住了。

那么,你能在编译期间解密吗?只有在向他们提供为其特定系统构建的自己破解的GCC二进制文件时才可以,这可能比提供自己的库的不同版本更麻烦(尽管它可能解决模板/头文件曝光问题)。

或者,您可以使用源代码混淆技术。这可能是实际上最好的方法了。我不知道有哪些工具,但这是人们追求几十年的方法(尽管我还没有听说过有人推荐它),所以肯定有一些成熟的工具。

关于模板化代码-其他人建议将模板化前端用作预编译对象提供C风格的通用实现。这可能是可行的(明显存在性能下降的风险,并且您必须捕获要求的一组类型特定操作-例如通过从抽象操作基类派生出一个类型特定的类进行实例化),但无论如何,预编译对象仍然会遇到B的问题)。

另一个想法是...客户可能会拿走你的源代码,但不太可能像你一样理解它。即使他们构建更多依赖于其版本的系统,从某种意义上说,他们会变得更加被锁定,并且将来可能更需要你的服务。而且,如果你发现他们没有公平竞争,到时候你可以适当地向他们收费。

0

看起来gcc 4.5支持插件。因此,您可以提供自己的.so文件,在编译阶段开始之前调用它。因此,您可以在其中拥有各种技巧(例如源文件解密),并且这些技巧被巧妙地隐藏。这也是可移植的解决方案,因为没有对g++本身进行任何更改。

这正是我一直在寻找的。您可以在此处阅读更多信息: http://www.codesynthesis.com/~boris/blog/2010/05/03/parsing-cxx-with-gcc-plugin-part-1/


1
事实证明,这并不是我一直在寻找的万能解决方案。存在许可问题,每个插件都必须使用GPL发布。我的希望落空了,无法实现解密算法 :) - deeJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接