custom server, r1 support finally works

This commit is contained in:
Meowster 2024-08-14 18:46:00 +02:00
parent 62258ee387
commit 71e41094eb
4 changed files with 66 additions and 33 deletions

View file

@ -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`
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`

View file

@ -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("<application")) {
const lineIndex = file.indexOf(line);
// +2 because 0 makes it so that it's behind the <application> 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.rmdirSync(base, { force: true, recursive: true});
fs.rmSync(`${base}_out.apk`);
console.log(`Your patched apk filename is: ${decompName}_Patched.apk !`)

View file

@ -1,4 +1,5 @@
{
"apkFileName": "RabbitLauncher0517",
"imei": ""
"r1_mode": false,
"imei": "",
"server_ip": ""
}

View file

@ -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}`
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;
}
}
fs.writeFileSync(manifest, arr.join(" "), "utf-8")
});
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}
module.exports = { generateIMEI, decomp, modifyFunc, replaceLib, build, replaceStringInManifest }