before i built nyami i used pyarmor. a lot of people do.
and honestly? for what it was designed to do, it's fine.
but "fine" isn't the same as "works against someone who actually knows what they're doing."
here's why i moved on from pyarmor and why i built something different.
how pyarmor actually works:
pyarmor encrypts your bytecode and wraps it in a bootstrap loader.
at runtime, the loader decrypts the bytecode and hands it to the python interpreter.
the idea is: encrypted bytecode = unreadable bytecode.
and against someone with zero RE knowledge, that's true.
the problem:
the decryption has to happen somewhere.
the key has to exist somewhere.
the decrypted bytecode has to exist in memory at some point.
and that's the attack surface.
tools like frida can hook the python interpreter at the moment decryption happens and read your bytecode clean out of memory.
pyarmor's protection is a locked box where the key is taped to the outside.
if you know where to look, the lock doesn't matter.
i know this because i broke pyarmor-protected scripts regularly during my year of python RE.
it wasn't even the hard ones. it was just part of the normal process.
what pyarmor doesn't do:
- it doesn't break decompilers. pylingual still runs fine on pyarmor output in many configurations.
- it doesn't use polymorphism. the same obfuscation pattern means once you figure out the approach, every pyarmor-protected script is vulnerable the same way.
- it doesn't detect dynamic analysis. frida hooks work. patched interpreters work. the runtime protection isn't there.
pyarmor's approach is: hide the code.
the problem is that hidden code has to be unhidden to run.
what i built differently with nyami:
pytoc - python to C compilation
this doesn't encrypt your bytecode. it eliminates it.
your python gets converted to C and compiled to machine code.
there's no python bytecode to decrypt because there's no python bytecode at all.
a decompiler has nothing to work with. there's no key to find because there's nothing to decrypt.
this is a fundamentally different approach, not a better version of the same thing.
polymorphic everything
every nyami build is unique.
different obfuscation patterns, different keys, different structures.
this matters because pyarmor's static approach means breaking one copy scales to every copy.
with nyami, breaking one build tells you nothing about the next version.
signature-based attacks don't work when there are no signatures.
decompiler-breaking
i spent a year understanding how pylingual, pycdc, and uncompyle6 work internally.
then i built output that specifically breaks their analysis pipelines.
not output that confuses them. output that crashes them.
when the tool fails entirely, the attacker has to switch approaches entirely.
this is different every build so it can't be fingerprinted.
anti-tamper that actually watches runtime
frida detection. hook detection. integrity checks.
not just a startup check you can patch out.
if someone tries to patch your running process, nyami crashes it.
the honest comparison:
pyarmor is good at stopping the most casual attackers.
if someone has never done python RE before, pyarmor will slow them down.
nyami is built by someone who was on the attacking side.
i know the attacks because i used them.
i know where pyarmor fails because i made it fail.
the goal isn't protection that looks strong.
it's protection that holds up against someone who actually tries.
if you want to see the difference yourself:
we post protected test files on discord after every update.
try whatever tools you want.
nyami.cc | discord.nyami.cc | documentation.nyami.cc
got any questions? dm me on discord @justmaniak
Top comments (0)