r1-apk-patcher/index.js
2024-05-29 18:23:53 +02:00

251 lines
6.1 KiB
JavaScript

const fs = require("fs");
const { execSync } = require("child_process");
const { Litterbox } = require("node-catbox");
const litterbox = new Litterbox();
//CHANGE THESE
let decompName = "RabbitLauncher0517";
let uploadToLitterBox = false;
//CHANGE THESE ^^^^^^^^^^
let base = `${decompName}_decompile_xml`;
let imei = generateIMEI();
const getOSVersion = [
`.method private final getOSVersion()Ljava/lang/String;`,
`.locals 0`,
`.line 49`,
`const-string p0, "rabbit_OS_v0.8.86_20240523151103"`,
`return-object p0`,
`.end method`,
];
const getImei = [
`.method public final getImei(Landroid/content/Context;)Ljava/lang/String;`,
`.locals 0`,
`.line 49`,
`const-string p0, "${imei}"`,
`return-object p0`,
`.end method`,
];
const getDeviceId = [
`.method public final getDeviceId()Ljava/lang/String;`,
`.locals 0`,
`.line 34`,
`const-string p0, "${imei}"`,
`return-object p0`,
`.end method`,
];
const onKeyUp = [
".method public final onKeyUp(ILandroid/view/KeyEvent;)Z",
".locals 3",
"const/4 p0, -0x1",
"sput p0, Ltech/rabbit/r1launcher/rabbit/KeyEventHandler;->lastKey:I",
"sput p1, Ltech/rabbit/r1launcher/rabbit/KeyEventHandler;->lastUpKey:I",
"const/16 p0, 0x18",
"if-eq p1, p0, :setter",
"const/16 p0, 0x19",
"if-eq p1, p0, :setter",
"const/16 p0, 0x13",
"if-eq p1, p0, :cond_0",
"const/16 p0, 0x14",
"if-eq p1, p0, :cond_0",
"packed-switch p1, :pswitch_data_0",
"goto :goto_0",
":setter",
"const/16 p1, 0x1A",
":cond_0",
":pswitch_0",
];
const onKeyDown = [
".method public final onKeyDown(ILandroid/view/KeyEvent;)Z",
".locals 3",
"const/16 p0, 0x18",
"if-eq p1, p0, :setter",
"const/16 p0, 0x19",
"if-eq p1, p0, :setter",
"const/16 p0, 0x13",
"if-eq p1, p0, :cond_0",
"const/16 p0, 0x14",
"if-eq p1, p0, :cond_0",
"packed-switch p1, :pswitch_data_0",
"goto :goto_0",
":setter",
"const/16 p1, 0x1A",
":cond_0",
":pswitch_0",
];
decomp();
modifyFunc(
`.\\${base}\\smali\\classes\\tech\\rabbit\\r1launcher\\RLApp.smali`,
getOSVersion
);
modifyFunc(
`.\\${base}\\smali\\classes\\tech\\rabbit\\r1launcher\\settings\\utils\\SystemControllerUtil.smali`,
getImei
);
modifyFunc(`.\\${base}\\smali\\classes\\AppConfig.smali`, getDeviceId);
modifyFunc(
`.\\${base}\\smali\\classes\\tech\\rabbit\\r1launcher\\rabbit\\KeyEventHandler.smali`,
onKeyUp
);
modifyFunc(
`.\\${base}\\smali\\classes\\tech\\rabbit\\r1launcher\\rabbit\\KeyEventHandler.smali`,
onKeyDown
);
replaceLib(".\\libbase.so", "libbase.so")
build();
fs.renameSync(
`${base}_out-aligned-debugSigned.apk`,
`${decompName}_Patched.apk`
);
fs.rmdirSync(`.\\${base}`)
fs.rmSync(`${base}_out.apk`)
if (uploadToLitterBox) {
console.log("Uploading to LitterBox");
litterbox
.upload({
path: `${decompName}_Patched.apk`,
duration: "24h", // or omit to default to 1h
})
.then((response) =>
console.log("Output uploaded to LitterBox! Link: " + response)
);
}
function calculateChecksum(imeiWithoutChecksum) {
let imeiArray = imeiWithoutChecksum.split("").map(Number);
let sum = 0;
let double = false;
for (let i = 0; i < imeiArray.length; i++) {
let digit = imeiArray[i];
if (double) {
digit *= 2;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
double = !double;
}
let checksum = (10 - (sum % 10)) % 10;
return String(checksum);
}
function generateIMEI() {
const TAC = "35847631";
const serialNumberPrefix = "00";
let serialNumber = serialNumberPrefix;
for (let i = 0; i < 4; i++) {
serialNumber += Math.floor(Math.random() * 10);
}
let imeiWithoutChecksum = TAC + serialNumber;
let checksum = calculateChecksum(imeiWithoutChecksum);
let generatedIMEI = imeiWithoutChecksum + checksum;
return generatedIMEI;
}
function decomp() {
execSync(
`java -jar APKEditor.jar d -i ${decompName}.apk`,
(err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log("decompiled");
}
);
}
function modifyFunc(path, modifyWith) {
let start = -1; //so we know what part to modify
let end = -1;
try {
let data = fs.readFileSync(path, "utf8");
let lineArr = data.split("\n");
let iter = 0;
lineArr.forEach((element) => {
if (element.includes(modifyWith[0])) {
start = lineArr.indexOf(element);
//console.log("start ", start);
}
if (start > 0 && end < 0) {
if (element.includes(modifyWith[modifyWith.length - 1])) {
end = iter;
//console.log("end ", end);
for (let i = start; i <= end; i++) {
if (modifyWith[i - start] !== undefined)
lineArr[i] = modifyWith[i - start];
else lineArr[i] = "";
}
}
}
element.replace(" ", "\n");
iter++;
});
fs.writeFileSync(path, lineArr.join("\n"), "utf-8");
console.log("File modified successfully");
} catch (err) {
console.error("Error reading or writing file", err);
}
}
function replaceLib(newLibLocation, oldLib) {
fs.copyFileSync(newLibLocation, `.\\${base}\\root\\lib\\arm64-v8a\\${oldLib}`)
}
function build() {
execSync(`java -jar APKEditor.jar b -i ${base}`, (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(`stdout: ${stdout}`);
});
execSync(
`java -jar uber-apk-signer-1.2.1.jar -a ${decompName}_decompile_xml_out.apk`,
(err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(`stdout: ${stdout}`);
}
);
}