TADpole-Online/public/js/custom/extraction.js
2018-04-01 20:47:17 +02:00

54 lines
1.8 KiB
JavaScript

function extractNormalKey(movableKeyY, keyXHex) {
let keyX = bigInt(keyXHex, 0x10);
let c = bigInt(constants.keys.c, 0x10);
let f128 = bigInt('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 0x10);
let keyY = bigInt(byteArrToHexStr(movableKeyY), 0x10);
let n = keyX.shiftLeft(2).or(keyX.shiftRight(128 - 2)).and(f128);
n = n.xor(keyY).add(c).and(f128);
n = n.shiftLeft(87).or(n.shiftRight(128 - 87)).and(f128);
let arr = n.toArray(256).value;
return (arr[0] === 0) ? arr.slice(1) : arr;
}
function extractDsiware(dsiware, normalKey) {
/* banner/header/footer extr & decrypt */
let locB = constants.dataLocations.dsiware.banner;
let locH = constants.dataLocations.dsiware.header;
let locF = constants.dataLocations.dsiware.footer;
let banner = dump(dsiware, normalKey, locB.off, locB.len);
let header = dump(dsiware, normalKey, locH.off, locH.len);
let footer = dump(dsiware, normalKey, locF.off, locF.len);
/* hash check */
if (!validateDsiwareComponents(banner, header, footer)) return;
/* content list extr & decrypt */
let buffer = sliceArr(header, 0x48, 0x2C).buffer;
let sizes = new Int32Array(buffer)
sizes.forEach((s, i) => { if (s === 0xB34) sizes[i] = 0xB40 });
let other = {};
let offset = constants.dataLocations.dsiware.other.off;
let otherNames = constants.dsiwareContent;
for (let i = 0; i < 11; i++) {
if (sizes[i] === 0) continue;
other[otherNames[i]] = dump(dsiware, normalKey, offset, sizes[i]);
offset += sizes[i] + 0x20;
}
return {
banner: banner,
header: header,
footer: footer,
other: other,
};
}
function dump(dsiware, normalKey, off, len) {
let encrypted = sliceArr(dsiware, off, len);
let iv = sliceArr(dsiware, off + len + 0x10, 0x10);
let aesCbc = new aesjs.ModeOfOperation.cbc(normalKey, iv);
let decryptedBytes = aesCbc.decrypt(encrypted);
return decryptedBytes;
}