This article is a shorter JavaScript adaptation, based on this article, where I talk about how to reverse engineer different types of programming languages and how to protect against it in multiple languages.

If you are interested in learning how people reverse engineer your code and stuff like that you should check it out.


Code obfuscation is an intentional act of making source code difficult to modify and understand by renaming stuff, using hard-to-read functions (hard to read for humans, not for computers), blurring code flow, inserting dead code, ordering code randomly, and more.

There are obviously several Pros and cons to Code Obfuscation. See following:


1. Reverse Engineering Protection

The reason I'm even talking about the pros and cons of obfuscation, is that no one will ever be able to obtain 100% of your original source code. How much source code can be retrieved will differ depending on the obfuscation and de-obfuscation used, but the renamed variables and things like that, in particular, can never be recovered.

2. Performance

Obfuscation can make your code longer (if you want to hear about that negative performance site of Obfuscation, scroll down a bit), but it can also make your code smaller, speed up the process of compilation and let your app run faster.

This can happen because obfuscators do not care about human readability, which is why a lot of metadata, unused, duplicate or even dead code, will be removed.

The Obfuscator does this with the goal of making it harder to read and not to optimize the code but it still works  ¯\_(ツ)_/¯.



1. Performance

As I said before, this could be a pro and a con. However, it's a con most of the time because the majority of obfuscators will make your code longer and run slower - By the way, you should not try to run your code through a Minifier after obfuscating it. This is going to break your code 90% of the time.

When you think of what the obfuscator is doing, this obviously makes sense. It adds weird stuff, dead code and encrypted values that a person will never use.

That's also why it's not always the best option to use the biggest and baddest of all obfuscators.

For instance, take this JavaScript Code obfuscated using This results in code that looks like this:

var _0x19a4=['fzMVe','constructor','string','SJPvD','RlHzi','PHTZd','while\x20(true)\x20{}','Hello\x20World!','return\x20/\x22\x20+\x20this\x20+\x20\x22/','\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)','jcoNn','apply','debu','stateObject','action','RvkSD','lOqWL','call','QEQSp','function\x20*\x5c(\x20*\x5c)','log','test','TeAWl','gger','input','chain','cHZdn','kyRAK','^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}'];(function(_0x417f3a,_0x2f1f1b){var _0x19a4c3=function(_0x362cd1){while(--_0x362cd1){_0x417f3a['push'](_0x417f3a['shift']());}},_0x523a90=function(){var _0x66f517={'data':{'key':'cookie','value':'timeout'},'setCookie':function(_0xb43266,_0x1aec04,_0x2769cf,_0x3a6955){_0x3a6955=_0x3a6955||{};var _0x5bf31e=_0x1aec04+'='+_0x2769cf,_0x1ebbea=0x0;for(var _0x4b4623=0x0,_0x5734be=_0xb43266['length'];_0x4b4623<_0x5734be;_0x4b4623++){var _0x2c2b5d=_0xb43266[_0x4b4623];_0x5bf31e+=';\x20'+_0x2c2b5d;var _0x346c4b=_0xb43266[_0x2c2b5d];_0xb43266['push'](_0x346c4b),_0x5734be=_0xb43266['length'],_0x346c4b!==!![]&&(_0x5bf31e+='='+_0x346c4b);}_0x3a6955['cookie']=_0x5bf31e;},'removeCookie':function(){return'dev';},'getCookie':function(_0x3c2e94,_0x35fc46){_0x3c2e94=_0x3c2e94||function(_0x4f8221){return _0x4f8221;};var _0x3eddc1=_0x3c2e94(new RegExp('(?:^|;\x20)'+_0x35fc46['replace'](/([.$?*|{}()[]\/+^])/g,'$1')+'=([^;]*)')),_0x155f2a=function(_0x369d7b,_0x5c458e){_0x369d7b(++_0x5c458e);};return _0x155f2a(_0x19a4c3,_0x2f1f1b),_0x3eddc1?decodeURIComponent(_0x3eddc1[0x1]):undefined;}},_0x4f5170=function(){var _0x16efd0=new RegExp('\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*[\x27|\x22].+[\x27|\x22];?\x20*}');return _0x16efd0['test'](_0x66f517['removeCookie']['toString']());};_0x66f517['updateCookie']=_0x4f5170;var _0x37cfea='';var _0x81c07c=_0x66f517['updateCookie']();if(!_0x81c07c)_0x66f517['setCookie'](['*'],'counter',0x1);else _0x81c07c?_0x37cfea=_0x66f517['getCookie'](null,'counter'):_0x66f517['removeCookie']();};_0x523a90();}(_0x19a4,0x10c));var _0x523a=function(_0x417f3a,_0x2f1f1b){_0x417f3a=_0x417f3a-0x1d9;var _0x19a4c3=_0x19a4[_0x417f3a];return _0x19a4c3;};function _0x212779(){var _0x164e9f=_0x523a,_0x471498=function(){var _0x3bd433=!![];return function(_0x298fbe,_0x5e51b4){var _0x57cf72=_0x3bd433?function(){var _0x4b6d20=_0x523a;if(_0x5e51b4){var _0x48608d=_0x5e51b4[_0x4b6d20(0x1dd)](_0x298fbe,arguments);return _0x5e51b4=null,_0x48608d;}}:function(){};return _0x3bd433=![],_0x57cf72;};}(),_0x4685d4=_0x471498(this,function(){var _0x223e49=_0x523a;if(_0x223e49(0x1ec)==='cHZdn'){var _0x29e924=function(){var _0x9bc43f=_0x223e49;if(_0x9bc43f(0x1e4)!=='QEQSp'){function _0x1c2282(){var _0x2068b3=_0x9bc43f,_0x236d87=_0x8a262d[_0x2068b3(0x1dd)](_0x162783,arguments);return _0x4a657c=null,_0x236d87;}}else{var _0x56cd34=_0x29e924['constructor'](_0x9bc43f(0x1da))()['constructor'](_0x9bc43f(0x1ee));return!_0x56cd34['test'](_0x4685d4);}};return _0x29e924();}else{function _0x2ac364(){return _0x18ed9f;}}});_0x4685d4();var _0x415810=function(){var _0x4d1ed0=!![];return function(_0x433606,_0x25a4ef){var _0x2ddd1e=_0x4d1ed0?function(){var _0x46fb2d=_0x523a;if(_0x46fb2d(0x1ef)===_0x46fb2d(0x1ef)){if(_0x25a4ef){var _0x251ebb=_0x25a4ef[_0x46fb2d(0x1dd)](_0x433606,arguments);return _0x25a4ef=null,_0x251ebb;}}else{function _0x30f1e1(){var _0x292d19=_0x46fb2d,_0x4634f9=_0x5012d5[_0x292d19(0x1f0)](_0x292d19(0x1da))()[_0x292d19(0x1f0)]('^([^\x20]+(\x20+[^\x20]+)+)+[^\x20]}');return!_0x4634f9[_0x292d19(0x1e7)](_0x5200c5);}}}:function(){};return _0x4d1ed0=![],_0x2ddd1e;};}();(function(){var _0x4cbb8f=_0x523a;if(_0x4cbb8f(0x1e2)===_0x4cbb8f(0x1f3)){function _0x178c78(){var _0x44fe84=_0x4cbb8f,_0x6648f5=_0x1e36ee[_0x44fe84(0x1dd)](_0x5b98ec,arguments);return _0x269cba=null,_0x6648f5;}}else _0x415810(this,function(){var _0x32c8c5=_0x4cbb8f,_0x4a061a=new RegExp(_0x32c8c5(0x1e5)),_0x52fb7e=new RegExp(_0x32c8c5(0x1db),'i'),_0x18936c=_0x5c9f83('init');if(!_0x4a061a[_0x32c8c5(0x1e7)](_0x18936c+_0x32c8c5(0x1eb))||!_0x52fb7e[_0x32c8c5(0x1e7)](_0x18936c+_0x32c8c5(0x1ea)))_0x18936c('0');else{if(_0x32c8c5(0x1e8)===_0x32c8c5(0x1e1)){function _0x377b2d(){if(_0xd6e4d8)return _0x1a6032;else _0x243ed0(0x0);}}else _0x5c9f83();}})();}(),console[_0x164e9f(0x1e6)](_0x164e9f(0x1d9)));}_0x212779();function _0x5c9f83(_0x451034){var _0x2f62aa=_0x523a;function _0x234f5a(_0x148936){var _0xcb8dc5=_0x523a;if(_0xcb8dc5(0x1ed)===_0xcb8dc5(0x1ed)){if(typeof _0x148936===_0xcb8dc5(0x1f1))return function(_0x1ff1b3){}[_0xcb8dc5(0x1f0)](_0xcb8dc5(0x1f5))['apply']('counter');else{if(_0xcb8dc5(0x1f2)===_0xcb8dc5(0x1f2))(''+_0x148936/_0x148936)['length']!==0x1||_0x148936%0x14===0x0?function(){return!![];}[_0xcb8dc5(0x1f0)](_0xcb8dc5(0x1de)+_0xcb8dc5(0x1e9))[_0xcb8dc5(0x1e3)](_0xcb8dc5(0x1e0)):function(){return![];}[_0xcb8dc5(0x1f0)](_0xcb8dc5(0x1de)+_0xcb8dc5(0x1e9))['apply'](_0xcb8dc5(0x1df));else{function _0x59502c(){var _0x2d4b6d=function(){var _0x252378=_0x523a,_0x1075cd=_0x2d4b6d[_0x252378(0x1f0)](_0x252378(0x1da))()[_0x252378(0x1f0)](_0x252378(0x1ee));return!_0x1075cd['test'](_0x3a5ce5);};return _0x2d4b6d();}}}_0x234f5a(++_0x148936);}else{function _0x59057d(){var _0x38b701=_0x3c2e94?function(){var _0x34ae9b=_0x523a;if(_0x5c458e){var _0x40b03a=_0x40fbd7[_0x34ae9b(0x1dd)](_0x3b310e,arguments);return _0x2963a1=null,_0x40b03a;}}:function(){};return _0x369d7b=![],_0x38b701;}}}try{if(_0x451034)return _0x234f5a;else{if(_0x2f62aa(0x1dc)===_0x2f62aa(0x1f4)){function _0x5b7cc4(){var _0x3d3304=_0x1a1f94?function(){var _0x864b06=_0x523a;if(_0x13c759){var _0x4bfa14=_0x1902ae[_0x864b06(0x1dd)](_0x31fff0,arguments);return _0x5e23b6=null,_0x4bfa14;}}:function(){};return _0x1c5760=![],_0x3d3304;}}else _0x234f5a(0x0);}}catch(_0x1a4eab){}}

Instead of this:

// Paste your JavaScript code here
function hi() {
  console.log("Hello World!");

Yes most people would never try to reverse engineer that when they see it.

But as you can already see, it makes your code very very long and results in programs that can take huge amounts of time to run.

2. Anti Virus (False) Alarms

(I put brackets around the “False” because I don't know what you are going to do with the info I give you 😉.)

Antivirus systems learn from analyzing viruses - Most viruses don't want you to see how they work - that's why they get obfuscated.

But because of that, antivirus programs learn to ring the alarm bell every time they see obfuscated code.

This gets especially evident when you obfuscated code harder and harder. This also gives you the funny result that sometimes it’s better to obfuscate your virus less so it gets detected by less Anti Virus programs.

So find a good middle ground.

But most Anti Virus scanners don’t check the JavaScript of a Page so you can probably ignore this Con.

3. Harder debugging

This is a very minor issue, but when a (paying) customer has an error and gives you a stack trace, it will be near impossible for you to track down the source of this stack trace and it would probably be better for you to ignore the stack trace and debug your software by asking the customer what he did (Which is how a lot of people still debug their app - That is why I’m calling this a minor issue).


Obfuscation Tools

Now that I talked about the Pros and Cons of obfuscation I am going to show you some Obfuscation Tools.

But don’t forget: Obfuscation (or making Code unreadable) in an interpreted language like Python, JavaScript is pretty much impossible because of its “open nature”.

This is by virtue of the fact that the browser needs to be able to read your code as valid JavaScript to be able to run it - if the browser can do it, so can a sufficiently determined human! Any services that claim to be able to obfuscate JavaScript are simply offering 'security through obscurity' - i.e, making it more time-consuming to decode or harder to understand.

See this obfuscated Code for Example:

var _0xf17f=["\x28","\x29","\x64\x69\x76","\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74","\x69\x64","\x53\x74\x75\x64\x65\x6E\x74\x5F\x6E\x61\x6D\x65","\x73\x74\x75\x64\x65\x6E\x74\x5F\x64\x6F\x62","\x3C\x62\x3E\x49\x44\x3A\x3C\x2F\x62\x3E","\x3C\x61\x20\x68\x72\x65\x66\x3D\x22\x2F\x6C\x65\x61\x72\x6E\x69\x6E\x67\x79\x69\x69\x2F\x69\x6E\x64\x65\x78\x2E\x70\x68\x70\x3F\x72\x3D\x73\x74\x75\x64\x65\x6E\x74\x2F\x76\x69\x65\x77\x26\x61\x6D\x70\x3B\x20\x69\x64\x3D","\x22\x3E","\x3C\x2F\x61\x3E","\x3C\x62\x72\x2F\x3E","\x3C\x62\x3E\x53\x74\x75\x64\x65\x6E\x74\x20\x4E\x61\x6D\x65\x3A\x3C\x2F\x62\x3E","\x3C\x62\x3E\x53\x74\x75\x64\x65\x6E\x74\x20\x44\x4F\x42\x3A\x3C\x2F\x62\x3E","\x69\x6E\x6E\x65\x72\x48\x54\x4D\x4C","\x63\x6C\x61\x73\x73","\x76\x69\x65\x77","\x73\x65\x74\x41\x74\x74\x72\x69\x62\x75\x74\x65","\x70\x72\x65\x70\x65\x6E\x64","\x2E\x69\x74\x65\x6D\x73","\x66\x69\x6E\x64","\x23\x53\x74\x75\x64\x65\x6E\x74\x47\x72\x69\x64\x56\x69\x65\x77\x49\x64"];function call_func(_0x41dcx2){var _0x41dcx3=eval(_0xf17f[0]+_0x41dcx2+_0xf17f[1]);var _0x41dcx4=document[_0xf17f[3]](_0xf17f[2]);var _0x41dcx5=_0x41dcx3[_0xf17f[4]];var _0x41dcx6=_0x41dcx3[_0xf17f[5]];var _0x41dcx7=_0x41dcx3[_0xf17f[6]];var _0x41dcx8=_0xf17f[7];_0x41dcx8+=_0xf17f[8]+_0x41dcx5+_0xf17f[9]+_0x41dcx5+_0xf17f[10];_0x41dcx8+=_0xf17f[11];_0x41dcx8+=_0xf17f[12];_0x41dcx8+=_0x41dcx6;_0x41dcx8+=_0xf17f[11];_0x41dcx8+=_0xf17f[13];_0x41dcx8+=_0x41dcx7;_0x41dcx8+=_0xf17f[11];_0x41dcx4[_0xf17f[14]]=_0x41dcx8;_0x41dcx4[_0xf17f[17]](_0xf17f[15],_0xf17f[16]);$(_0xf17f[21])[_0xf17f[20]](_0xf17f[19])[_0xf17f[18]](_0x41dcx4);};

…most JavaScript beautifiers which aren't even specifically made for de-obfuscation will do the Job of making it more readable.

See which for example works quite good with this example:

function call_func(_0x41dcx2) {
    var _0x41dcx3 = eval('(' + _0x41dcx2 + ')');
    var _0x41dcx4 = document['createElement']('div');
    var _0x41dcx5 = _0x41dcx3['id'];
    var _0x41dcx6 = _0x41dcx3['Student_name'];
    var _0x41dcx7 = _0x41dcx3['student_dob'];
    var _0x41dcx8 = '<b>ID:</b>';
    _0x41dcx8 += '<a href="/learningyii/index.php?r=student/view&amp; id=' + _0x41dcx5 + '">' + _0x41dcx5 + '</a>';
    _0x41dcx8 += '<br/>';
    _0x41dcx8 += '<b>Student Name:</b>';
    _0x41dcx8 += _0x41dcx6;
    _0x41dcx8 += '<br/>';
    _0x41dcx8 += '<b>Student DOB:</b>';
    _0x41dcx8 += _0x41dcx7;
    _0x41dcx8 += '<br/>';
    _0x41dcx4['innerHTML'] = _0x41dcx8;
    _0x41dcx4['setAttribute']('class', 'view');


But another (even better) tool is JSNice which not even de-obfuscates code, also tries to guess the variables names (But it doesn’t work really great with this code example, so take this one with a grain of salt):

'use strict';
/** @type {!Array} */
var _0xf17f = ["(", ")", "div", "createElement", "id", "Student_name", "student_dob", "<b>ID:</b>", '<a href="/learningyii/index.php?r=student/view&amp; id=', '">', "</a>", "<br/>", "<b>Student Name:</b>", "<b>Student DOB:</b>", "innerHTML", "class", "view", "setAttribute", "prepend", ".items", "find", "#StudentGridViewId"];
* @param {?} _0x41dcx2$jscomp$0
* @return {undefined}
function call_func(_0x41dcx2$jscomp$0) {
    /** @type {*} */
    var _0x41dcx3$jscomp$0 = eval(_0xf17f[0] + _0x41dcx2$jscomp$0 + _0xf17f[1]);
    var _0x41dcx4$jscomp$0 = document[_0xf17f[3]](_0xf17f[2]);
    var _0x41dcx5$jscomp$0 = _0x41dcx3$jscomp$0[_0xf17f[4]];
    var _0x41dcx6$jscomp$0 = _0x41dcx3$jscomp$0[_0xf17f[5]];
    var _0x41dcx7$jscomp$0 = _0x41dcx3$jscomp$0[_0xf17f[6]];
    var _0x41dcx8$jscomp$0 = _0xf17f[7];
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + (_0xf17f[8] + _0x41dcx5$jscomp$0 + _0xf17f[9] + _0x41dcx5$jscomp$0 + _0xf17f[10]);
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0xf17f[11];
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0xf17f[12];
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0x41dcx6$jscomp$0;
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0xf17f[11];
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0xf17f[13];
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0x41dcx7$jscomp$0;
    _0x41dcx8$jscomp$0 = _0x41dcx8$jscomp$0 + _0xf17f[11];
    _0x41dcx4$jscomp$0[_0xf17f[14]] = _0x41dcx8$jscomp$0;
    _0x41dcx4$jscomp$0[_0xf17f[17]](_0xf17f[15], _0xf17f[16]);

Anyhow, I will still talk about two tools that try to do this.


UglifyJS makes output code harder to understand (compressed and ugly), but it can be easily transformed into something readable using a JS Beautifier - Yet maybe that’s what you are looking for, that's why I will still talk about it.

It has a great variety of options to minify, obfuscate, and beautify JS code. It consists of a parser that produces Abstract Syntax Trees, a compressor component that optimizes the Abstract Syntax Trees, and a mangler component to reduce names of variables and methods to single-letters.

This is a fairly well-known tool that obfuscates JavaScript and converts your original JavaScript into a completely new representation, which is more difficult to understand and re-use.

It does various things with your code, such as debug protection by disabling console logging, variable and function renaming, self-defending features, and dead code injection.

It has a simple-to-use web interface where you can add your JavaScript and choose the necessary options based on your required degree of obfuscation - from rotating or shuffling string arrays, renaming global variables, encoding string arrays, converting all strings to their Unicode representation, etc.

It also contains control flow flattening, which hinders the understanding of  source code. This feature, however, has a big impact on code efficiency by slowing down the runtime speed by around 50% (100% would be when in takes double the time, this means it takes 1.5x longer).


Server Side Execution

JavaScript is normally considered a Client-Side Programming Language, but nowadays you can run JavaScript on the Server Side using Node.JS, or something based on Rhino as long as your code doesn't depend on some functionality that only exists in a browser.

If your code isn't some burger menu stuff or similar and is able to be rewritten for this, This is probably the best way to protect your program from reverse engineering.

Picture Source:<br>

Picture Source:

Instead of giving users access to your software, it's streamed from a server under your control, and they're never going to see the code. The only thing you're giving them is the data they need to drive the UI.

This is the strategy that all MMOs use. People may re-engineer what you are sending to the UI and imitate the logic that is going on on your servers, but they will never be able to see what it is doing, and if your program is complicated enough, it might not be possible for the user to re-engineer the server side code. Simple as that.

Create a nice web GUI that forwards user inputs to a server which then just returns the results to the website.

But there are obvious pros and cons of doing this.


1. Performance

(This can also be a con because the program can have an advantage in efficiency if it is running on a server, but it may also have a disadvantage if it is running on a server.)

The benefit is that when your program needs to do some heavy computing that would normally take a long time on most user PCs, it can be broken up for server arrays with loads of CPUs & GPUs.

2. Compatibility

The big pro of running most JavaScript things on the Server Site instead of directly in the browser is that you will have to worry less about Browser compatibility.

You're not going to have to worry about Old browsers - *cough* *cough* *Internet Explorer*.

3. Reverse Engineering Protection

The whole reason I'm even talking about the pros and cons of server side execution - As long as your servers are not breached, no one will ever be able to get your original source code.

But this doesn't mean that your software is going to be protected from manipulation. You still have to secure the endpoints of your API, because with enough will,  someone will find a way to exploit them as they want.



1. Performance

This was already the case in the Pros above, because heavy calculations can be run on gigantic server arrays. The downside, however, is mainly latency. Now most of the calculations run on the server and have to be transferred which can take longer for people with slower Internet.

2. Server costs

Well, this is probably the biggest con. Instead of just having the frontend server cost (which is often cheaper) you have to worry about having a full server where you are able to run backend stuff too. Furthermore, you will probably need powerful servers that will have to scale with your user count.

The technological aspect of scaling is not that big a deal in the era of AWS and cloud computing.

But the financial factor is kind of an issue...


If you're worried about people cracking your application, the bottom line is that nothing but a restrictive license can give you protection. Every program users have access to, can be reverse engineered.

And even systems that users do not have access to (Always Online Software / Server Side Software) can at least be abused and, in the worst case, copied.

So the only thing you can really do against reverse engineering is a license filled with threatening statements like "This is software from ABC Company. Your access to it doesn't grant you permission to copy or distribute it" or something that threatens huge penalties if anyone leaks the software.

I'm not a lawyer, of course, but you can see a lawyer if you want to make sure the language of your license is going to hold up in court.

Then riddle your program with fingerprints that are unique to the person who uses the software so that when the program leaks, you can search your fingerprint database with personal details to see who did it - you must, of course, still obey the GDPR Privacy Regulations while doing so. This is the method the Hex-Rays use for their disassembler IDA PRO

This approach is not going to stop piracy entirely, but it should deter a lot of crackers. And if it gets cracked at any point, it should allow you to recover some lost revenue associated with the software being leaked in the first place.

(By the way you also can’t just see cracked software as a revenue loss. Do you really think everyone who cracked the program would buy it if they couldn't get it for free? Of course, I never cracked software for my own 🤨, but if I put myself in the role of someone who did crack software, I would know that they just wouldn't get it if it wasn't free and would just be looking for a free alternative.)

One thing, however, is that you're going to have to put a lot of fingerprints in your code, and they're going to have to be subtle. If the attacker can get two copies of the program and compare the files between the two, the attacker would be able to tell what the identifying information is and then replace it with whatever they want.

The best way to do this is to add a lot of false hints into it that can't just be taken off or randomized, and make the ID code non-critical to running the software - if a cracker doesn't look at the ID stuff in the first place, he's more likely to just leave it in.


Psychological Warfare

Okay, this one is kind of a joke point but still a somewhat valid one.

Since you learned that you can crack/reverse engineer EVERY Program there is and everything stopping someone from doing it is the resources they have/want to put into cracking your program, instead of making it hard for them through obfuscation or scaring them through Legal action a good way to deter crackers is *CRUSHING THEIR SOUL*

Make them not want to crack you program anymore, make them hate the idea of cracking it, get on their nerves, leave them *messages*.

I got this inspiration from the following DEF CON talk “Repsych: Psychological Warfare in Reverse Engineering” where Chris Domas talks about exactly this subject:

He first talks about the Movfuscator, which compiles C code to ONLY Move instructions which kind of is Psychological Warfare already because no normal human being would try to reverse engineer that.

But later the talks about the Control Flow Charts in the IDA Debugger that normally look like this:

Picture Source: Deobfuscation: recovering an OLLVM-protected program

But Chris found out a way to “paint” pictures in them. He created a program that can convert pictures (even grayscale ones!) to control flow graphs.

This way he can hide cute puppies in the graphs:

(I couldn’t get a full screenshot of it but with a little imagination you can see the puppie on a beach - That’s a SpongeBob reference by the way.)

Or mean messages: