mirror of
https://github.com/meowstercatel/r1-apk-patcher.git
synced 2024-12-22 23:25:20 -06:00
custom server, r1 support finally works
This commit is contained in:
parent
62258ee387
commit
71e41094eb
4 changed files with 66 additions and 33 deletions
19
README.md
19
README.md
|
@ -1,13 +1,14 @@
|
||||||
# r1-apk-patcher
|
# r1-apk-patcher
|
||||||
tool to patch a clean rabbit apk into a working one
|
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:
|
how to run:
|
||||||
1. download nodejs [here](https://nodejs.org/en/download/package-manager/current)
|
1. download nodeJS [here](https://nodejs.org/en/download/package-manager/current), and Java.
|
||||||
2. if you have your own apk that you want to patch, change it in settings.json
|
2. changing the settings
|
||||||
4. finally run `node index.js`
|
2.1 if you want to use the patched app with your r1, set "r1_mode" to true.
|
||||||
5. your patched apk will have the original filename and "_Patched" added to it.
|
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`
|
||||||
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`
|
3. finally run `node index.js`
|
||||||
or in termux `pm grant tech.rabbit.r1launcher.r1 android.permission.WRITE_SECURE_SETTINGS`
|
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`
|
34
index.js
34
index.js
|
@ -3,18 +3,44 @@ const {functions} = require("./functions");
|
||||||
const {decomp, modifyFunc, replaceLib, build, replaceStringInManifest} = require("./utils");
|
const {decomp, modifyFunc, replaceLib, build, replaceStringInManifest} = require("./utils");
|
||||||
const settings = require("./settings.json");
|
const settings = require("./settings.json");
|
||||||
|
|
||||||
const decompName = settings.apkFileName;
|
const decompName = "RabbitLauncher0517";
|
||||||
const base = `${decompName}_decompile_xml`;
|
const base = `${decompName}_decompile_xml`;
|
||||||
|
|
||||||
const appVersion = "20240615.10-dirty";
|
const appVersion = "20240615.10-dirty";
|
||||||
|
|
||||||
decomp();
|
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 => {
|
functions.functions.forEach(func => {
|
||||||
modifyFunc(`./${base}/`+func.location, func.code)
|
modifyFunc(`./${base}/`+func.location, func.code)
|
||||||
})
|
})
|
||||||
|
|
||||||
replaceStringInManifest("android:versionName", `"${appVersion}"`)
|
replaceStringInManifest("android:versionName", `${appVersion}`)
|
||||||
replaceLib("./libbase.so", "libbase.so");
|
replaceLib("./libbase.so", "libbase.so");
|
||||||
|
|
||||||
if(fs.existsSync(`./${decompName}_out.apk`)) fs.rmSync(`./${decompName}_out.apk`);
|
if(fs.existsSync(`./${decompName}_out.apk`)) fs.rmSync(`./${decompName}_out.apk`);
|
||||||
|
@ -27,5 +53,7 @@ fs.renameSync(
|
||||||
`${decompName}_Patched.apk`
|
`${decompName}_Patched.apk`
|
||||||
);
|
);
|
||||||
|
|
||||||
fs.rmSync(`./${base}`, { recursive: true, force: true });
|
fs.rmdirSync(base, { force: true, recursive: true});
|
||||||
fs.rmSync(`${base}_out.apk`);
|
fs.rmSync(`${base}_out.apk`);
|
||||||
|
|
||||||
|
console.log(`Your patched apk filename is: ${decompName}_Patched.apk !`)
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
"apkFileName": "RabbitLauncher0517",
|
"r1_mode": false,
|
||||||
"imei": ""
|
"imei": "",
|
||||||
|
"server_ip": ""
|
||||||
}
|
}
|
33
utils.js
33
utils.js
|
@ -1,7 +1,7 @@
|
||||||
const { execSync } = require("child_process");
|
const { execSync } = require("child_process");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const settings = require("./settings.json");
|
const decompName = "RabbitLauncher0517";
|
||||||
const decompName = settings.apkFileName;
|
const base = `${decompName}_decompile_xml`;
|
||||||
|
|
||||||
//these next 2 functions are taken from
|
//these next 2 functions are taken from
|
||||||
//https://annabelsandford.github.io/rabbit-r1-imeigen/imei_check_v1.html
|
//https://annabelsandford.github.io/rabbit-r1-imeigen/imei_check_v1.html
|
||||||
|
@ -87,30 +87,33 @@ function modifyFunc(path, modifyWith) {
|
||||||
function replaceLib(newLibLocation, oldLib) {
|
function replaceLib(newLibLocation, oldLib) {
|
||||||
fs.copyFileSync(
|
fs.copyFileSync(
|
||||||
newLibLocation,
|
newLibLocation,
|
||||||
`./${decompName}_decompile_xml/root/lib/arm64-v8a/${oldLib}`
|
`./${base}/root/lib/arm64-v8a/${oldLib}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceStringInManifest(name, value) {
|
function replaceStringInManifest(name, value) {
|
||||||
//replaces every instance of the "name" keyword
|
const file = fs.readFileSync(`${base}/AndroidManifest.xml`);
|
||||||
const manifest = `./${decompName}_decompile_xml/AndroidManifest.xml`;
|
let content = file.toString()
|
||||||
const data = fs.readFileSync(manifest, "utf-8")
|
content = content.split("\n");
|
||||||
let arr = data.split(" ");
|
content.forEach((line) => {
|
||||||
for (let i = 0; i < arr.length; i++) {
|
const lineIndex = content.indexOf(line);
|
||||||
let line = arr[i];
|
|
||||||
if (line.includes(name)) {
|
if (line.includes(name)) {
|
||||||
line = `${name}=${value}`
|
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() {
|
function build() {
|
||||||
execSync(`java -jar APKEditor.jar b -i ${decompName}_decompile_xml`);
|
execSync(`java -jar APKEditor.jar b -i ${base}`);
|
||||||
|
|
||||||
execSync(
|
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`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue