Hacker News new | ask | show | jobs
by userbinator 2247 days ago
This is part of a larger pattern of fairly weak attempts to confuse a reverse engineer that made it frustrating to figure out what all the opcodes did, and there were many duplicate opcodes that were just implemented in different ways.

Since the code presented in the article didn't look like handwritten Asm (and if it was, it would've probably been even more insanely obfuscated and greatly confused IDA's decompilation), I wonder if compilers of the time were far worse at optimisation, or if the author deliberately disabled it so that the code would be more bloated and harder to understand as well as containing the source obfuscations; seems like "Here's addition implemented by multiplying the result with some number and its reciprocal" would be something that's replaced-on-sight by an optimiser doing constant propagation.

Also, I was not surprised to discover that this program appears to be both [1] of German origin, and [2] shareware. When I was in the cracking scene long ago, "German shareware" was widely known for the insane strength of its protection.

4 comments

Pure speculation, but it's quite possible that it was written in Delphi (the last iteration of Borland's Turbo Pascal lineage), which had a fast single-pass compiler that did very little optimization. Delphi was very popular in Germany in the late 1990s and early 2000s.
Delphi makes things worse because the code it generates is incredibly ugly. The code listings use the C++ std and it looks straightforward so presumably it is just good old C++.
It could equally be C++Builder. Back in those dates, the C++ compiler used a similar backend to Delphi - it was derived from Delphi's originally, since the two products interop and you can use both languages in one app. Today's C++Builder uses LLVM.
Borland had a C++ compiler too, but it was never nearly as popular as the Pascal-based Delphi.
I doubt the compiler would optimize out multiplications like that, as floating point math is not necessarily associative. You'd have to pass -ffast-math to get the compiler to attempt to optimize that out. It looks like typical compiler output to me.
A lot of obfuscators out there use VMs with convoluted pieces of assembly implementing each opcode of the VM. Pushing, popping, swapping register values, etc, etc. In many cases the opcodes are microinstructions that can be used to implement x86 instructions making the VM an x86 emulator. It's super satisfying when you finally get x86 opcodes out of the other end and then patch those back into the program.
Historically, Germany has had issues with crackers.