protecting C++ code in program - c++

I realize this must be a somewhat naive question, but I have written C++ program for a client. He needs the program installed on his machine, but I don't want to give him the code obviously.
How can I protect the code so he doesn't have access to the source code? any suggestions to help me get started would be appreciated.
thanks!

Compile the program, and give him the compiled version? Like most computer programs?
Beyond that, I refer you to Protecting executable from reverse engineering?

You don't have to give your customer the source code of your program. Generally speaking, he should only need the executable program.

C++ is a compiled language. That means that after compilation, the compiler will generate a binary file which contains machine code - for example, a dll, a lib or an exe file under Windows. In windows, all you have to do is deliver the exe's and associated dll's, if they are not already present on the client's machine. There can be different versions of the binaries (depending on platforms, e.g. 32bit vs 64bit compilations) so you might have to run more compilations and let an installer utility handle the distribution.

Related

If C++ compiles to machine code, why do we need to install a 'runtime'?

At the end of the compilation process, the program is in a .exe file in machine code. So shouldn't the machine be able to run it without having to install something like MS Visual Studio C++? Basically, I am making a program with mingw and want to share it with someone else. I do not understand why I can not just send them the .exe file. Clarification will be appreciated.
C++ compiles your code to machine code. If your program is self-contained, that is all you need. However, more complex running programs often relies on additional compiled code, which is made available to your program through a library.
Generally, libraries come in two "flavors" - static and dynamic. Static libraries are "baked into" your compiled code. This is not ideal, because multiple programs include identical code, leading to code duplication. Dynamic libraries, on the other hand, are shared among all programs using them, leading to more efficient use of space.
Installing runtime adds dynamic libraries for use by all programs compiled with C++.
Your program likely calls many functions from the standard library that you didn't write yourself. You need the runtime libraries for that. Your code probably also needs code run before main to setup the basic environment that's expected for a C++ program - the runtime libs do that for you. Also after main ends, various cleanup needs to happen according to the standard (and your program probably also depends on this) and the compilers runtime libraries take care of this.
Your code does not exist in a vacuum (it can, but then it's no longer a standard hosted C++ program). It depends on and relies on the standard runtime libs to provide the environment the C++ standard says you can expect.

C++ Versions, do they auto-detect the version of an exe?

Okay so I know that there are multiple c++ versions. And I dont really know much about the differences between them but my question is:
Lets say i made a c++ application in c++ 11 and sent it off to another computer would it come up with errors from other versions of c++ or will it automatically detect it and run with that version? Or am I getting this wrong and is it defined at compile time? Someone please tell me because I am yet to find a single answer to my question on google.
It depends if you copy the source code to the other machine, and compile it there, or if you compile it on your machine and send the resulting binary to the other computer.
C++ is translated by the compiler to machine code, which runs directly on the processor. Any computer with a compatible processor will understand the machine code, but there is more than that. The program needs to interface with a filesystem, graphic adapters, and so on. This part is typically handled by the operating system, in different ways of course. Even if some of this is abstracted by C++ libraries, the calls to the operating system are different, and specific to it.
A compiled binary for ubuntu will not run on windows, for example, even if both computers have the same processor and hardware.
If you copy the source code to the other machine, and compile it there (or use a cross-compiler), your program should compile and run fine, if you don't use OS-specific features.
The C++ version does matter for compilation, you need a C++11 capable compiler of course if you have C++11 source code, but once the program is compiled, it does not matter any more.
C++ is compiled to machine code, which is then runnable on any computer having that architecture e.g. i386 or x64 (putting processor features like SSE etc. aside).
For Java, to bring a counterexample, it is different. There the code is compiled to a bytecode format, that is machine independent. This bytecodeformat is read/understood by the Java Virtual Machine (JVM). The JVM then has to be available for your architecture and the correct version has to be installed.
Or am I getting this wrong and is it defined at compile time?
This is precisely the idea: The code is compiled, and after that the language version is almost irrelevant. The only possible pitfall would be if a newer C++ version would include a breaking change to the standard C++ library (the library, not the language itself!). However, since the vast majority of that library is template code, it's compiled along with your own code anyway. It's basically baked into your .exe file along with your own code, so it's just as portable as yours. Also, both the C and C++ designers take great care not to break old code; so you can expect even those parts that are provided by the system itself (the standard C library) not to break anything.
So, even though there are things that could break in theory, pure C++ code should run fine on all machines that understand the same .exe format as the machine it was compiled on.

COCOS2D-X cross-platform mistery for me

I am a C++ developer I am interested in Cocos2d-x framework. I know that you can write C++ code using the framework, compile it for different platforms and that's it, you have your 2D on Windows, Android, iOS. This is amazing but I don't understand how it is being done and, consequently, I worry that some thing that I have done for one platform will not work on other one. To go into details I would like to open my concerns. In order to do that let's clarify what is compiling and what is running a code.
What does it mean to compile C++ code for a platform (platform is OS + CPU architecture)? It means that C++ source code is mapped to instructions which is understandable for a concrete CPU architecture. And the final set of instructions is packaged into an executable file which is understandable for a concrete OS which means a concrete SO or OSes that understand how to handle the executable file can run it. Also we should not forget that in the set of instructions that the executable contains there could be system calls. Which is also specific to OS.
What does it mean to run the executable? It means that OS knows the format of particular executable file. When you give run command OS loades it into the virtual memory and starts to execute that CPU instructions set step by step. (Very raw but in general it is like that I guess.)
Now returning to the COSOS2D-X. How it is possible to compile a C++ code so that it was able to be recognized and loaded by different OSes and by different CPUs. What mechanisms we use in order to get appropriate .apk, .ipa or .exe files. Is there a trap that we can fall while using system calls or processor specific calls? In general how all this problems are solved? Please explain the process, for example, for Android or it would be great for iOS too. :)
Cocos2d-x has 95% of the same code for all target OS and platforms. And it has 5% of code which is written for the concrete platform. For example there are some Java sources for Android. And there are some Obj-C files for iOS. Also there is some code in C++ for different platform. #define is used to separate this code. Examples of such code is working with files which is written in C++ but differs from platform to platform.
Generating of appropriate output file is responsibility of the compiler and SDK used for target platform. For example xCode with clang compiler will generate the iOS build. While Android NDK with gcc inside will build the apk.

C++ Compile on different platforms

I am currently developing a C++ command line utility to be distributed as an open-source utility on Github. However, I want people who download the program to be able to easily compile and run the program on any platform (specifically Mac, Linux, and Windows) in as few steps as possible. Assuming only small changes have to be made to the code to make it compatible with the various platform-independent C++ compilers (g++ and win32), how can I do this? Are makefiles relevant?
My advice is, do not use make files, maintaining the files for big enougth projects is tedious and errors happen sometimes which you don't catch immediatly (because the *.o file is still there).
See this question here
Makefiles are indeed highly relevant. You may find that you need (at least) two different makefiles to compensate for the fact that you have different compilers.
It's hard to be specific about how you solve this, since it depends on how complex the project is. It may be easiest to write a script/batchfile, and just document "Use the command build.sh on Linux/Unix, and build.bat on Windows") - and then let the respective files deal with for example setting up the name of the compiler and flags, etc.
Or you can have an include into the makefile, which is determined by the architecture. Or different makefiles.
If the project is REALLY simple, it may be just enough to provide a basic makefile - but it's unlikely, as a compile of x.cpp on Linux/MacOS makes an object file is called x.o, on windows the object file is called x.obj. Libraries have different names, dll's have differnet names, and on Linux/MacOS, the final executable has no extension (typically) so it's called "myprog", where the executable under windows is called "myprog.exe".
These sorts of differences mean that the makefile needs to be different.

Same binary code on Windows and Linux (x86)

I want to compile a bunch of C++ files into raw machine code and the run it with a platform-dependent starter written in C. Something like
fread(buffer, 1, len, file);
a=((*int(*)(int))buffer)(b);
How can I tell g++ to output raw code?
Will function calls work? How can I make it work?
I think the calling conventions of Linux and Windows differ. Is this a problem? How can I solve it?
EDIT: I know that PE and ELF prevent the DIRECT starting of the executable. But that's what I have the starter for.
There is one (relatively) simple way of achieving some of this, and that's called "position independent code". See your compiler documentation for this.
Meaning you can compile some sources into a binary which will execute no matter where in the address space you place it. If you have such a piece of x86 binary code in a file and mmap() it (or the Windows equivalent) it is possible to invoke it from both Linux and Windows.
Limitations already mentioned are of course still present - namely, the binary code must restrict itself to using a calling convention that's identical on both platforms / can be represented on both platforms (for 32bit x86, that'd be passing args on the stack and returning values in EAX), and of course the code must be fully self-contained - no DLL function calls as resolving these is system dependent, no system calls either.
I.e.:
You need position-independent code
You must create self-contained code without any external dependencies
You must extract the machine code from the object file.
Then mmap() that file, initialize a function pointer, and (*myblob)(someArgs) may do.
If you're using gcc, the -ffreestanding -nostdinc -fPIC options should give you most of what you want regarding the first two, then use objdump to extract the binary blob from the ELF object file afterwards.
Theoretically, some of this is achievable. However there are so many gotchas along the way that it's not really a practical solution for anything.
System call formats are totally incompatible
DEP will prevent data executing as code
Memory layouts are different
You need to effectively dynamically 'relink' the code before you can run it.
.. and so forth...
The same executable cannot be run on both Windows and Linux.
You write your code platform independently (STL, Boost & Qt can help with this), then compile in G++ on Linux to output a linux-binary, and similarly on a compiler on the windows platform.
EDIT: Also, perhaps these two posts might help you:
One
Two
Why don't you take a look at wine? It's for using windows executables on Linux. Another solution for that is using Java or .NET bytecode.
You can run .NET executables on Linux (requires mono runtime)
Also have a look at Agner's objconv (disassembling, converting PE executable to ELF etc.)
http://www.agner.org/optimize/#objconv
Someone actually figured this out. It’s called αcτµαlly pδrταblε εxεcµταblε (APE) and you use the Cosmopolitan C library. The gist is that there’s a way to cause Windows PE executable headers to be ignored and treated as a shell script. Same goes for MacOS allowing you to define a single executable. Additionally, they also figured out how to smuggle ZIP into it so that it can incrementally compress the various sections of the file / decompress on run.
https://justine.lol/ape.html
https://github.com/jart/cosmopolitan
Example of a single identical Lua binary running on Linux and Windows:
https://ahgamut.github.io/2021/02/27/ape-cosmo/
Doing such a thing would be rather complicated. It isn't just a matter of the cpu commands being issued, the compiler has dependencies on many libraries that will be linked into the code. Those libraries will have to match at run-time or it won't work.
For example, the STL library is a series of templates and library functions. The compiler will inline some constructs and call the library for others. It'd have to be the exact same library to work.
Now, in theory you could avoid using any library and just write in fundamentals, but even there the compiler may make assumptions about how they work, what type of data alignment is involved, calling convention, etc.
Don't get me wrong, it can work. Look at the WINE project and other native drivers from windows being used on Linux. I'm just saying it isn't something you can quickly and easily do.
Far better would be to recompile on each platform.
That is achievable only if you have WINE available on your Linux system. Otherwise, the difference in the executable file format will prevent you from running Windows code on Linux.