109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
const VK_PATTERN = (new TextEncoder()).encode("vkDestroyInstance");
|
|
const YUZU_PATTERN = (new TextEncoder()).encode("yuzu Emulator");
|
|
|
|
addEventListener("load", () => {
|
|
const input = document.getElementById("input");
|
|
const button = document.getElementById("upload");
|
|
|
|
input.addEventListener("change", (e) => {
|
|
if (e.target.files.length) {
|
|
handleFile(e.target.files[0]);
|
|
}
|
|
});
|
|
|
|
button.addEventListener("click", () => input.click());
|
|
button.addEventListener("drop", (e) => {
|
|
e.preventDefault();
|
|
button.classList.remove("dragover");
|
|
if (e.dataTransfer.files.length) {
|
|
handleFile(e.dataTransfer.files[0]);
|
|
}
|
|
});
|
|
button.addEventListener("dragover", (e) => {
|
|
e.preventDefault();
|
|
button.classList.add("dragover");
|
|
});
|
|
button.addEventListener("dragleave", (e) => {
|
|
button.classList.remove("dragover");
|
|
});
|
|
});
|
|
|
|
/**
|
|
* @param {File} file
|
|
*/
|
|
function handleFile(file) {
|
|
const filename = file.name ?? "yuzu.exe";
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
const buff = e.target.result;
|
|
const view = new DataView(buff);
|
|
|
|
const patternLen = VK_PATTERN.byteLength;
|
|
const buffLen = buff.byteLength;
|
|
|
|
// Find the pattern
|
|
let foundIndex = -1;
|
|
for (let i = 0; i <= buffLen - patternLen; i++) {
|
|
let found = true;
|
|
for (let j = 0; j < patternLen; j++) {
|
|
if (view.getUint8(i + j) !== VK_PATTERN[j]) {
|
|
found = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found) {
|
|
foundIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (foundIndex == -1) {
|
|
console.error("Could not find pattern in file");
|
|
alert("Could not find pattern in file");
|
|
return;
|
|
}
|
|
|
|
// Walk backwards until we hit the start of the Emulator string
|
|
let startIndex = -1;
|
|
let emuLen = 0;
|
|
for (let i = foundIndex - 2;; i--) { // skip over first 0 byte right before current index
|
|
if (view.getUint8(i) == 0) {
|
|
startIndex = i + 1;
|
|
break;
|
|
}
|
|
emuLen++;
|
|
}
|
|
|
|
const yuzuLen = YUZU_PATTERN.byteLength;
|
|
if (emuLen < yuzuLen) {
|
|
console.error("Cannot patch emulator with smaller default name then yuzu");
|
|
alert("Cannot patch emulator with smaller default name then yuzu");
|
|
return;
|
|
}
|
|
|
|
if (emuLen == yuzuLen) {
|
|
let isYuzu = true;
|
|
for (let i = 0; i < emuLen; i++) {
|
|
if (view.getUint8(startIndex + i) != YUZU_PATTERN[i]) {
|
|
isYuzu = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (isYuzu) {
|
|
console.error("Either this is an already patched fork or its real yuzu");
|
|
alert("Either this is an already patched fork or its real yuzu");
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < emuLen; i++) {
|
|
view.setUint8(startIndex + i, YUZU_PATTERN[i] || 0);
|
|
}
|
|
|
|
const blobPatched = new Blob([buff]);
|
|
saveAs(blobPatched, filename.replace(".exe", "_patched.exe"));
|
|
}
|
|
reader.readAsArrayBuffer(file);
|
|
} |