Вообще есть 2 разные вещи: программа на компилируемом языке (C/C++/Golang/etc), т.е. исходник; и программа на одном из языков CPU (для GPGPU - GPU), так называемая release версия (либо debug, но суть не меняется, т.к. в отладочных бинарниках информации не сильно больше), она то и попадает на компьютеры клиентов/потребителей софта. Языков CPU (GPU - тем более) существует множество. Код на них необходимо перевести на IR/IL - выдуманный вспомогательный язык, затем в C-подобный функционально эквивалентный декомпилированный код. Так что исходники не раздобыть, но для модов/кряков/etc это лучше, чем ассемблер. Но минус в том, что с таким кодом могут потребоваться танцы с бубном, перед тем, как скомпилировать его снова. Для байткодов всё не так сложно, там декомпилированный код часто совпадает с исходным. Для первых (кроме GPU - в разработке) есть Ghidra, для байткодов: JVM байткод - Fernflower/CFR, C# байткод - JB dotPeek, Python байткод - Uncompiler. Вообще нет никакой защиты в большинстве случаев, по сути вся проблема в разнице между исходником и тем, что способен понять процессор. Поэтому никогда не пытайтесь оттранслировать CPU (x86/PPC/MIPS/ARM/AARCH64/...) в C++, только в C.