diff --git a/README.md b/README.md index dc85eda..62e21f1 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ # r1-apk-patcher tool to patch a clean rabbit apk into a working one -To use this repo you need to download [nodeJS](https://nodejs.org/en/download/package-manager/current) and java. \ -If anyone wants to make a fix for vision mode not working for many people, DM me on Discord, @meowstercatel (smali / java knowledge recommended ofc) how to run: -1. download nodejs [here](https://nodejs.org/en/download/package-manager/current) -2. if you have your own apk that you want to patch, change it in settings.json -4. finally run `node index.js` -5. your patched apk will have the original filename and "_Patched" added to it. - -to run the apk you need to execute this command first (adb): `adb shell pm grant tech.rabbit.r1launcher.r1 android.permission.WRITE_SECURE_SETTINGS` -or in termux `pm grant tech.rabbit.r1launcher.r1 android.permission.WRITE_SECURE_SETTINGS` \ No newline at end of file +1. download nodeJS [here](https://nodejs.org/en/download/package-manager/current), and Java. +2. changing the settings +2.1 if you want to use the patched app with your r1, set "r1_mode" to true. +2.2 if you have your own r1 IMEI that you'd want to use, put it in the imei value. +2.3 if you have your own rabbit backend set up, you can set the URL of it in the server_ip value. Example value: `ws://192.168.0.110:3000` +3. finally run `node index.js` +4. your patched apk will have the original filename and "_Patched" added to it. +5. run a command to grant the r1 app the secure settings permission +5.1. adb command: `adb shell pm grant tech.rabbit.r1launcher.r1 android.permission.WRITE_SECURE_SETTINGS` +5.2 termux: (needs root in order to work): `pm grant tech.rabbit.r1launcher.r1 android.permission.WRITE_SECURE_SETTINGS` \ No newline at end of file diff --git a/index.js b/index.js index 7226576..27c28a9 100644 --- a/index.js +++ b/index.js @@ -3,18 +3,44 @@ const {functions} = require("./functions"); const {decomp, modifyFunc, replaceLib, build, replaceStringInManifest} = require("./utils"); const settings = require("./settings.json"); -const decompName = settings.apkFileName; +const decompName = "RabbitLauncher0517"; const base = `${decompName}_decompile_xml`; const appVersion = "20240615.10-dirty"; decomp(); +if(settings.server_ip !== "") { + functions.functions.push({ + location: "smali/classes/tech/rabbit/r1launcher/RLApp.smali", + code: [ + "sget-object v0, Ltech/rabbit/r1launcher/wss/WebSocketManager;->INSTANCE:Ltech/rabbit/r1launcher/wss/WebSocketManager;", + `const-string v2, "${settings.serverIP}"`, + "invoke-virtual {v0, v2}, Ltech/rabbit/r1launcher/wss/WebSocketManager;->setRabbitServiceUrl(Ljava/lang/String;)V" + ] + }) + let file = fs.readFileSync(`./${base}/AndroidManifest.xml`).toString(); + file = file.split("\n"); + file.forEach(line => { + if(line.includes(" tag + file.splice(lineIndex+2, 0, `android:usesCleartextTraffic="true"`); + } + }) + fs.writeFileSync(`./${base}/AndroidManifest.xml`, file.join("\n")); +} + +if(settings.r1_mode === true) { + functions.functions[3].code[5] = "const/16 p0, 0x50" + functions.functions[4].code[2] = "const/16 p0, 0x50" +} + functions.functions.forEach(func => { modifyFunc(`./${base}/`+func.location, func.code) }) -replaceStringInManifest("android:versionName", `"${appVersion}"`) +replaceStringInManifest("android:versionName", `${appVersion}`) replaceLib("./libbase.so", "libbase.so"); if(fs.existsSync(`./${decompName}_out.apk`)) fs.rmSync(`./${decompName}_out.apk`); @@ -27,5 +53,7 @@ fs.renameSync( `${decompName}_Patched.apk` ); -fs.rmSync(`./${base}`, { recursive: true, force: true }); -fs.rmSync(`${base}_out.apk`); \ No newline at end of file +fs.rmdirSync(base, { force: true, recursive: true}); +fs.rmSync(`${base}_out.apk`); + +console.log(`Your patched apk filename is: ${decompName}_Patched.apk !`) \ No newline at end of file diff --git a/settings.json b/settings.json index a5e0ab4..0346bde 100644 --- a/settings.json +++ b/settings.json @@ -1,4 +1,5 @@ { - "apkFileName": "RabbitLauncher0517", - "imei": "" + "r1_mode": false, + "imei": "", + "server_ip": "" } \ No newline at end of file diff --git a/utils.js b/utils.js index ecf5e1b..17a5b5b 100644 --- a/utils.js +++ b/utils.js @@ -1,7 +1,7 @@ const { execSync } = require("child_process"); const fs = require("fs"); -const settings = require("./settings.json"); -const decompName = settings.apkFileName; +const decompName = "RabbitLauncher0517"; +const base = `${decompName}_decompile_xml`; //these next 2 functions are taken from //https://annabelsandford.github.io/rabbit-r1-imeigen/imei_check_v1.html @@ -87,31 +87,34 @@ function modifyFunc(path, modifyWith) { function replaceLib(newLibLocation, oldLib) { fs.copyFileSync( newLibLocation, - `./${decompName}_decompile_xml/root/lib/arm64-v8a/${oldLib}` + `./${base}/root/lib/arm64-v8a/${oldLib}` ); } function replaceStringInManifest(name, value) { - //replaces every instance of the "name" keyword - const manifest = `./${decompName}_decompile_xml/AndroidManifest.xml`; - const data = fs.readFileSync(manifest, "utf-8") - let arr = data.split(" "); - for (let i = 0; i < arr.length; i++) { - let line = arr[i]; - if(line.includes(name)) { - line = `${name}=${value}` - } - } - fs.writeFileSync(manifest, arr.join(" "), "utf-8") - + const file = fs.readFileSync(`${base}/AndroidManifest.xml`); + let content = file.toString() + content = content.split("\n"); + content.forEach((line) => { + const lineIndex = content.indexOf(line); + if (line.includes(name)) { + console.log(line) + line = line.split(`"`); + line[1] = value; + line = line.join(`"`); + content[lineIndex] = line; + } + }); + content = content.join("\n"); + fs.writeFileSync(`${base}/AndroidManifest.xml`, content); } function build() { - execSync(`java -jar APKEditor.jar b -i ${decompName}_decompile_xml`); + execSync(`java -jar APKEditor.jar b -i ${base}`); execSync( - `java -jar uber-apk-signer-1.2.1.jar -a ${decompName}_decompile_xml_out.apk` + `java -jar uber-apk-signer-1.2.1.jar -a ${base}_out.apk` ); } -module.exports = {generateIMEI, decomp, modifyFunc, replaceLib, build, replaceStringInManifest} \ No newline at end of file +module.exports = { generateIMEI, decomp, modifyFunc, replaceLib, build, replaceStringInManifest } \ No newline at end of file