Bypassing X‑Wu App Signature with Frida RPC: A Step‑by‑Step Guide

This tutorial demonstrates how to capture and reproduce the dynamic newSign parameter of the X‑Wu Android app by reverse‑engineering the request‑signing method with Frida, exposing it via an RPC server, and then using the generated signature to call the official search API.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Bypassing X‑Wu App Signature with Frida RPC: A Step‑by‑Step Guide

Introduction

Hello, I am 码农星期八 . In this tutorial I will show how to obtain the newSign parameter required by the X‑Wu app’s search API by hooking the signing method with Frida and exposing it through an RPC interface.

Target App

x物4.74.5版本
链接:https://pan.baidu.com/s/1el0a48vsIl7XI-cDr7iynA 
提取码:tlvb

Environment

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

Capturing the Signature

By monitoring the network traffic of the app we identified that the newSign value changes each request and is required for a successful API call.

We decompiled the APK with JADX, searched for newSign, and found the method RequestUtils.c that generates it.

Hook Code

Java.perform(function () {
    function printMap2(map) {
        return Java.cast(map, Java.use("java.util.HashMap"));
    }
    Java.use("com.shizhuang.duapp.common.utils.RequestUtils").c.implementation = function (map, j2) {
        console.log("RequestUtils c is call");
        console.log("map:", map);
        console.log("map:", printMap2(map));
        console.log("j2:", j2);
        let result = this.c(map, j2);
        console.log("RequestUtils c result:", result);
        return result;
    }
});

Running this script confirms that the hooked method is indeed the one producing newSign.

Exposing the Method via RPC

from fastapi import FastAPI
import uvicorn
import frida

jsCode = """
    function newsign(arg_f,j2) {
        let result = "";
        Java.perform(function () {
            let map = Java.use("java.util.HashMap").$new();
            for (let key in arg_f) {
                map.put(key + "", arg_f[key] + "")
            }
            result = Java.use("com.shizhuang.duapp.common.utils.RequestUtils").c(map, j2)
        })
        return result;
    }
    rpc.exports = { newSign:newsign };
"""
process = frida.get_usb_device().attach('com.shizhuang.duapp')
script = process.create_script(jsCode)
print('[*] Running')
script.load()

from pydantic import BaseModel
app = FastAPI()

class Item(BaseModel):
    m: dict
    j2: int

@app.post("/getnewsign")
async def getencrypt(item: Item):
    result = script.exports.newsign(item.m, item.j2)
    return {"data": result}

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

Calling the Real API

import requests, time, json

timestamp = int(time.time() * 1000)
url = "https://app.dewu.com/api/v1/app/search/ice/search/list"
params = {
    "originSearch": "false",
    "catId": 0,
    "abTest": '[{"name":"search_equlheight_spu_strategy","value":"0"}]',
    "hideAddProduct": 0,
    "sortType": 0,
    "showHot": 1,
    "limit": 20,
    "productDetailVersionFlag": 1,
    "typeId": 0,
    "sortMode": 0,
    "page": 0,
    "title": "13苹果"
}
# encrypt newSign
data = {"m": params, "j2": timestamp}
r = requests.post("http://127.0.0.1:8080/getnewsign", data=json.dumps(data))
sign = r.json().get("data")
params["newSign"] = sign
headers = {
    "duuuid": "38a763c08fd35e88",
    "duplatform": "android",
    "appId": "duapp",
    "duchannel": "pp",
    "duv": "4.74.5",
    "dudeviceTrait": "Pixel+2",
    "dudeviceBrand": "google",
    "timestamp": f"{timestamp}",
    "User-Agent": "duapp/4.74.5(android;10)",
    "X-Auth-Token": "Bearer <TOKEN>"
}
resp = requests.get(url=url, headers=headers, params=params)
print(resp.url)
print(resp.text)

The request succeeds and returns the expected product list, confirming that the RPC‑exposed newSign works.

Conclusion

This short demonstration shows that using Frida to hook the signing method, exposing it via an RPC server, and then integrating the generated signature into normal HTTP requests provides a flexible way to bypass dynamic signature checks in mobile apps.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AndroidRPCAPIreverse engineeringFridasignature
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.