views:

245

answers:

8

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.

+4  A: 

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.

McWafflestix
This is called "shrouded source" and it used to be pretty common for e.g. UNIX software.
tialaramex
Couldn't you also strip the debugging information from it, or is this is what you are referring to?
Hooked
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.
Andrew Medico
A: 

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
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
Assuming the only goal is to make it portable to other platforms, that's good enough, right?
bdonlan
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
+5  A: 

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

John
Game developers do that with online betas, but this is higher risk/higher reward.
Hooked
This is probably the best answer. If you don't trust your users, make sure you can go after them in court if they fuck you over. Or, you know, just embrace the whole Free Software thing.
jrockway
+4  A: 

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
This doesn't solve the "native platform" issue, as it is machine-dependent (and possibly distro-dependent, depending on what headers are included).
Michael E
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
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
+1  A: 

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
+1  A: 

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
+1  A: 

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

hhafez
A: 

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