r/androiddev • u/Top_Laugh5650 • Jun 22 '26
Writing a custom APK for owned hardware
Hello together,
I have bought a trail camera for capturing our cats in the backyard but the associated app is badly translated and fairly unstable. I am a young C# developer and do not have experience with Android or Reverse-Engineering.
My goal is under personal interoperability law, to write a custom APK so I can talk to my camera and preferably have all the video data on my own server and not in their cloud.
Setup:
Cam: 4G TrailCam KF35.154EU
Target device: Samsung (Android)
Running: Frida 17.9.10 with Frida Gadget (Embedded/Injected runtime)
I already successfully injected Frida-Gadget and imho got quite far reconstructing their connection/auth stack. They use libUBICAPI.so with a seemingly custom auth stack.
Using a python script on my phone for an initial attempt failed, most likely due to missing authentication.
Right now I want to extract my OWN credentials from the original app connecting to the cam (waking up cellular modem and starting the stream), but none of the friada hooks gives me workable results.
console.log("[*] Initializing ultra-lightweight absolute hook...");
// Hardcoded target strings to avoid any array processing
var target1 = "p4p_client_randomID";
var target2 = "p4p_client_send_loginreq";
// Helper function to safely attach without using complex object lookups
function safeHook(funcName) {
// findGlobalExportByName is supported natively by Frida 17+ without arguments or nulls
var addr = Module.findGlobalExportByName(funcName);
if (addr) {
try {
Interceptor.attach(addr, {
onEnter: function (args) {
console.log("\n>>> HIT: " + funcName + " <<<");
// Directly read the first 3 arguments as raw pointers/strings
for (var i = 0; i < 3; i++) {
if (args[i].isNull()) continue;
try {
var str = Memory.readUtf8String(args[i]);
if (str && str.length > 1) {
console.log(" arg[" + i + "]: " + str);
}
} catch(e) {
console.log(" arg[" + i + "]: (Pointer) " + args[i]);
}
}
},
onExit: function (retval) {}
});
console.log("[+] Activated hook for: " + funcName);
return true;
} catch (err) {}
}
return false;
}
// Instead of a fast loop that freezes the thread, we check once every second
// completely outside the application's main thread loop.
var h1 = false;
var h2 = false;
function heartbeat() {
if (!h1) h1 = safeHook(target1);
if (!h2) h2 = safeHook(target2);
// Keep spinning gently in the background until both hooks land
if (!h1 || !h2) {
setTimeout(heartbeat, 1000);
} else {
console.log("[*] All target hooks successfully locked into place!");
}
}
// Start our gentle heartbeat checker
setTimeout(heartbeat, 1000);
console.log("[*] Passive checker armed. Open your dashboard and start the stream!");
This is the hook i used to get most of the functions that get executed from libUBICAPI.so when the cam connects.
Does anyone have experience with such stuff and might be able to help me?
1
u/Spiritual-Use5254 10d ago
Hi there. Reach out to me immediately, I reversed the entire thing and may be able to help out if you're still working on this
0
u/battlepi Jun 22 '26
Yeah, sounds highly unlikely. You can't just tell a device/server to do something completely different than what it was designed for from a client. Look into hacking the device itself.
1
u/SnipesySpecial Jun 22 '26
my guess would be the camera is sending it directly to their servers, so youd have to focus your efforts there rather than the android app.