Disclaimer: The following is a technical exploration for educational purposes only. It is not intended to bypass licensing or promote piracy. Sononym is a commercial application, and users should respect its licensing terms.
Sononym is a music sample browsing tool that helps producers, sound designers, and musicians quickly search, tag, and organize audio samples. Its smart search features and AI-assisted audio analysis make it a valuable tool for anyone working with large sample libraries.
When I started exploring Sononym, I wanted to see how its evaluation and licensing logic worked. I began with Procmon to track what files and registry keys the app touched. I didn’t see much except for a license.json in the roaming folder at:
%APPDATA%\Roaming\Sononym\1.5.6\license.json
Modifying that file didn’t change the behavior, which suggested that the licensing checks weren’t solely relying on it.
Next, I loaded sononym.exe into IDA Freeware and noticed references to Electron, which told me that the app was built on Electron. Electron is a framework for building desktop applications using web technologies like JavaScript, HTML, and CSS, combined with Node.js for backend functionality. Since Electron apps package their code in ASAR archives (which are basically zip-like containers for JavaScript files and assets), I looked in the installation directory and found app.asar. I extracted it using the official asar tool:
npx asar extract app.asar %USERPROFILE%/extracted/sononym.out
This let me browse the JavaScript source code. Searching for keywords related to evaluation like “expired” and “evaluation”.
led me to several locations, but the file that stood out was license.js in the models directory.
Inside license.js, there was a function called remainingEvaluationDays. This function actually calls another implementation of the same name exposed by a .node file named encore.node. .node files are compiled native addons for Node.js, usually written in C or C++, that can be loaded and called from JavaScript.
get ['remainingEvaluationDays']() {
return (0x0, registration_1['remainingEvaluationDays'])();
}
I did not dig into the native implementation; instead, I patched the JS function to always return a fixed value to continue testing the app without hitting trial restrictions. This shows how Electron apps can mix JavaScript logic with native modules.
Exploring this process taught me a lot about Electron app structure. By combining runtime monitoring with disassembly and ASAR extraction, you can observe app behavior and understand internal logic without modifying sensitive components. Functions that manage licensing or trials are usually straightforward, especially when the core logic is in JavaScript, and you can learn patterns and control flow safely.
Overall, this exercise reinforced that careful observation, methodical exploration, and reading code are core skills in reverse-engineering. For anyone curious about similar research, the Electron documentation is a helpful resource, and tools like Procmon, IDA Pro, and ASAR provide a strong foundation for exploring desktop applications in a safe and ethical way.
Mitigation: To make this kind of JS-level patching harder, there are a few avenues that developers can explore. Sensitive evaluation and licensing logic could be moved into compiled native modules, checks could be validated on a server instead of the client, and the JavaScript code could be obfuscated. Adding integrity checks and encrypting configuration data are also options. Combining these approaches can make bypassing the trial logic much more difficult while keeping the app functional.