For years, a familiar threat to software developers was a skilled, persistent reverse engineer targeting an application and releasing a cracked version. Understanding the binary, debugging its behavior and building custom tools could demand substantial time and expertise.
Agentic large language models (LLMs) change that equation. An AI agent can work through an analysis task, write scripts and use tools with far less human intervention. For software developers, the concern is: what happens when the skill barrier and the expertise needed to attack a license check is lower?
We tested that question on an application we created ourselves. The difference between the unprotected and protected builds was noticeable, but so was the limit we found when the underlying algorithm was too simple.
A working keygen was generated.
No working keygen before the model stopped.
Observed outcomes in our internal test. The protected result is an unsuccessful attempt, not a measured time to crack.
The test: one binary, one prompt, one session
We created a basic application that accepts a username and a serial number, then passes them through a license-checking function.
alice.We gave a frontier AI model the binary and one task: generate a program that could produce a valid serial or password for any supplied username. We provided no explanation of the algorithm and no additional guidance.
Success meant producing a fully functional key generator, or keygen, within one prompt and one session. This tested whether the model could reproduce the licensing algorithm. It did not test every possible way to bypass a license check.
Unprotected: a keygen in 3 minutes
On the unprotected binary, the model took 3 minutes to generate a keygen script that produced a valid password or serial for any username. It had reproduced enough of the licensing logic to break the system.
For this application, the work that once required a knowledgeable person to examine and reconstruct the check was completed by the agent from a single request.
Protected: more than four hours without a keygen
We then protected the application with Dhaedalida, enabling the packer and virtualizing the license-checking functions, and asked the model to perform the same task.
The model began with static analysis. It recognized that the program was packed and attempted to unpack it. After spending time on the packer and obtaining a partially unpacked file, it moved to dynamic analysis with Unicorn, a CPU emulation framework. The important code was still obfuscated by virtualization.
The model continued working through the protection features. After more than four hours, with roughly 70% of its context window used, it concluded that it could not find a solution. No functional keygen had been generated in that session.
We also tested the same algorithm with two other popular software protectors. The outcomes were similar: the models stopped after more than four hours without producing a working keygen. In these tests, the benefit was not unique to Dhaedalida. Adding protection changed the difficulty of the task.
The important exception: a simple algorithm still fell
We repeated the experiment with a much smaller, simpler serial-checking algorithm. This time, a keygen was generated for all three protectors, including Dhaedalida.
The model did not create a general-purpose devirtualization tool. Instead, it repeatedly used the emulator and inspected virtual register values as handlers executed, reconstructing the algorithm from the behavior it observed.
That distinction matters. An attacker does not necessarily need to remove every protection layer or recover the original source code. Reproducing enough behavior to generate accepted serials can be sufficient.
What these results tell us
These are observations from our own test sessions, not a controlled benchmark or proof that a protected application cannot be cracked. The model, its tools, the prompt, the available time and the application itself can all affect the outcome. The model and version are not identified here, so this account is not a reproducible comparison of AI systems or protectors.
A session ending without a keygen does not establish permanent resistance. Another attempt, a different approach or a human analyst could produce a different result. Likewise, generating a keygen for this test application does not mean that any AI subscriber can crack any software.
The practical lesson is still clear: in our main test, exposing the original licensing logic made the task quick. Packing the binary and virtualizing the sensitive functions added enough difficulty that the attempted keygen was not completed in the session.
Build a stronger foundation, then protect it
Developers should consider licensing design and binary protection together. The simpler-algorithm result shows why neither should be treated as a substitute for the other.
- Review the licensing design. Ask whether observing the check or a few accepted inputs would make valid serials easy to reconstruct.
- Protect the sensitive implementation. Apply protection to the code that validates licenses and handles critical decisions. Our main test combined packing with function virtualization.
- Test the result on your own application. Compare the unprotected and protected builds, assess compatibility and performance, and revisit the assessment as analysis tools improve.
The goal is to increase the effort needed to understand, reproduce or modify your software. AI-assisted analysis makes that goal more urgent. Robust licensing design plus layered protection is a stronger starting point than either alone.
Continue with how license checks are attacked, how code virtualization works, or our software protector evaluation checklist.