Reverse engineering software licensing from early-2000s abandonware
yingtongli.me
yingtongli.me
This where you end up with DOS, Windows 3.1 and even Windows NT computers controlling machines that make millions of dollars worth of product, 24 hours a day.
We've spent hours scouring eBay or industrial auction sites finding parts of computers to keep 'just in case'. None of this software virtualizes easily or can even be moved to a machine of similar vintage without relicensing. Some of it is hardware dongles, some of it software keys.
It seems like you could create quite a business being able to crack this software. Companies would pay tens of thousands to get these machines running. Often times the 'new' version of the hardware and software is $100,000 US.
In a few years, internet-based licensing will be the thing to crack.
That would be against the copyright holder interests because as you point out:
> Often times the 'new' version of the hardware and software is $100,000 US.
An as per the Disney lobbied US copyright law you would have to wait at least the life of the author + 70 years or 95 years from publication depending on some circumstances.
I'd be pretty surprised if a judge was like "ah yes the defendant's consultancy modified a piece of industrial control software that you haven't given a thought to in three decades to make it run on a modern computer and not require a parallel port dongle, and that's definitely a DMCA violation and you've been harmed by it and deserve all the money."
There may be b2b contracts in addition to what the law says, but I believe the DMCA has an interoperability exception. I'm curious if "getting it to run on new hardware" is enough for that to trigger.
So, below, you have people wondering about cracking machine equipment. Totally legal to do.
What about defining the equipment as "repairably broken" and asserting that circumventing the license protection falls within right to repair?
*Opens even bigger can of worms*
What about invoking this in a situation where someone's using an older piece of equipment and does not want to pay for example $500k, $1m, or more to green-field replace an entire installation when 99% of the existing system has perhaps a decade or more life left in it?
--
I'm not entirely read up on the finer points of the John Deere tractor situation (which is kind of the current poster child for this whole thing), but I actually think the above arguments actually resonate with the precedent set by this particular case.
I've only read about it but never tried it though, it may have been using the SYSPREP tools?
I've done it once, migrating a very old machine to new hardware by just moving the disk.
We have also virtualised many physical servers at my job. We use Veeam to create the VHD
> Often times the 'new' version is $100,000 US
Is the price really the issue here? It almost sounds like the company could afford it if it wanted to.
So it's $100,000 plus:
* The costs to disassemble and remove the old machine
* The costs to install the new machine, which could include specialized contractors.
* The costs to realign any supporting equipment to fit the new machine (i. e. if a conveyor belt feeding parts in or out has to be moved)
* The costs to retool the rest of the manufacturing process that was dependent on quirks of the old machine. This could have a significant and expensive research phase.
* Retraining to operate the new machine
* Any parts scrapped by use in the testing or teething-trouble adjustment of the new machine
* Downtime of the actual production process, potentially extending to failure to meet contracts and associated penalties
So that "$100,000" machine could have end-to-end costs well into seven or eight figures.
This project is a spiritual successor to an earlier project reverse engineering a gaming DRM system, so if you enjoy this post you might enjoy that older one too: https://yingtongli.me/blog/2018/11/16/drm1-1.html
Ghidra's decompiler worked fine for this project. It made 2 relevant mistakes which I talk about in the blog posts, but they were fairly easy to identify when comparing with the disassembly.
As I discussed in the post, Ghidra did have some difficulty (which IDA did not have) locating all the functions, so I did end up using both Ghidra and IDA in the initial stages.
The progress that Ghidra is making though (e.g. the recent implementation of debugger support) is promising for the future.
The IDA GUI and scripting functionalities are much more common in tutorials and the ecosystem, so the Ghidra learning curve can be greater, but it's not really inferior.
IDA has fewer decompilation/disassembly bugs but in both IDA and Ghidra, bugs are usually fairly easy to spot and not a huge detriment to achieving a goal.
IDA deals with C++ better than Ghidra (imo).
Anyway, for free Ghidra eats IDA's lunch, and the IDA home edition offering is weak - so for a hobbyist, Ghidra is a clear home run.
> Copyright law is pretty scary around anti-circumvention rules – putting the name of the software right in an article about how to break its DRM/licensing just sounds like asking for trouble, so I never do. (Not legal advice – just my personal musings!)
> At least if the software is unnamed, the article is clearly more for educational purposes – you won't find the article if you've got the software and you're trying to break it, and you won't have access to the software if you're just reading the article.
The broader point to make is that this is a general policy of mine – I deidentify all software that I discuss in any of my RE writeups. Having a blanket policy avoids needing to make ultimately arbitrary decisions about what to name and what not to name – and in any case, not naming the software doesn't prevent anyone from reading the writeup and taking inspiration from it if they choose.
I've always felt the biggest mistake people make is thinking no one is looking at their ramblings.
Then again, I also exercised my skills from the Fravia/Searchlores era ;-)
Out of benign curiousity, was the software...?
- Industrial/control oriented (talking to bespoke hardware)
- An "internal" B2B line of business thing
- An off-the-shelf/productized/marketed piece of software
I suspect the latter.
I'm naturally also curious what it was for, but I suspect that even generally scoping that would make identification significantly easier for a large majority of people, so I'll leave it there :)
[0]: https://www.brandonstaggs.com/2007/07/26/implementing-a-part...
[1]: https://keygen.sh/blog/how-to-generate-license-keys-in-2021/
The key validation algorithm in this software is extraordinarily simple, so I'm leaning away from there being anything fancy. I was unable to correlate keys used in later versions of the software with this algorithm, though, so you might be on to something. (I don't have a copy of a later version, but would love to check if I ever get my hands on one.)
What if you release a new version where, if the key is valid under the old check but not under the new check (indicating a keygen-ed licence), you start subtly screwing with the user. Like EarthBound or Spyro...
Quite off topic but very interesting!
Also, I love your anti-cv!
Re: anti-CV – Thanks! Imposter syndrome is a big problem in medicine, as it is in IT and probably every field, and I wanted to do my little bit to combat it. (Not my idea, got it from my seniors, who got it from some uni professors.)
How (long) did (it take) you (to) find out?
In the first case, the decompiled code reports a function call, but in the disassembly it is preceded by pushing some suspicious-looking magic numbers onto the stack which are not reported in the decompiled code – clearly, something was going on there.
In the second case, the "ret" instruction at the supposed end of the function was immediately preceded by pushing an address to the stack – so again fairly simple to determine that the return must necessarily jump to that address, rather than return from the function.
You might be able to guess why I write this.
I got a bit confused by the title at first, thinking they were trying to deduce the specific licensing terms or something.
I disassembled the blob and it turned out that it was down-casting a NT handle to 32-bits. This seemed to be fine in practice as I never observed the higher bits set. Unfortunately however, the code then used a signed load to read it in from memory and hence corrupted the handle if the 32nd bit was set, causing a crash.
I made a patched blob which fixed the problem but sadly the legal department vetoed shipping it in case it violated our license with Flex :-P.
Nice! Next time when I encounter an "Enter license key:" dialog, I'll simply try some simple registration codes first.
I'll start with clever variations of the value "1", e.g. 00001, 00010, 00100 ...
I contacted him to sell me a license but he refused categorically, telling me I “should have bought it when it was being sold.”
Now I find myself using a buggy version and hoping I’d get around to cracking the new version myself. Heck I’d pay to get it cracked.
Ghidra didn't exist yet and I didn't care to deal with the IDA demo, so I used OllyDbg and then just manually hex-patched the binary. Simpler times :)
A few software (especially antivirus software) did a simple version check, Windows reports it's version 5.2, and the assumption was made that it must have been Windows Server 2003. Refuse to run because you have to pay more for a server edition.
I actually don't know all that much about binary RE – my usual work is generally high-level Python stuff – so I try to write how I would like things explained to me, which I think helps.
1: Of course not being an expert can contribute to communicating the wrong thing clearly, which is its own problem.
Does anybody know any similar articles? Maybe something where the software is named and it's possible to follow along step-by-step? Seems like it'd be a fun exercise.
https://www.smokingonabike.com/2021/01/17/hacking-super-monk...
It sounds like what you might be after is some content on crackmes/specific RE challenges. I'm not involved in that space, so someone else probably would have better links, but one challenge that was my start in RE was the Synacor Challenge: https://challenge.synacor.com/
It starts off just as a programming challenge, no real RE knowledge required, but if you see it through to the end you'll definitely wind up with a bunch of foundational RE skills. And there are a whole bunch of public writeups online if you want to follow along with someone else's approach.
(Just to note, though, that it's based on a custom CPU architecture – implementing that is the programming part of the challenge – so very much from the ‘learn it the hard way so when you do regular stuff it feels easy’ school of thought.)
The Youtube channel LiveOverflow also has some videos going step-by-step through some RE puzzles, and his content is very digestible.
The SEH pattern (PUSH 32bit address then RET) should be identifiable with a plugin, and a code flow override should fix the decompilation.
I wonder, did you try this, and did it help fix the Ghidra decompilation?
Sounds like try-catch handling is not implemented in general yet, but is on the cards.
> Totally, putting some small patches into the binary would definitely work in the case of just wanting to get rid of the licence validation. The goal of my project, though, was to get to a state where the software could be used in its original unmodified state, with a "real" licence. Just felt more authentic! So the process over the 3 parts of the blog series is guided by that final destination.
Looks like Armadillo protection at first sight, but not 100% sure, been too long :)
Could these tools and techniques be used on older PowerPC Mac executables? I have some old software that was protected by ADB dongles. I own the software, and even have the dongles, but I don't have any PowerPC ADB-equipped machines.