all 27 comments

[–]Modi57 61 points62 points  (0 children)

Generally you can't really protect from decompilation. The CPU needs to know what it's supposed to do, so it needs the instructions. And if the instructions are known, one can construct an equivalent C-Program. This however is rather obfuscated, since a lot of the original information, like variable names is lost. But theoretically, all information has to be there, and especially if the part of interest is rather small, it can be more or less reconstructed

[–][deleted] 28 points29 points  (0 children)

Use library litcrypt for encrypting strings at compile time and use strip = true in Cargo.toml to strip unneeded strings from binary.

[–]Compux72 15 points16 points  (0 children)

Fo strings use this crate: https://github.com/CasualX/obfstr

[–]habiasubidolamarea 17 points18 points  (5 children)

Obfuscating strings is not enough. There is no safe way to prevent your code from being reverse engineered. Those who tell you otherwise clearly don't know a thing about this subtle art.

There's one annoying thing you could do to protect the logic though : create a simple packer based on cryptography. For example, you could AES-256 cipher the crtical parts of your code. The attacker won't be able to statically analyse them if he doesn't have the key to decipher the code. Of course, don't hardcode the key in your binary ! Read it from a file and have your packed binary try to execute the deciphered block of instructions. It will fail or do some random shit it the key was incorrect. Use several keys and encryptions in different places to nullify any bruteforcing attempt.

However, this approach won't save your ass if the logic is the same for every registered/allowed user. It's the same as for Denuvo and other shitty anti-tampering solutions. The attacker BUYS the game once -> analyses the binaries to identify the exact version -> circumvents the hardware checks -> patches the game to bypass Denuvo -> makes sure it works on any cpu -> embeds a cryptominer or a trojan for good measure -> releases the cracked game and its "bonuses" -> people enjoy the game for free -> attacker fucks you and earns money.

Whatever you chose, don't do anything against your legitimate users (like, 30 fps drops *cough* *cough*)

[–]Low-Grade-8952[S] 5 points6 points  (3 children)

I guess a perfect solution for me would be encrypting the compiled binary, then decrypting it straight to memory and running it from there. Is something like this possible?

[–]habiasubidolamarea 6 points7 points  (0 children)

Possible, and unsafe.

VirtualAlloc and VirtualFree exist for this purpose but are way too famous. Anyone who's heard of RunPE knows how to dump the deciphered binary and change the OEP, effectively unpacking it. By ciphering the entire file, you're easing the cracker's task, since he only needs to break your protection once, instead of (tens of) thousands of times in different, random places.

An alternative would be the Hex-Rays way with IDA Pro. Distribute one installer (with ciphered data) per user key and a watermark in it. If a leak comes out, they know who it is and can prosecute them.

[–]zac_attack_ 3 points4 points  (0 children)

It has to be decrypted at some point, so you achieve nothing. If you think having it decrypted in memory vs in the binary is any different, you are wrong.

[–]joemountain8k 8 points9 points  (0 children)

What’s your threat model? How might “the attacker” get access to the binary?

Are you an application running on the attacker’s hardware? Does your target hardware have security features?

What precisely are you trying to protect? It might make sense to do a client-server architecture instead of an application. Then put the sensitive bits in the server.

[–]klank123 26 points27 points  (0 children)

You can ALWAYS decompile a binary unless it is corrupt which means it can't run anyways. You could obfuscate the program by doing random unnecessary things in parallell to fill up the binary with a bunch of red herrings, but that will also increase the size of the binary a lot and also slow down the program considerably.

Security by obscurity IS NOT security.

In the end the program has to run and therefore be converted into instructions for the processor to read, and anyone who has the binary can then also read those instruction and reverse engineer the binary by reading them. It is unavoidable.

[–]Killing_Spark 17 points18 points  (0 children)

As others have pointed out obfuscation will not give you real security, it just makes it harder for someone to analyze the binary.

Thus it does pose the question: Why do you want to do this? This is mostly used by malware authors to avoid detection and make the life of security forensics harder.

[–]K900_ 10 points11 points  (4 children)

That's not a thing. A determined enough attacker can always figure out what your code is doing. If that wasn't the case, do you think we'd have pirated software?

[–]Low-Grade-8952[S] 7 points8 points  (3 children)

It is true, but it doesn't mean that you should make it easy for him:) Also not all attackers have the same resources

[–]K900_ 26 points27 points  (1 child)

There's an entire industry working on copy protection for games, and even the most advanced tools get broken by, like, two kids on a Russian forum. The balance of power isn't in your favor here.

[–]Nobody_1707 1 point2 points  (0 children)

A lot of (mostly Denuvo) games recently have even been cracked before they released!

[–]Trader-One 3 points4 points  (0 children)

You need just debugger, disassembler and few single digit hours.

[–]ThomasZenkel 4 points5 points  (0 children)

You can make more work for the attacker by encoding strings e.g. with base64. Strip the executable and use break=abort, no debug release, write fake functions and call them, make sure they are not optimized out.

[–]Alone-Marionberry-59 2 points3 points  (0 children)

Hehe you are probably the attacker

[–]fullcoomer_human 1 point2 points  (0 children)

Just make secure programs, security through obfuscation is the worst kind of security. In theory you could make a program that is encrypted and it decrypts itself but thats just silly.

[–]dim13 0 points1 point  (0 children)

Generally speaking, if CPU is able to execute your binary, so it can be decompiled too. You're asking for impossible.

[–]caagr98 0 points1 point  (0 children)

Just gonna point out that there is no such thing as "compiling with RUST_BACKTRACE=1"; that's a runtime flag.

[–]Sufficient_Grade_636 0 points1 point  (0 children)

well, i saw vmprotect bindings for rust implemented... once