How to Use Frida RPC Forwarding to Bypass Mobile App Encryption with Python

This article demonstrates how to employ Frida's RPC forwarding to intercept and bypass encryption in a mobile app, providing step‑by‑step environment setup, hook scripts, and a FastAPI service that enables Python‑based crawling of protected API endpoints.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
How to Use Frida RPC Forwarding to Bypass Mobile App Encryption with Python

Frida RPC Algorithm Forwarding

Introduction

The article introduces a tool for crawling mobile app APIs using Frida RPC forwarding, which avoids the need to analyse complex Java and native code.

Why Use RPC Forwarding

Most Android apps are built with Java and native C++ libraries compiled to .so files, making reverse engineering difficult. By using RPC forwarding, you can call Java or native methods directly via Frida, retrieve encrypted data, and avoid deep analysis.

Environment

pixel2 v10 (rooted)
Magisk v23.0
Charles v4.6.2
Drony v1.3.154
Python v3.8.6
frida v14.2.18

RPC Forwarding Example

The target app is "嘟嘟牛". Using packet capture we find the login API endpoint http://api.dodovip.com/api/user/login. The request payload is encrypted with a field like Encrypt:xxxx.

Analysis

Decompiled the APK with jadx and searched for the keyword Encrypt. The encryption logic resides in the following class:

Hooking the relevant methods with Frida yields the script below:

Java.perform(function () {
    function printMap2(map) {
        return Java.cast(map, Java.use("java.util.HashMap"));
    }
    // hook encodeDesMap
    Java.use("com.dodonew.online.http.RequestUtil").encodeDesMap.overload('java.lang.String','java.lang.String','java.lang.String').implementation = function (data, desKey, desIV) {
        console.log("RequestUtil encodeDesMap is call");
        console.log("data:", data);
        console.log("desKey:", desKey);
        console.log("desIV:", desIV);
        let result = this.encodeDesMap(data, desKey, desIV);
        console.log("RequestUtil encodeDesMap result:", result);
        return result;
    };
    // hook paraMap
    Java.use("com.dodonew.online.http.RequestUtil").paraMap.overload('java.util.Map','java.lang.String','java.lang.String').implementation = function (addMap, append, sign) {
        console.log("RequestUtil paraMap is call");
        console.log("addMap:", addMap);
        console.log("addMap:", printMap2(addMap));
        console.log("append:", append);
        console.log("sign:", sign);
        let result = this.paraMap(addMap, append, sign);
        console.log("RequestUtil paraMap result:", result);
        return result;
    };
    // hook decodeDesJson
    Java.use("com.dodonew.online.http.RequestUtil").decodeDesJson.implementation = function (json, desKey, desIV) {
        console.log("RequestUtil decodeDesJson is call");
        console.log("json:", json);
        console.log("desKey:", desKey);
        console.log("desIV:", desIV);
        let result = this.decodeDesJson(json, desKey, desIV);
        console.log("RequestUtil decodeDesJson result:", result);
        return result;
    };
});

Organizing Calls

Based on the hooks, the active calls are:

// Request encryption
function callparaMap(username, userPwd, timeStamp) {
    let result = "";
    Java.perform(function () {
        let map = Java.use("java.util.HashMap").$new();
        map.put("timeStamp", timeStamp);
        map.put("loginImei", "Androidnull");
        map.put("equtype", "ANDROID");
        map.put("userPwd", userPwd);
        map.put("username", username);
        let r1 = Java.use("com.dodonew.online.http.RequestUtil").paraMap(map, "sdlkjsdljf0j2fsjk", "sign");
        result = Java.use("com.dodonew.online.http.RequestUtil").encodeDesMap(r1, "65102933", "32028092");
    });
    return result;
}

// Response decryption
function calldecodedesjson(data) {
    let result = "";
    Java.perform(function () {
        result = Java.use("com.dodonew.online.http.RequestUtil").decodeDesJson(data, "65102933", "32028092");
    });
    return result;
}

Building the Service

Combine the Frida script with a FastAPI server so that the crawler can request encryption/decryption via HTTP.

from fastapi import FastAPI
import uvicorn
import frida

jsCode = """
Java.perform(function () {
    // (the Frida script shown above)
});
"""

process = frida.get_usb_device().attach('com.dodonew.online')
script = process.create_script(jsCode)
script.load()

app = FastAPI()

@app.get("/getencrypt")
async def getencrypt(username: str, password: str, timestamp: str):
    result = script.exports.encrypt(username, password, timestamp)
    return {"data": result}

class Item(BaseModel):
    data: str

@app.post("/getdecode")
async def getdecode(item: Item):
    result = script.exports.decode(item.data)
    return {"data": result}

if __name__ == "__main__":
    uvicorn.run(app, port=8080)

Running the service produces the following output:

Constructing Requests

Use the service to obtain encrypted parameters, send them to the real API, then decrypt the response:

import requests, time, json

dt = int(time.time() * 1000)
enc = requests.get(f"http://127.0.0.1:8080/getencrypt?username=18903916120&password=1111×tamp={dt}").json()
payload = {"Encrypt": enc["data"]}
login_resp = requests.post("http://api.dodovip.com/api/user/login", headers={"Content-Type": "application/json;charset=utf-8"}, data=json.dumps(payload))
decoded = requests.post("http://127.0.0.1:8080/getdecode", headers={"Content-Type": "application/json;charset=utf-8"}, data=json.dumps({"data": login_resp.text})).text
print(decoded)

Conclusion

The app uses two layers of encryption, but with RPC forwarding only a few lines of code are needed to encrypt requests and decrypt responses. The main limitation is the dependency on a rooted device and a PC, which is acceptable for data‑collection tasks.

PythonRPCmobile securityFastAPIFrida
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.