Skip to content

Instantly share code, notes, and snippets.

@towerofnix
Created March 23, 2016 02:17
Show Gist options
  • Save towerofnix/af2caa3bb82a59ab3f5e to your computer and use it in GitHub Desktop.
Save towerofnix/af2caa3bb82a59ab3f5e to your computer and use it in GitHub Desktop.
/* 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