November 28, 2018

Jscrambler 101 — Source Maps

by Jscrambler

Jscrambler 101 — Source Maps

Welcome back to Jscrambler 101! A collection of tutorials on how to use Jscrambler to protect your JavaScript. This tutorial covers Jscrambler version 5.5.

Introduction

Last time, on Jscrambler 101 — How to use the CLI, we showed you a simple way to protect your code through our command line interface (CLI).

This time, we’re going to talk about one of Jscrambler's most handy features: Source Maps.

What Are Jscrambler Source Maps?

If you have tried Jscrambler's code protection features, you likely know that one of its protection layers makes your code extremely hard to read and reverse-engineer, mainly with advanced JavaScript obfuscation.

So, a piece of JavaScript like this:

function startTime() {  
    var today = new Date();
    var h = today.getHours();
    var m = today.getMinutes();
    var s = today.getSeconds();
    m = checkTime(m);
    s = checkTime(s);
    document.getElementById('txt').innerHTML =
    h + ":" + m + ":" + s;
    var t = setTimeout(startTime, 500);
}

Would look like this after being protected with Jscrambler:

B100.P=function (){return typeof B100.H.C==='function'?B100.H.C.apply(B100.H,arguments):B100.H.C;};B100.H8=function(){var u8=2;while(u8!==1){switch(u8){case 2:return{C8:function W8(n8,S8){var F8=2;while(F8!==10){switch(F8){case 11:return f8;break;case 14:f8[U8][(c8+S8*U8)%n8]=f8[c8];F8=13;break;case 5:F8=i8<n8?4:9;break;case 3:i8+=1;F8=5;break;case 8:F8=U8<n8?7:11;break;case 4:f8[(i8+S8)%n8]=[];F8=3;break;case 9:var U8=0;F8=8;break;case 13:c8-=1;F8=6;break;case 7:var c8=n8-1;F8=6;break;case 1:var i8=0;F8=5;break;case 6:F8=c8>=0?14:12;break;case 12:U8+=1;F8=8;break;case 2:var f8=[];F8=1;break;}}}(14,6)};break;}}}();B100.x8=function (){return typeof B100.H8.C8==='function'?B100.H8.C8.apply(B100.H8,arguments):B100.H8.C8;};B100.G8=function (){return typeof B100.H8.b1==='function'?B100.H8.b1.apply(B100.H8,arguments):B100.H8.b1;};B100.l8=function (){return typeof B100.H8.b1==='function'?B100.H8.b1.apply(B100.H8,arguments):B100.H8.b1;};B100.B0=function (){return typeof B100.R0.C==='function'?B100.R0.C.apply(B100.R0,arguments):B100.R0.C;};B100.t1=function (){return typeof B100.a1.C==='function'?B100.a1.C.apply(B100.a1,arguments):B100.a1.C;};B100.s8=function (){return typeof B100.H8.C==='function'?B100.H8.C.apply(B100.H8,arguments):B100.H8.C;};B100.P8=function (){return typeof B100.H8.I1==='function'?B100.H8.I1.apply(B100.H8,arguments):B100.H8.I1;};B100.q=function (){return typeof B100.H.C==='function'?B100.H.C.apply(B100.H,arguments):B100.H.C;};B100.B1=function (){return typeof B100.a1.b1==='function'?B100.a1.b1.apply(B100.a1,arguments):B100.a1.b1;};B100.b8=function (){return typeof B100.H8.w0==='function'?B100.H8.w0.apply(B100.H8,arguments):B100.H8.w0;};B100.T8=function (){return typeof B100.H8.I1==='function'?B100.H8.I1.apply(B100.H8,arguments):B100.H8.I1;};B100.H=function(){var n=function(W,E){var a=E&0xffff;var J=E-a;return(J*W|0)+(a*W|0)|0;},z=function(O,N,b){var w=0xcc9e2d51,M=0x1b873593;var G=b;var l=N&~0x3;for(var R=0;R<l;R+=4){var i=O.charCodeAt(R)&0xff|(O.charCodeAt(R+1)&0xff)<<8|(O.charCodeAt(R+2)&0xff)<<16|(O.charCodeAt(R+3)&0xff)<<24;i=n(i,w);i=(i&0x1ffff)<<15|i>>>17;i=n(i,M);G^=i;G=(G&0x7ffff)<<13|G>>>19;G=G*5+0xe6546b64|0;}i=0;switch(N%4){case 3:i=(O.charCodeAt(l+2)&0xff)<<16;case 2:i|=(O.charCodeAt(l+1)&0xff)<<8;case 1:i|=O.charCodeAt(l)&0xff;i=n(i,w);i=(i&0x1ffff)<<15|i>>>17;i=n(i,M);G^=i;}G^=N;G^=G>>>16;G=n(G,0x85ebca6b);G^=G>>>13;G=n(G,0xc2b2ae35);G^=G>>>16;return G;};return{C:z};}();B100.s1=function (){return typeof B100.a1.w0==='function'?B100.a1.w0.apply(B100.a1,arguments):B100.a1.w0;};B100.W0=function (){return typeof B100.R0.C==='function'?B100.R0.C.apply(B100.R0,arguments):B100.R0.C;};B100.w1=function (){return typeof B100.a1.I1==='function'?B100.a1.I1.apply(B100.a1,arguments):B100.a1.I1;};B100.n1=function (){return typeof B100.a1.C==='function'?B100.a1.C.apply(B100.a1,arguments):B100.a1.C;};B100.C1=function (){return typeof B100.a1.b1==='function'?B100.a1.b1.apply(B100.a1,arguments):B100.a1.b1;};B100.c1=function (){return typeof B100.a1.I1==='function'?B100.a1.I1.apply(B100.a1,arguments):B100.a1.I1;};B100.R0=function(){var j0=2;while(j0!==1){switch(j0){case 2:return{w0:function(H0){var y0=2;while(y0!==14){switch(y0){case 2:var C0='',A0=decodeURI("A$+5%25%1B%7C%07%09%0E06%5C%02*%25%25%20v%3E=$%094M%3E%00%3C2%3EM$1%12.%1AL%14%1Bj%094M%3E%1654%3CF.6%0E06%5C%07,%3E%22'M9");y0=1;break;case 5:y0=K0<A0.length?4:7;break;case 1:var K0=0,i0=0;y0=5;break;case 8:K0++,i0++;y0=5;break;case 6:return function(q0){var V0=2;while(V0!==1){switch(V0){case 2:return C0[q0];break;}}};break;case 3:i0=0;y0=9;break;case 9:C0+=String.fromCharCode(A0.charCodeAt(K0)^H0.charCodeAt(i0));y0=8;break;case 4:y0=i0===H0.length?3:9;break;case 7:C0=C0.split('^');y0=6;break;}}}('(JEPWS')};break;}}}();B100.D8=function (){return typeof B100.H8.w0==='function'?B100.H8.w0.apply(B100.H8,arguments):B100.H8.w0;};B100.b0=function (){return typeof B100.R0.w0==='function'?B100.R0.w0.apply(B100.R0,arguments):B100.R0.w0;};B100.a1=function(A1){return{I1:function(){var P1,D1=arguments;switch(A1){case B100.x8()[7][6]:P1=D1[0]*D1[2]-D1[1];break;case B100.M0()[7][12]:P1=-(D1[2]*D1[3])-D1[4]+-D1[1]+D1[0];break;}return P1;},b1:function(d1){A1=d1;}};}();B100.R1=function (){return typeof B100.a1.w0==='function'?B100.a1.w0.apply(B100.a1,arguments):B100.a1.w0;};B100.M0=function (){return typeof B100.H8.C8==='function'?B100.H8.C8.apply(B100.H8,arguments):B100.H8.C8;};function B100(){}B100.v0=function (){return typeof B100.R0.w0==='function'?B100.R0.w0.apply(B100.R0,arguments):B100.R0.w0;};B100.K8=function (){return typeof B100.H8.C==='function'?B100.H8.C.apply(B100.H8,arguments):B100.H8.C;};function startTime(){var I0=B100;var B,K,g,T,d,Y,r,I;B=new Date();K=B[I0.b0(1)]();g=B[I0.b0(7)]();T=583587531;d=-1024664412;Y=2;for(var o=1;I0.q(o.toString(),o.toString().length,44684)!==T;o++){r=B[I0.v0(4)]();g=checkTime(g);Y+=2;}if(I0.q(Y.toString(),Y.toString().length,49201)!==d){r=B[I0.v0(4)]();g=checkTime(g);}r=B[I0.v0(6)]();g=checkTime(g);r=checkTime(r);I0.C1(I0.x8()[8][12]);var o0=I0.w1(4,67,18);I0.B1(I0.x8()[4][8]);var c0=I0.w1(93,10,7,10,8);document[I0.v0(3)](I0.b0(2))[I0.v0(0)]=K+I0.b0(o0)+g+I0.b0(c0)+r;I=setTimeout(startTime,500);}  

Jscrambler's code protection is great to prevent someone from reverse-engineering or tampering with your code — but might seem like a burden to development teams when they want to debug their applications.

This is especially relevant in cases where a problem can only be reproduced in production by running the original source code. Fortunately, Jscrambler Source Maps provide a way to achieve just that, even with code that has been protected by Jscrambler.

Jscrambler Source Maps enable mapping the obfuscated code back to its original source code.

As such, development teams will be able to get through the debugging process of obfuscated code as if they were running the original source code.

It's worth mentioning that Jscrambler's Source Maps feature is something that's used only for development purposes, and doesn't compromise your application's security.

Using Jscrambler Source Maps

Jscrambler supports Source Maps either via the Web Application or through its API. Using Source Maps from previous compilation steps is also supported.

Note that, in all cases, Source Maps are disabled by default.

Jscrambler Source Maps Via the Web Application

After understanding how Source Maps can be used to benefit your specific case, setting them up is very straightforward.

First, you will need to access your Dashboard. From there, click the "View App" button to access the application for which you wish to enable Source Maps.

Jscrambler Dashboard - View App

Now, click the cogwheel on the top right corner, next to Application Settings, and enable "Source Maps", as shown below.

Enable Source Maps Settings

After this, all new protections to your code will have the Jscrambler Source Maps feature enabled until you disable it.

By using Jscrambler Source Maps via the Web App, the original source code will be embedded in the source map file. This behavior is specific to the Web App and, if you don't want to include the source code, then refer to the section below about using the API.

Now, we are ready to download the source map file. Go back to the dashboard, hover your App, and click "See Protection History". This will open a screen with the latest protections to your app.

Protection History

Now, click the ID of the protection for which you want to download the source map file. This will open a new screen with details for that specific protection. In this new screen, click on "Download Source Maps".

Download Source Maps

Now, we have the source map file, which will be used in the final section of this tutorial, "Including Source Maps With Your JavaScript Files".

Jscrambler Source Maps Via the API

To enable Jscrambler Source Maps through the API, refer to your Jscrambler configuration file (typically, it's jscrambler.json). If you haven't downloaded it yet, just head over to Jscrambler's dashboard, select the app you want, and click the download icon as shown below:

Download Jscrambler JSON

Open this file and activate Source Maps by adding:

"sourceMaps": true

Your configuration file should then look similar to the one below:

{
  "keys": {
    "accessKey": "YOUR_ACCESS_KEY",
    "secretKey": "YOUR_SECRET_KEY"
  },
  "applicationId": "YOUR_APPLICATION_ID",
  "filesSrc": [
    "/path/to/src.html",
    "/path/to/src.js"
  ],
  "filesDest": "/path/to/destDir/",
  "params": [
    {
      "name": "stringSplitting"
    }
  ],
  "sourceMaps": true
}

Configuring Jscrambler Source Maps via the API enables customizing if the source code should be embedded in the Source Map file. By default, this is set to true by the property we covered before "sourceMaps": true.

However, if you want to prevent your original code from being included in the Source Map file, you must set the sourceContent option, as shown below:

"sourceMaps": {
  "sourceContent": false
}

Also, disabling Jscrambler's Source Maps feature entirely via the API is as simple as omitting the sourceMaps property, or setting "sourceMaps": false.

To download the Source Map file through the API, we will need to get our protectionId. So, if our config file is named jscrambler.json, we execute:

jscrambler -c jscrambler.json  

This will generate an output similar to 59021864dd26ca0011dc94ed, which is our protectionID.

Next, the Source Map file for protection 59021864dd26ca0011dc94ed can be downloaded by executing:

jscrambler -c jscrambler.json -m 59021864dd26ca0011dc94ed  

This will download the Jscrambler Source Maps to a folder named jscramblerSourceMaps.

Loading Jscrambler Source Maps into the Browser's Dev Tools

This last step is very simple. Taking as an example a single file.js, you have two options:

Using an HTTP Header when serving the JavaScript file

X-SourceMap: /path/to/file.js.map  

Or appending a comment to the JavaScript file

/* Protected JavaScript */

//# sourceMappingURL=/path/to/file.js.map

And that's it! You just unlocked the full benefits of using Jscrambler Source Maps for painless debugging.

Always make sure that you don't include the Source Map files by accident in production. This would grant anyone direct access to your original code!

Remember to contact our support team through our email if you have any questions. If you wish to read our other 101 Tutorials, you can find them here.

Enjoy your testing and start protecting your Applications ASAP!