Created
March 23, 2016 02:17
-
-
Save towerofnix/af2caa3bb82a59ab3f5e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Notes: **READ ALL OF THESE** | |
Original source of the program is here: | |
https://scratch.mit.edu/discuss/post/1868091/ | |
I've slightly modified the code (pretty-printed, renamed a couple variables, | |
etc. - don't forget to read these notes! - but the old code is still intact | |
here. If you're curious about what the original entirely non-modified code | |
was though don't hesitate to open that link. :P | |
Variable names are shortened to three characters in the guide, i.e. | |
"v1734c920f74b86f10c57800e3b4c69d0" to "v17[..]". | |
Within the guide, | |
* "data" refers to the _0xbcb9 array that I renamed to data. | |
* "lib" refers to the v8556a7b67af9dc854f44a6c0d4718aa4 array that I renamed to | |
lib. | |
* "storage" refers to the v2060faea334945e1d530c548660e8151 array that I didn't | |
rename because renaming would cause issues within the actual encoded function | |
data. | |
Some purely unnecessary spam library calls were removed from the source, as | |
well as the unused library methods. | |
Beware the lines that have over 80 characters across. You should disable word | |
wrapping in your text editor or code viewer becaues it'll just make reading the | |
guide so much better. | |
This is a pretty long document! It took me about two hours to write it (and | |
figure out how the program worked, as I was writing it..) and I'm not entirely | |
sure it'll be very easy or fun to walk through, but that was my goal so.. I can | |
always hope you enjoy it? :) | |
*/ | |
/* ------- */ | |
// Renamed _0xbcb9 to data. | |
var data = [ | |
// Replaced all escape coded strings w/ their actual evaluated strings, ie | |
// "\x74\x65\x78\x74" === "text" so I replaced "\x74\x65\x78\x74" with | |
// "text" (for easier reading). | |
// #0 | |
, | |
// #1 | |
"createElement", | |
// #2 | |
"getContext", | |
// #3 | |
"text", | |
// #4 (I couldn't find a use of this in the program.) | |
"c837307a9a2ad4d08ca61a4f1bd848ba3d6890fcb73f74ea6e3907a0d0cd8a30014b32ad", | |
// #5 | |
"9c882d5c6a1aa240b2672dce0ffb03360abcaca50fca0a1767504a7aaf8f6a5f6a481ef0", | |
// #6 | |
"display", | |
// #7 | |
"style", | |
// #8 | |
"none", | |
// #9 | |
"onload", | |
// #10 | |
"src", | |
// #11, the name of the argument passed to most dynamically created | |
// functions | |
"vdfae0ffa569e9b81bccad7485560e63f", | |
// #12, THIS IS THE DECODE FUNCTION, it is used to decode lots of things | |
"return unescape(decodeURIComponent(window.atob(vdfae0ffa569e9b81bccad7485560e63f)))", | |
// #13, decoded: | |
/* | |
return 'canvas'; | |
*/ | |
"cmV0dXJuJTIwJ2NhbnZhcyclM0I=", | |
// #14, decoded: | |
/* | |
return 'none'; | |
*/ | |
"cmV0dXJuJTIwJ25vbmUnJTNC", | |
// #15, decoded: | |
/* | |
return '2d'; | |
*/ | |
"cmV0dXJuJTIwJzJkJyUzQg==", | |
// #16, decoded: | |
/* | |
return 'script'; | |
*/ | |
"cmV0dXJuJTIwJ3NjcmlwdCclM0I=", | |
// #17 | |
"", | |
// #18, probably a variable | |
"v6d69d61d21a9622f6bae5f2fb94b085c", | |
// #19, probably a variable | |
"v7a0c2f384080b6f1b7f66271458e3285", | |
// #20, decoded: | |
/* | |
return 'data:image/png;base64,'; | |
*/ | |
"cmV0dXJuJTIwJ2RhdGElM0FpbWFnZSUyRnBuZyUzQmJhc2U2NCUyQyclM0I=", | |
// #21, the image source | |
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAkUlEQVQImQXBsQqCYACF0U/5JS/UYlHgEkHRGNUz9CatPmRv4NJQkE1uIjbUDYTsnKg4Fxa6maMo4Qd76AmurV40ojXAGr5wUVAOpVlhIJUaqOBETAQzsZASkeHMTPDVsV/igO/wsD7QymPYEpPYTzOCJe7QFG3grViDNEg7HERuB1xB6mBZNR5QgEaeQ2ca/QGPLzxvc1LOxgAAAABJRU5ErkJggg==", | |
// #22, decoded: | |
/* | |
return v9e070ab7ccfd61fff8dd382d7e02a2b0 | |
.getElementById(vdfae0ffa569e9b81bccad7485560e63f); | |
*/ | |
"cmV0dXJuJTIwdjllMDcwYWI3Y2NmZDYxZmZmOGRkMzgyZDdlMDJhMmIwLmdldEVsZW1lbnRCeUlkKHZkZmFlMGZmYTU2OWU5YjgxYmNjYWQ3NDg1NTYwZTYzZiklM0I=", | |
// #23, decoded: | |
/* | |
return document | |
*/ | |
"cmV0dXJuJTIwZG9jdW1lbnQ=", | |
// #24, decoded: | |
/* | |
for (v4be7b6ee7554fb965b2460f341bd2701 = v62c4c9ef94561dc30351b877b376b93f[2]; | |
v4be7b6ee7554fb965b2460f341bd2701 < v34b8f090cb414c065e63ecd587bac498.data.length; | |
v4be7b6ee7554fb965b2460f341bd2701 += 4) | |
v8de318bf92f1e91a9ceef7dc499987d9 += ( | |
v34b8f090cb414c065e63ecd587bac498.data[v4be7b6ee7554fb965b2460f341bd2701] != | |
v62c4c9ef94561dc30351b877b376b93f[1] | |
) ? vbc7e070b51bbf801d0583ccbca7b8fe4(v34b8f090cb414c065e63ecd587bac498.data[v4be7b6ee7554fb965b2460f341bd2701]) | |
: v2060faea334945e1d530c548660e8151[4]; | |
v8de318bf92f1e91a9ceef7dc499987d9 = v8de318bf92f1e91a9ceef7dc499987d9.trim(); | |
*/ | |
"Zm9yKHY0YmU3YjZlZTc1NTRmYjk2NWIyNDYwZjM0MWJkMjcwMSUzRHY2MmM0YzllZjk0NTYxZGMzMDM1MWI4NzdiMzc2YjkzZiU1QjIlNUQlM0IlMjB2NGJlN2I2ZWU3NTU0ZmI5NjViMjQ2MGYzNDFiZDI3MDElMjAlM0MlMjB2MzRiOGYwOTBjYjQxNGMwNjVlNjNlY2Q1ODdiYWM0OTguZGF0YS5sZW5ndGglM0IlMjB2NGJlN2I2ZWU3NTU0ZmI5NjViMjQ2MGYzNDFiZDI3MDElMkIlM0Q0KXY4ZGUzMThiZjkyZjFlOTFhOWNlZWY3ZGM0OTk5ODdkOSUyQiUzRCh2MzRiOGYwOTBjYjQxNGMwNjVlNjNlY2Q1ODdiYWM0OTguZGF0YSU1QnY0YmU3YjZlZTc1NTRmYjk2NWIyNDYwZjM0MWJkMjcwMSU1RCElM0R2NjJjNGM5ZWY5NDU2MWRjMzAzNTFiODc3YjM3NmI5M2YlNUIxJTVEKSUzRnZiYzdlMDcwYjUxYmJmODAxZDA1ODNjY2JjYTdiOGZlNCh2MzRiOGYwOTBjYjQxNGMwNjVlNjNlY2Q1ODdiYWM0OTguZGF0YSU1QnY0YmU3YjZlZTc1NTRmYjk2NWIyNDYwZjM0MWJkMjcwMSU1RCklM0F2MjA2MGZhZWEzMzQ5NDVlMWQ1MzBjNTQ4NjYwZTgxNTElNUI0JTVEJTNCJTIwdjhkZTMxOGJmOTJmMWU5MWE5Y2VlZjdkYzQ5OTk4N2Q5JTNEdjhkZTMxOGJmOTJmMWU5MWE5Y2VlZjdkYzQ5OTk4N2Q5LnRyaW0oKSUzQg==", | |
// #25, decoded: | |
/* | |
return new Image(); | |
*/ | |
"cmV0dXJuJTIwbmV3JTIwSW1hZ2UoKSUzQg==", | |
// #26, decoded: | |
/* | |
return String.fromCharCode(vdfae0ffa569e9b81bccad7485560e63f); | |
*/ | |
"cmV0dXJuJTIwU3RyaW5nLmZyb21DaGFyQ29kZSh2ZGZhZTBmZmE1NjllOWI4MWJjY2FkNzQ4NTU2MGU2M2YpJTNC", | |
// #27 | |
"width", | |
// #28 | |
"height", | |
// #29 | |
"drawImage", | |
// #30 | |
"getImageData"]; | |
// Renamed v8556a7b67af9dc854f44a6c0d4718aa4 to lib. | |
// Also each function takes a parameter _0x7b17x1, I renamed that | |
// to arg. | |
lib = [ | |
, // 0 | |
function(arg) { // 1 | |
// runs document.createElement with the given argument | |
// (v9e[..] is the document/<html> element, data[1] is createElement) | |
return v9e070ab7ccfd61fff8dd382d7e02a2b0[data[1]](arg) | |
}, | |
function(arg) { // 2 | |
// runs data[2] (or 'getContext') of arg[0] with arg[1] | |
return arg[0][data[2]](arg[1]) | |
}, | |
, // 3 | |
, // 4 | |
, // 5 | |
, // 6 | |
function(arg) { // 7 | |
// hides arg, then returns arg. | |
// same as: | |
/* arg['style']['display'] = 'none'; return arg */ | |
arg[data[7]][data[6]] = data[8]; | |
return arg | |
}, | |
function(arg) { // 8 | |
// sets data[9] (onload) of vc7[..] (the <img>) to the passed argument | |
vc7834f3a25b010e8e4edbfba13943d98[data[9]] = arg | |
}, | |
function(arg) { // 9 | |
// sets data[10] (src) of vc7[..] (the <img>) to the passed argument | |
vc7834f3a25b010e8e4edbfba13943d98[data[10]] = arg | |
}, | |
// 10, gets evaluated as | |
/* | |
function(arg) { | |
return unescape(decodeURIComponent(window.atob(arg))) | |
} | |
*/ | |
// as you can see this is the decode function | |
new Function(data[11], data[12]), | |
function(arg) { // 11 | |
// Assigns a function that returns a decoded value from the storage | |
// array to v8e[..], and returns v8e[..]. | |
v8efd9c3630870f924b498b9e60b53675 = new Function( | |
// data[11] is the general argument name, vdf[..], remember. | |
data[11], | |
// decode (that's lib[10]) the string from within the storage list | |
// (that's v20[..]) picked by arg | |
lib[10](v2060faea334945e1d530c548660e8151[arg]) | |
); | |
return v8efd9c3630870f924b498b9e60b53675 | |
} | |
]; | |
v62c4c9ef94561dc30351b877b376b93f = [0, 255, 1]; | |
// This is just a storage array! | |
v2060faea334945e1d530c548660e8151 = [ | |
data[13], // 0 | |
data[14], // 1 | |
data[15], // 2 | |
data[16], // 3 | |
data[17], // 4 | |
data[18], // 5 | |
data[19], // 6 | |
data[20], // 7 | |
data[17], // 8 | |
data[21], // 9 | |
data[22], // 10 | |
data[23], // 11 | |
data[24], // 12 | |
data[25], // 13 | |
data[26] // 14 | |
]; | |
// takes the result of running storage[11] or data[23], which is the document | |
// (<html>) and assigns it to v9e[..]. | |
v9e070ab7ccfd61fff8dd382d7e02a2b0 = lib[11](11)(); | |
// function that takes argument vdf[..] and runs storage[10] or data[22] | |
// actually the same as v9e[..].getElementById(vdf[..]), remember that v9e[..] | |
// is actually the document/<html> element! | |
// TL;DR v2a[..] is document.getElementById | |
v2a6b8da18e813b836b7a4bd25b838107 = new Function(data[11], lib[10](v2060faea334945e1d530c548660e8151[10])); | |
// takes the result of running storage[13] or data[25], which is an <img> | |
// element, hides the <img>, and assigns the <img> to vc7[..] | |
vc7834f3a25b010e8e4edbfba13943d98 = lib[7](lib[11](13)()); | |
// set the onload of the <img> using lib[8] to do this code: | |
lib[8](function() { | |
// takes the result of running lib[1] (document.createElement) with the | |
// result of running storage[0] or data[13] ('canvas'), ie creates a | |
// <canvas> element and assigns to v17[..] | |
v1734c920f74b86f10c57800e3b4c69d0 = lib[1](lib[11](0)()); | |
// sets data[27] ('width') of v17[..] (the <canvas>) to data[27] of vc7[..] | |
// (the <img>), ie sets the <canvas> width to the <img> width | |
v1734c920f74b86f10c57800e3b4c69d0[data[27]] = vc7834f3a25b010e8e4edbfba13943d98[data[27]]; | |
// same as above but with data[28], ie 'height' | |
v1734c920f74b86f10c57800e3b4c69d0[data[28]] = vc7834f3a25b010e8e4edbfba13943d98[data[28]]; | |
// sets v8d[..] to storage[4] or data[17], which is an empty string | |
v8de318bf92f1e91a9ceef7dc499987d9 = v2060faea334945e1d530c548660e8151[4]; | |
// runs lib[2] with the v17[..] (the <canvas>) and the result of running | |
// storage[2] or data[15] ('2d') to result in getting a 2D context of | |
// canvas (literally v17[..].getContext('2d')) and stores this in v4a[..] | |
v4ab4aa9f1f7fd2c9f1005680f393ef52 = lib[2]([v1734c920f74b86f10c57800e3b4c69d0, lib[11](2)()]); | |
// creates a function that takes an argument vdf[..] (that's data[10]) and | |
// runs the decoded value of storage[14] or data[26], assigning a function | |
// that calls String.fromCharCode to vbc[..] | |
vbc7e070b51bbf801d0583ccbca7b8fe4 = new Function(data[11], lib[10](v2060faea334945e1d530c548660e8151[14])); | |
// runs data[29] ('drawImage') of v4a[..] (the canvas 2D context) with | |
// vc7[..] (the <img>), v62[..][0] (0), and v62[..][0] again (literally | |
// v4a[..].drawImage(vc7[..], 0, 0)) | |
v4ab4aa9f1f7fd2c9f1005680f393ef52[data[29]](vc7834f3a25b010e8e4edbfba13943d98, v62c4c9ef94561dc30351b877b376b93f[0], v62c4c9ef94561dc30351b877b376b93f[0]); | |
// runs data[30] ('getImageData') of v4a[..] (the canvas 2D context, again) | |
// with a bunch of arguments: | |
// * v62[..][0] (0) | |
// * v62[..][0] again | |
// * data[27] ('width') of v17[..] (the <canvas>) (ie canvas width) | |
// * and the same as above but with the height | |
// TL;DR gets image data of the <canvas> | |
v34b8f090cb414c065e63ecd587bac498 = v4ab4aa9f1f7fd2c9f1005680f393ef52[data[30]](v62c4c9ef94561dc30351b877b376b93f[0], v62c4c9ef94561dc30351b877b376b93f[0], v1734c920f74b86f10c57800e3b4c69d0[data[27]], v1734c920f74b86f10c57800e3b4c69d0[data[28]]); | |
// runs storage[12] or data[24] and stores the result in vfb[..] | |
// I'm going to copy and paste the code here to explain exactly what | |
// data[24] does: | |
/* | |
// this for loop does three things: | |
for ( | |
// at the start of the loop, set v4b[..] to v62[..][2] (1) | |
v4be7b6ee7554fb965b2460f341bd2701 = v62c4c9ef94561dc30351b877b376b93f[2]; | |
// keep looping while v4b[..] is less than the data length of v34[..] | |
// (the image data) | |
v4be7b6ee7554fb965b2460f341bd2701 < v34b8f090cb414c065e63ecd587bac498.data.length; | |
// each interval, increase v4b[..] by 4 | |
v4be7b6ee7554fb965b2460f341bd2701 += 4) | |
// remember how v8d[..] started as an empty string? now we're appending | |
// to it. what we append depends on.. | |
v8de318bf92f1e91a9ceef7dc499987d9 += ( | |
// if v34[..]'s data at v4b[..] is NOT v62[..][1] (255) | |
v34b8f090cb414c065e63ecd587bac498.data[v4be7b6ee7554fb965b2460f341bd2701] != | |
v62c4c9ef94561dc30351b877b376b93f[1] | |
// if they aren't the same, append the result of calling vbc[..] | |
// (String.fromCharCode) with the data at the current point in the | |
// loop | |
) ? vbc7e070b51bbf801d0583ccbca7b8fe4(v34b8f090cb414c065e63ecd587bac498.data[v4be7b6ee7554fb965b2460f341bd2701]) | |
// otherwise, append storage[4] or data[17] (an empty string, so | |
// don't append anything) | |
: v2060faea334945e1d530c548660e8151[4]; | |
// then finally trim any extra whitespace around the resulting string that | |
// is stored in v8d[..] | |
v8de318bf92f1e91a9ceef7dc499987d9 = v8de318bf92f1e91a9ceef7dc499987d9.trim(); | |
*/ | |
vfb4b0bca3c7a54043a9ff882402ca5b9 = lib[11](12)(); | |
// v8d[..] is now stored as the encoded code to alert the secret msesage, | |
// so we need to unencode it with lib[10] and then run a function created | |
// with that code | |
(new Function(lib[10](v8de318bf92f1e91a9ceef7dc499987d9)))(); | |
}); | |
// take the result of running storage[7] or data[20] (the PNG image data URI | |
// prefix), concatenate storage[9] or data[21] (the image source) to the end | |
// this triggers the loading script that causes the above function to be called | |
vfb4b0bca3c7a54043a9ff882402ca5b9 = lib[9](lib[11](7)() + v2060faea334945e1d530c548660e8151[9]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment