11

I have a proprietary application I would like to hand out to a few people for testing, except we do not want to reveal the source to them. The application is written in C++ for Linux. It links against readily available packages on the Fedora/Ubuntu repos.

Is there any way to process the source to something intermediate... then distribute it, and have the users do a final compile which actually compiles and links the intermediate code to their native platform.

I am trying to see if there is any alternative to distributing precompiled binaries. Thanks.

hhafez
  • 38,949
  • 39
  • 113
  • 143
The Unknown
  • 19,224
  • 29
  • 77
  • 93
  • I had a very similar question http://stackoverflow.com/questions/1025494/obfuscating-c-c-code – hhafez Jul 16 '09 at 04:27
  • What's the motivation? Is there any particular reason why they can't be allowed to see the source? And what is the reason for not wanting to distribute precompiled binaries? – jalf Aug 08 '09 at 13:44

8 Answers8

6

Just compile it to assembler. Can be done using the -S option.

helloworld.cpp:

#include <iostream>

using namespace std;

int main(void)
{
    cout << "Hello World" << endl;
    return 0;
}

And then do:

emil@lanfear /home/emil/dev/assemblertest $ g++ -S -o helloworld.s helloworld.cpp
emil@lanfear /home/emil/dev/assemblertest $ g++ -o helloworld helloworld.s
emil@lanfear /home/emil/dev/assemblertest $ ./helloworld
Hello World

Using this method you can distribute only the .s-files which will contain very hard to read assembler.

Emil H
  • 39,840
  • 10
  • 78
  • 97
  • 1
    This doesn't solve the "native platform" issue, as it is machine-dependent (and possibly distro-dependent, depending on what headers are included). – Michael Ekstrand Jul 16 '09 at 01:05
  • 2
    Fair point. I still believe that it could be an option in some cases though, so I'll leave the post rather than delete it. – Emil H Jul 16 '09 at 01:07
  • 1
    Even though it is platform-dependent there're not so many platforms out there - you most likely can do this separately for all platforms of interest. – sharptooth Jul 16 '09 at 04:28
5

It's not a technical answer, but do you trust them enough to just ask for a signed NDA?

John
  • 1,549
  • 1
  • 13
  • 15
4

You can process the existing source code to "mangle" it; basically this consists of stripping out all comments, and changing variable names to be minimal and stripping out all source code formatting. The problem is, they can relatively easily change the variable names back and add formatting and comments; while they won't have the same level of information in the resultant source code as you do, they WILL have completely functional source code (because that's what you distributed to them). This is about the only way to do this sort of thing.

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
  • 1
    This is called "shrouded source" and it used to be pretty common for e.g. UNIX software. – tialaramex Jul 16 '09 at 00:58
  • Couldn't you also strip the debugging information from it, or is this is what you are referring to? – jkeys Jul 16 '09 at 01:02
  • No, you can't pre-strip the debugging info when you're distributing source code (even mangled source code). The debugging info doesn't get created until the binary is compiled. – nobody Jul 16 '09 at 01:25
1

In short, no. By definition if they can compile it then they have your source. The best you can do is increase the pain of them trying to understand it.

I agree with John. If you have a small number of clients and trust them, an NDA would be a better route.

Another thing I just thought about... what about just running the preprocessor and compiler, but not the assembler and the linker? You would need a copy for each specific architecture's assembly language, but I assume that would be painful enough to dissuade editing while easy enough to compile.

Bob Somers
  • 7,266
  • 5
  • 42
  • 46
1

You could divide your application in two parts: first part will contain precompiled libraries with the OS independent functionality, and the second one will contain a little parts of sources that users would compile. In such way NVIDIA distributes their drivers.

Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
1

You could obfuscate your C/C++ code. See my question for C/C++ obfuscation tools

Community
  • 1
  • 1
hhafez
  • 38,949
  • 39
  • 113
  • 143
1

The best solution I can come up with is to either limit the number of platforms you support and do your own compilations, or compile to a binary format that is hard to extract information from, but the user can compile this to their native format.

Personally I would go with option 1.

tomjen
  • 3,779
  • 3
  • 29
  • 35
  • Since it already has Fedora and Ubuntu specific dependencies, then the list of target platforms is already limited. So yes - the option 1 is the most reasonable. Besides, providing end-users with architecture-specific, precompiled binaries is how it's done for most (all?) proprietary software written in C++. – Tomek Jun 18 '20 at 21:31
0

If it's C, you can use the clang compiler, then dump the LLVM intermediate representation. If it's C++, you might need to wait a while until clang's C++ support matures.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • The LLVM intermediate representation has already been compiled, and thus any build-time changes (e.g. different size of a structure on one persons system from another) won't be reflected in the resulting binaries. So this will usually only work in cases where distributing binaries would have been just as effective. – tialaramex Jul 16 '09 at 01:00
  • Assuming the only goal is to make it portable to other platforms, that's good enough, right? – bdonlan Jul 16 '09 at 02:52
  • 1
    Let's take an easy example. Linux and BSD have some system structures which are different sizes. When you compile from C to LLVM's intermediate representation, the header file which declares these structures on the platform where you compile (say, OpenBSD) will decide how big the compiler thinks the structure is. When you try to use that LLVM intermediate representation to build a running binary on Linux, the structure size will be wrong and your program will crash. So, no, doesn't seem good enough to me. – tialaramex Jul 16 '09 at 17:35