Jump to content

Recommended Posts

Not sure if anyone is interesting on this. I am currently trying to develop a new way to reasonably *protect* full Javascript code, and just out of curiosity: can you actually rip this?

https://imersiva.com/security_test ]

Probably an easy task for some people, who knows, rippers get very creative some times.

I am not worrying about the WebGL shader code for now, but just the Javascript part. Are you able to rip that program completely and run it on your own machine or anywhere else?

Thanks. =)

Link to post
Share on other sites
46 minutes ago, imerso said:

Not sure if anyone is interesting on this. I am currently trying to develop a new way to reasonably *protect* full Javascript code, and just out of curiosity: can you actually rip this?

https://imersiva.com/security_test ]

Probably an easy task for some people, who knows, rippers get very creative some times.

I am not worrying about the WebGL shader code for now, but just the Javascript part. Are you able to rip that program completely and run it on your own machine or anywhere else?

Thanks. =)

    var vertexSource = `
        attribute vec3 pos;
        void main(void)
        {
            gl_Position = vec4(pos, 1.0);
        }
    `;

    var fragmentSource = `
        precision highp float;

        uniform vec2 res;        // canvas res
        uniform float time;        // simulation time
        uniform vec2 mouse;        // normalized mouse coordinates
        uniform vec3 cam;        // camera position

        void main(void)
        {
            // plasma by imerso
            #define PI 3.1415926535897932384626433832795
            vec2 uv = vec2(gl_FragCoord.x/res.x, gl_FragCoord.y/res.y) - vec2(.5, .5);
            uv.x += 0.1*sin(time) + 0.2 * sin(time+uv.y*4.);
            uv.y += 0.1*cos(time*0.33) + 0.2 * sin(time+uv.x*3.);
            vec2 suv = uv * (8. + 4. * sin(time));                        // zoom
            float lum = sin(suv.x+time) + sin(suv.y+time/2.);        // repeat
            lum += sin(sqrt(suv.x*suv.x + suv.y*suv.y)+time*1.5);        // distance field
            vec3 c = vec3(sin(lum*PI), 0., cos(lum*PI));            // cyclic color
            c.y = c.x * c.z;                        // cyclic color
            gl_FragColor = vec4(c, 1.0);
        }

    `;

Link to post
Share on other sites

From hacking perspective nothing changed?

var gl;
var canvas;
var cam = new Object();
var mouse = new Object();

var demoTime = 0;
var curTime = (new Date).getTime();
var lastTime = curTime;
var elapsed;

// shader
var program;
var posAttr, resAttr, timeAttr, camAttr, mouseAttr;

// quad definition
var vertices = [ -1,1,0, -1,-1,0, 1,-1,0, 1,1,0 ];
var indices = [ 3, 2, 1, 3, 1, 0 ];

// vertex and index buffers
var vb, ib;


Run();


// run demo
function Run()
{
    document.body.style = "height:100%; width:100%; padding:0; margin:0; font-family:Tahoma; background:#000000; font-color:#808080; overflow:hidden";

    // init canvas
    canvas = document.createElement("canvas");
    canvas.style.width = "100%";
    canvas.style.height= "100%";
    document.body.appendChild(canvas);
    if (!canvas) { alert('glcanvas not found'); return false; }
    canvas.width = 800;
    canvas.height = 450;

    var div = document.createElement("div");
    div.style = "position:absolute; top:32px; left:32px; font-family:verdana; font-size:32px; color:#FFFF00; font-weight:bold";
    div.innerHTML = "CAN YOU<br>STEAL THIS<br>JAVASCRIPT CODE?";
    document.body.appendChild(div);

    // init gl
    if (!(gl = InitGL(canvas))) { alert('failed to initialize webgl'); return false; }
    if (!LoadShader()) { alert('failed to load shaders'); return false; }
    CreateQuad();

    cam.x = cam.y = 0;
    cam.z = -100;
    mouse.x = canvas.width / 2;
    mouse.y = canvas.height / 2;

    // activate shader and vertex attribute
    gl.useProgram(program);
    gl.enableVertexAttribArray(posAttr);

    // pass the values which will remain fixed for the entire demo
    gl.vertexAttribPointer(posAttr, 3, gl.FLOAT, false, 0, 0);
    gl.uniform2fv(resAttr, [canvas.width, canvas.height]);

    // mouse handling
    canvas.addEventListener('mousemove', function(event)
    {
        var rect = canvas.getBoundingClientRect();
        mouse.x = event.clientX - rect.left;
        mouse.y = event.clientY - rect.top;
    });

    // touch handling
    canvas.addEventListener('touchmove', function(event)
    {
        var rect = canvas.getBoundingClientRect();
        mouse.x = event.touches[0].clientX - rect.left;
        mouse.y = event.touches[0].clientY - rect.top;
    });

    // start demo loop
    requestAnimationFrame(Draw);

    // succeeded
    return true;
}


// switch to fullscreen
function RequestFullscreen()
{
    if (document.fullscreenEnabled) return;

    if (canvas.requestFullscreen)
    {
        canvas.requestFullscreen();
    }
    else if (canvas.msRequestFullscreen)
    {
        canvas.msRequestFullscreen();
    }
    else if (canvas.mozRequestFullScreen)
    {
        canvas.mozRequestFullScreen();
    }
    else if (canvas.webkitRequestFullscreen)
    {
        canvas.webkitRequestFullscreen();
    }
}


// initialize gl
function InitGL()
{
    var gl = null;

    try
    {
        gl = canvas.getContext("webgl", {antialias:false});
        gl.disable(gl.DEPTH_TEST);
        gl.viewport(0, 0, canvas.width, canvas.height);
    }
    catch(e)
    {
    }

    return gl;
}


// create a fullscreen quad
function CreateQuad()
{
    vb = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vb);

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);

    ib = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ib);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

    gl.bindBuffer(gl.ARRAY_BUFFER, vb);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ib);
}


// load and compile shaders
function LoadShader()
{
    var vertexSource = `
        attribute vec3 pos;
        void main(void)
        {
            gl_Position = vec4(pos, 1.0);
        }
    `;

    var fragmentSource = `
        precision highp float;

        uniform vec2 res;        // canvas res
        uniform float time;        // simulation time
        uniform vec2 mouse;        // normalized mouse coordinates
        uniform vec3 cam;        // camera position

        void main(void)
        {
            // plasma by imerso
            #define PI 3.1415926535897932384626433832795
            vec2 uv = vec2(gl_FragCoord.x/res.x, gl_FragCoord.y/res.y) - vec2(.5, .5);
            uv.x += 0.1*sin(time) + 0.2 * sin(time+uv.y*4.);
            uv.y += 0.1*cos(time*0.33) + 0.2 * sin(time+uv.x*3.);
            vec2 suv = uv * (8. + 4. * sin(time));                        // zoom
            float lum = sin(suv.x+time) + sin(suv.y+time/2.);        // repeat
            lum += sin(sqrt(suv.x*suv.x + suv.y*suv.y)+time*1.5);        // distance field
            vec3 c = vec3(sin(lum*PI), 0., cos(lum*PI));            // cyclic color
            c.y = c.x * c.z;                        // cyclic color
            gl_FragColor = vec4(c, 1.0);
        }

    `;

    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexSource);
    gl.compileShader(vertexShader);

    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentSource);
    gl.compileShader(fragmentShader);

    program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return false;

    posAttr = gl.getAttribLocation(program, "pos");
    resAttr = gl.getUniformLocation(program, "res");
    timeAttr = gl.getUniformLocation(program, "time");
    mouseAttr = gl.getUniformLocation(program, "mouse");
    camAttr = gl.getUniformLocation(program, "cam");

    return true;
}


// load one shader program
function GetShader(id)
{
    var shaderScript = document.getElementById(id);
    if (!shaderScript) return null;

    var theSource = "";
    var currentChild = shaderScript.firstChild;

    while(currentChild)
    {
        if (currentChild.nodeType == 3)
        {
            theSource += currentChild.textContent;
        }

        currentChild = currentChild.nextSibling;
    }

    var shader;

    if (shaderScript.type == "x-shader/x-fragment")
    {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    }
    else if (shaderScript.type == "x-shader/x-vertex")
    {
        shader = gl.createShader(gl.VERTEX_SHADER);
    }
    else return null;

    gl.shaderSource(shader, theSource);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
    {
        alert('fragment error: ' + gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}


// draw scene
function Draw()
{
    // update demo time
    curTime = (new Date).getTime();
    elapsed = curTime - lastTime;
    lastTime = curTime;
    demoTime += elapsed / 1000;

    // normalize mouse coords
    var mx = mouse.x / window.innerWidth;
    var my = mouse.y / window.innerHeight;

    // update shader variables
    gl.uniform1f(timeAttr, demoTime);
    gl.uniform2fv(mouseAttr, [ mx, my ]);
    gl.uniform3fv(camAttr, [ cam.x, cam.y, cam.z ]);

    // draw fullscreen quad
    gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

    // next frame
    requestAnimationFrame(Draw);
}

Link to post
Share on other sites
  • 3 months later...

@imerso

I'm not sure why you would want to do this - unless you were hard coding passwords and other high security info in your JS - which would be a huge mistake anyway. Otherwise, I've found practically nothing that is written in JavaScript which needs to be hidden as there's practically very little "new" approaches to accomplishing what is seen on-screen, and most any JS developer can recrete whatever they see.

If you're trying to hide server side operations, then you can look at Socket.IO and Node.IO to hide much of what you are doing which you wish to remain secure. Also look at exmples of obfuscation - which to me is more wasted time than what you wish to accomplish - and you had better be a creatinve developer as there's no reason or logic which will take you step by step through how you choose to create machine code which makes sense within your application.

My company has built a node.js server brain which determines operations on the srver side, and is remote from the application and local functions - as again, show me a function locally, and I'll be able to recreate it with little effort generally. Perhaps if you describe "why" you need to hide your JS code, then we might be able to assist. Otherwise, it simply makes no sense as to why hide your JS files in the first place. It also depends on who you are trying to hide the scripts from. If you're attempting to hide from most common front end developers, then perhaps use a combination of PHP and run your "secret" scripts server side using ASP - then call it via AJAX. However, almot anything can still be read by anyone who really wants to read it. Once again, why?

DB

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...