现充|junyu33

Xposed, from beginner to quitter

After getting a new phone, after two days of disdainful efforts (and the stupidity tax of 50 yuan to unlock the bootloader?), I finally gained full control of my Huawei phone.

I haven't found any special use for it yet, I'll update the post when I have the ability in the future.

updated on 2024-8-17

I've had some free time lately, so I finally have time to update.

First and foremost, I feel like rooting can do much less than I expected. After all, this phone is running Android 7.0, which is already outdated.

Some of the following tasks can be done without rooting, but I'll also include the more hacky ones.

uninstall system apps (success)

First, using MyAndroidTools cannot uninstall normally (even if with root access). The reason is unknown.

The correct way is to get the package name, enter the shell with root privileges, and then enter the following command:

adb shell pm uninstall --user 0 <package_name>

By comparing the application lists before and after using MyAndroidTools, I confirmed that it permanently uninstalls the app, rather than just removing it for the current user, which often happens on newer versions of Android.

System RW (failed)

While I was at NUS, I stumbled upon the tool SystemRW (www.systemrw.com, don't click, it's down) while exploring Waydroid on an Ubuntu laptop. I used it to successfully make my Waydroid's system partition writable, which allowed me to enjoy network packet capture.

The tool's official website is now down, but the unzipped file is still sitting on my computer. So, I skillfully pushed it to my phone and ran it. Here's the result:

HWSTF:/data/local/tmp/sysrw_1.41 # ./sysrw

 ---------------------------------------------------
|  Welcome to the one and only original, universal  |
|===================================================|
|        SystemRW / SuperRW v1.41 featuring         |
|          MakeRW / ro2rw v1.1 by lebigmac          |
|===================================================|
|(read-only-2-read/write SUPER partition converter) |
|---------------------------------------------------|
|Also known as System-RW/Vendor-RW/Product-RW/Odm-RW|
|   FORCE-RW, TRUE-RW, EROFS-RW, F2FS-RW, EXT4-RW,  |
| THE REAL RW, FULL-RW, ERWFS, F2FS-2-RW-CONVERTER, |
|EROFS-2-RW-CONVERTER, Super Flasher/Resizer/Patcher|
| Root enhancer, Full Root, Real Root & more aliases|
|---------------------------------------------------|
|Inspiring a whole generation of talented developers|
|     and empowering the open source community.     |
|     The prophecy has finally been fullfilled!     |
|The Pandora's Box has been fully unlocked at last! |
|Let the Olympic System Modding Games (OASMG) begin!|
| The power is now in YOUR hands! And do not forget:|
|    With great power comes great responsibility!   |
|---------------------------------------------------|
|  CREDITS: @lebigmac @Brepro1 @Kolibass @Yuki1001  |
| Shoutouts: harpreet.s, frxhb, HemanthJabalpuri    |
|===================================================|
|    OFFICIAL HOMEPAGE @ http://www.systemrw.com    |
|===================================================|
|You can use this software for free for educational,|
| personal, non-commercial, legal purposes. To use  |
|this software for commercial purposes,please rent a|
| commercial usage license @ the official link above|
|---------------------------------------------------|
|   WARNING! NEVER TRUST THE SOFTWARE OF THIEVES!   |
|This project (or parts thereof) was stolen, hacked |
|    and/or abused by brigudav, leegarchat & co!    |
|dr-ketan steal my unique System-RW name from me :( |
|---------------------------------------------------|
|Always download original System-RW from link above!|
|---------------------------------------------------|
|You can learn from my code but please do not steal,|
| hack, crack or abuse it in any way! Thank you! <3 |
 ---------------------------------------------------
sysrw: Custom exclude detected: " odm product system_dlkm system_ext vendor vendor_dlkm "
sysrw: Backups enabled
sysrw: Initiating procedure...

sysrw: Device is in Android mode
sysrw: Current device: HUAWEI 
sysrw: Current device architecture: aarch64
sysrw: Please install Android 10 or newer and try again

The developer is still a bit chuunibyou, don't you think so?

Unfortunately, this tool only supports Android 10 and above. I previously tried to flash an Android 13 ROM in fastboot mode, but there were some issues with that ROM that prevented me from booting into the system. So this method is not feasible for the time being.

Trying replace magisk root method by kernelSU (failed)

Obviously, I think kernelSU is a more advanced root method. Maybe it can solve the problem of /system partition not being writable.

However:

KernelSU officially supports Android GKI 2.0 devices (kernel 5.10+). Older kernels (4.14+) are also compatible, but the kernel will have to be built manually.

HWSTF:/ # uname -a
Linux localhost 4.1.18-g7bd0d96 #1 SMP PREEMPT Fri Oct 12 10:15:13 CST 2018 aarch64

Apparently, my phone's kernel version is 4.1.18, so this method doesn't work either.

Trying to replace shizuku by sui (failed)

Shizuku said in its app that Sui would eventually replace Shizuku, so I tried installing Sui.

However, I tried various versions of Sui (Zygisk) from GitHub, but none of their installers worked on my phone. I suspect it was an issue with the Android version. So, I gave up.

Install Ubuntu (success)

Ideally, I'd install Ubuntu directly on my device, but according to misane, Ubuntu Touch supports very few phone models. Furthermore, the phone drivers are closed source and not necessarily in the Linux kernel, but likely in the Android HAL layer, making this difficult.

So I had to settle for the next best thing: installing Ubuntu on Termux. The latest version of Termux wouldn't install on my device; the only version I could find that works with Android 7.0 is 0.88.

Then, I set up Ubuntu on Termux following this tutorial, but its functionality isn't much stronger than Termux itself.

apt-get update
apt-get upgrade -y
apt-get install wget proot git -y
termux-setup-storage
git clone https://github.com/MFDGaming/ubuntu-in-termux.git
cd ubuntu-in-termux
chmod +x ubuntu.sh
./ubuntu.sh -y
# start
./startubuntu.sh

The mirror source from the tutorial is outdated, the correct mirror for Termux is deb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main

In addition, the installation does not take several hours (said in the tutorial), and with the proxy enabled, it only takes a minute at most.

BTW, typing commands on my phone is really painful, so I installed OpenSSH on it and operate from my computer.

Here, starting the SSHD service doesn't require the whole systemctl setup; just running sshd does the work.

Prevent killing the background process (success)

I asked ChatGPT and it recommended App Systemizer. I checked its GitHub page and found that the tool was last updated seven years ago and only supports Magisk v14 (my version is 27). GitHub doesn't provide an installation package, and Magisk currently doesn't support searching for modules either. So I had to go to XDA to find the latest compressed package (2019), drop it into Magisk, and it installed successfully.

As for installing an offline Magisk zip, here's a quick guide: Modules → Install from storage → select RE/MT file manager → choose the zip package. For usage instructions, refer to the YouTube video linked in the XDA thread.

Additionally, I can keep the screen always on to prevent the background process from being killed. However, for some unknown reason, the Sleep option in Settings is greyed out and cannot be changed. According to ChatGPT, you can modify the Android system settings database directly via ADB or root access to adjust the sleep timeout. The specific commands are as follows:

adb shell settings put system screen_off_timeout 2147483647

I tried it, and it really works. The setting is now set to "Never." With this, my old phone isn't far from becoming a Raspberry Pi.

hack system theme (success)

I really like the system theme on my old phone and want to transfer it to my current main device. I found out the theme's name is 再见时光 (Goodbye Time) from the theme store on my old phone, but when I searched for it on my main phone, it couldn't be found.

So I referred to this link and learned that Huawei theme packages have the .hwt extension. However, the path on my phone was different from the one in the video, so I decided to:

find / -name "*.hwt" 2>/dev/null

Part of the output is as follows:

./system/emui/china/themes/Droidsansfallback.hwt                                              
./system/emui/china/themes/FZLT.hwt                                                           
./system/emui/china/themes/FZLTH.hwt                                                          
./storage/emulated/0/HWThemes/.cache/Rhapsody.hwt                                             
./storage/emulated/0/HWThemes/.cache/Flow.hwt                                                 
./storage/emulated/0/HWThemes/.cache/Memento.hwt                                              
./storage/emulated/0/HWThemes/.cache/Serenade.hwt                                             
./storage/emulated/0/HWThemes/.cache/Symphony.hwt                                             
./storage/emulated/0/HWThemes/.cache/Waltz.hwt                                                
./storage/emulated/0/HWThemes/.cache/Droidsansfallback.hwt                                    
./storage/emulated/0/HWThemes/.cache/FZLT.hwt                                                 
./storage/emulated/0/HWThemes/.cache/FZLTH.hwt                                                
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/73E071837FEE1E3023D3BE4E1C725237.hwt
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/b7e06a7ad1d2468082d4bcf11f1d158f.hwt
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/20170322172846.62772498.hwt     
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/20170331163957.18140689.hwt     
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/628834ba702c488ebde3a43777795a7d.hwt
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/1FCE0D891DD45D68F7E67399E1499281.hwt
./storage/emulated/0/HWThemes/.cache/cover/onlinethemepreview/CF0193A7174829B27F8D8465E3231170.hwt
./storage/emulated/0/HWThemes/.cache/20170331163957.18140689.hwt                               
./storage/emulated/0/HWThemes/.cache/b7e06a7ad1d2468082d4bcf11f1d158f.hwt                     
./storage/emulated/0/HWThemes/.cache/628834ba702c488ebde3a43777795a7d.hwt                      
./storage/emulated/0/HWThemes/20170331163957.18140689.hwt                                     
./storage/emulated/0/HWThemes/b7e06a7ad1d2468082d4bcf11f1d158f.hwt                             
./storage/emulated/0/HWThemes/628834ba702c488ebde3a43777795a7d.hwt

So the theme's path is /storage/emulated/0/HWThemes. Then, check the .cache directory and run ls:

HWSTF:/storage/emulated/0/HWThemes/.cache # ls
20170331163957.18140689.hwt          Flow.hwt     Waltz.hwt                            
628834ba702c488ebde3a43777795a7d.hwt Memento.hwt  b7e06a7ad1d2468082d4bcf11f1d158f.hwt 
Droidsansfallback.hwt                Rhapsody.hwt cover                                
FZLT.hwt                             Serenade.hwt diycache                             
FZLTH.hwt                            Symphony.hwt themecache

Inside, each item is a folder, and each folder contains a file named description.xml. By looking at this file, you can find out the name of the theme.

HWSTF:/storage/emulated/0/HWThemes/.cache # cat b7e06a7ad1d2468082d4bcf11f1d158f.hwt/description.xml
<?xml version="1.0" encoding="UTF-8"?>

<HwTheme>
    <title>bye lyh</title>
    <title-cn>再见时光</title-cn>
    <author>云海</author>
    <designer>云海</designer>
    <screen>FHD</screen>
    <version>5.0.0</version>
    <font>Default</font>
    <font-cn>默认</font-cn>
    <briefinfo>【限时免费】需要壁纸的请加微信公众号:YHtheme 回复 壁纸下载 ,或加QQ100750086,备注华为主题锁屏是动态锁屏,会有花瓣树叶等飘落,已适配海量图标,拨号界面,联系人,短信列表等界面。
</briefinfo>
</HwTheme>




HWSTF:/storage/emulated/0/HWThemes/.cache # 

So we found that we should pull out the folder b7e06a7ad1d2468082d4bcf11f1d158f.hwt—that's already half the battle won.

Next, I needed to copy this .hwt file from the HWThemes directory to my main device. Naturally, the path would be different from the old phone. By now, the Huawei Theme Store had become the Honor Theme Store, so the corresponding path is /storage/emulated/0/Honor/Themes, which contains a folder called themecache. Therefore, it was fairly certain that placing the .hwt file in this path would work.

I followed the same procedure, opened the Honor Theme Store on my main device, and indeed, the theme appeared under "My Themes." I could even see the user comments for this theme.

Looks like Huawei and Honor haven't completely gone their separate ways yet.

Perhaps due to the different screen aspect ratio, the theme's lock screen on the main device had some minor issues, and the messaging interface couldn't display the background. But aside from that, it worked quite perfectly.

Greenify (success)

I found an older version of Greenify that works on Android 7 here. I enabled root access, but the Xposed mode in Work Mode couldn't be selected for some unknown reason.

For privacy reasons, I put all network-enabled apps to sleep except for NCalc+ and Termux. Other than that, I didn't make any further changes.

Exploring Frida (success)

First, I found magisk-frida on GitHub and installed the zip package via Xposed. Then, I set up the Frida client on my Ubuntu host with the following steps:

conda create -n frida python=3.11
conda activate frida
pip3 install frida frida-tools

Next, run:

adb forward tcp:27042 tcp:27042
frida-ps -U

This allows you to see the processes running on the phone.

  PID  Name
-----  ------------------------------------------
12346  Clash Meta for Android
 1575  Gboard
19507  Google Play 商店
  498  HwCamCfgSvr
  509  HwServiceHost
16389  Magisk
12938  MyAndroidTools
 1932  SIM 卡应用
18117  Via
12080  adbd
 2256  android.process.acore
12014  android.process.media
  552  audioserver
  485  bastetd
  500  cameraserver
  516  chargemonitor
 1570  com.android.bluetooth
19319  com.android.defcontainer
 2588  com.android.incallui
 2748  com.android.nfc
19294  com.android.packageinstaller
19231  com.android.providers.calendar
19681  com.android.vending:background
 6247  com.bidau.nkngl
18285  com.github.metacubex.clash.meta
 2523  com.google.android.ext.services
 2637  com.google.android.gms
 2292  com.google.android.gms.persistent
11716  com.google.android.gms.unstable
19209  com.google.android.webview:webview_service
11682  com.google.process.gapps
 1910  com.huawei.android.chr
 2190  com.huawei.android.instantshare
 2830  com.huawei.android.launcher
 6480  com.huawei.android.pushagent.PushService
 2652  com.huawei.bd
...

com.bidau.nkngl

There's a process called com.bidau.nkngl that seemed suspicious to me. Using MyAndroidTools on the phone, I found that the app's name is SystemStars, and the APK path is /system/app/MTExMSxodW/MTExMSxodWF3ZWktc3RmLWFsMDAsNjU1OTUsMQ==.apk. Decoding the Base64 gives 1111,hu/1111,huawei-stf-al00,65595,1, which didn't seem meaningful. So I decided to use Frida to inspect the app's behavior, focusing specifically on network-related activity:

First enumerate classes related to network activity:

Java.perform(function() {
    Java.enumerateLoadedClasses({
        onMatch: function(className) {
            if (className.includes("okhttp") || className.includes("http") || className.includes("network")) {
                console.log("Loaded class: " + className);
            }
        },
        onComplete: function() {
            console.log("Class enumeration complete.");
        }
    });
});

Here is the result:

Attaching...                                                                                                                                                                16:15:52 [120/187]
Loaded class: org.apache.http.HttpEntityEnclosingRequest
Loaded class: org.apache.http.ProtocolVersion
Loaded class: org.apache.http.HttpResponse
Loaded class: org.apache.http.impl.cookie.DateParseException
Loaded class: org.apache.http.message.AbstractHttpMessage
Loaded class: org.apache.http.HeaderIterator
Loaded class: org.apache.http.HttpHost
Loaded class: org.apache.http.params.AbstractHttpParams
Loaded class: org.apache.http.message.BasicHeader
Loaded class: org.apache.http.StatusLine
Loaded class: org.apache.http.client.methods.HttpUriRequest
Loaded class: org.apache.http.conn.ClientConnectionManager
Loaded class: org.apache.http.HttpEntity
Loaded class: org.apache.http.Header
Loaded class: org.apache.http.client.HttpClient
Loaded class: org.apache.http.NameValuePair
Loaded class: org.apache.http.message.BasicStatusLine
Loaded class: org.apache.http.message.BasicHttpResponse
Loaded class: org.apache.http.impl.cookie.DateUtils
Loaded class: org.apache.http.client.ResponseHandler
Loaded class: org.apache.http.client.methods.HttpEntityEnclosingRequestBase
Loaded class: org.apache.http.client.methods.AbortableHttpRequest
Loaded class: org.apache.http.client.methods.HttpRequestBase
Loaded class: org.apache.http.HttpVersion
Loaded class: org.apache.http.HttpRequest
Loaded class: org.apache.http.HttpMessage
Loaded class: org.apache.http.client.utils.URLEncodedUtils
Loaded class: org.apache.http.client.methods.HttpPost
Loaded class: org.apache.http.entity.BasicHttpEntity
Loaded class: org.apache.http.message.HeaderGroup
Loaded class: org.apache.http.params.BasicHttpParams
Loaded class: org.apache.http.protocol.HttpContext
Loaded class: org.apache.http.entity.AbstractHttpEntity
Loaded class: org.apache.http.params.HttpConnectionParams
Loaded class: org.apache.http.params.CoreConnectionPNames
Loaded class: org.apache.http.params.HttpParams
Loaded class: org.apache.http.conn.ConnectTimeoutException
Loaded class: com.android.okhttp.internal.http.HttpTransport
Loaded class: com.android.okhttp.Headers
Loaded class: com.android.okhttp.internal.tls.OkHostnameVerifier
Loaded class: com.android.okhttp.internal.http.RequestException
Loaded class: com.android.okhttp.internal.huc.HttpsURLConnectionImpl
Loaded class: com.android.okhttp.Connection
Loaded class: com.android.okhttp.ConnectionSpec
Loaded class: com.android.okhttp.internal.http.CacheStrategy
Loaded class: com.android.okhttp.internal.http.HttpMethod
Loaded class: com.android.okhttp.internal.huc.HttpURLConnectionImpl
Loaded class: com.android.okhttp.internal.OptionalMethod
Loaded class: com.android.okhttp.ConnectionPool$1
Loaded class: com.android.okhttp.internal.Util
Loaded class: com.android.okhttp.OkHttpClient$1
Loaded class: com.android.okhttp.internal.Network$1
Loaded class: com.android.okhttp.internal.http.HttpConnection$ChunkedSource
Loaded class: com.android.okhttp.RequestBody
Loaded class: com.android.okhttp.Headers$Builder
Loaded class: com.android.okhttp.CacheControl$Builder
Loaded class: com.android.okhttp.HttpUrl
Loaded class: com.android.okhttp.HttpHandler$CleartextURLFilter
Loaded class: com.android.okhttp.internal.http.OkHeaders$1
Loaded class: com.android.okhttp.okio.AsyncTimeout$1
Loaded class: com.android.okhttp.CertificatePinner$Builder
Loaded class: com.android.okhttp.Route
Loaded class: com.android.okhttp.Handshake
Loaded class: com.android.okhttp.okio.AsyncTimeout$2
Loaded class: com.android.okhttp.okio.BufferedSink
Loaded class: com.android.okhttp.internal.http.RouteException
Loaded class: com.android.okhttp.internal.http.Transport
Loaded class: com.android.okhttp.okio.RealBufferedSink$1
Loaded class: com.android.okhttp.Dispatcher
Loaded class: com.android.okhttp.okio.RealBufferedSink
Loaded class: com.android.okhttp.internal.http.OkHeaders
Loaded class: com.android.okhttp.internal.http.HttpEngine
Loaded class: com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
Loaded class: com.android.okhttp.internal.Util$1
Loaded class: com.android.okhttp.Request
Loaded class: com.android.okhttp.okio.Source
Loaded class: com.android.okhttp.okio.RealBufferedSource$1
Loaded class: com.android.okhttp.TlsVersion
Loaded class: com.android.okhttp.HttpUrl$Builder$ParseResult
Loaded class: com.android.okhttp.OkUrlFactory
Loaded class: com.android.okhttp.okio.Timeout$1
Loaded class: com.android.okhttp.okio.ForwardingTimeout
Loaded class: com.android.okhttp.internal.Network
Loaded class: com.android.okhttp.internal.http.StatusLine
Loaded class: com.android.okhttp.internal.Internal
Loaded class: com.android.okhttp.internal.ConnectionSpecSelector
Loaded class: com.android.okhttp.CipherSuite
Loaded class: com.android.okhttp.HttpHandler
Loaded class: com.android.okhttp.ConnectionSpec$Builder
Loaded class: com.android.okhttp.Address
Loaded class: com.android.okhttp.ConfigAwareConnectionPool$1
Loaded class: com.android.okhttp.internal.http.HttpConnection$AbstractSource
Loaded class: com.android.okhttp.ConfigAwareConnectionPool
Loaded class: com.android.okhttp.okio.Timeout
Loaded class: com.android.okhttp.ConnectionPool
Loaded class: com.android.okhttp.okio.RealBufferedSource
Loaded class: com.android.okhttp.okio.SegmentPool
Loaded class: com.android.okhttp.okio.BufferedSource
Loaded class: com.android.okhttp.okio.Okio
Loaded class: com.android.okhttp.okio.Okio$1
Loaded class: com.android.okhttp.Response$Builder
Loaded class: com.android.okhttp.internal.http.RequestLine
Loaded class: com.android.okhttp.internal.http.RouteSelector
Loaded class: com.android.okhttp.okio.Okio$2
Loaded class: com.android.okhttp.ResponseBody
Loaded class: com.android.okhttp.okio.Okio$3
Loaded class: com.android.okhttp.Authenticator
Loaded class: com.android.okhttp.Response
Loaded class: com.android.okhttp.internal.http.RetryableSink
Loaded class: com.android.okhttp.HttpsHandler
Loaded class: com.android.okhttp.Protocol
Loaded class: com.android.okhttp.okio.Segment
Loaded class: com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
Loaded class: com.android.okhttp.okio.Util
Loaded class: com.android.okhttp.okio.AsyncTimeout
Loaded class: com.android.okhttp.RequestBody$2
Loaded class: com.android.okhttp.okio.Sink
Loaded class: com.android.okhttp.internal.http.CacheStrategy$Factory
Loaded class: com.android.okhttp.CertificatePinner
Loaded class: com.android.okhttp.internal.RouteDatabase
Loaded class: com.android.okhttp.internal.http.HttpEngine$1
Loaded class: com.android.okhttp.HttpUrl$Builder
Loaded class: com.android.okhttp.internal.http.RealResponseBody
Loaded class: com.android.okhttp.internal.URLFilter
Loaded class: com.android.okhttp.internal.http.HttpConnection
Loaded class: com.android.okhttp.okio.AsyncTimeout$Watchdog
Loaded class: com.android.okhttp.internal.Platform
Loaded class: com.android.okhttp.CacheControl
Loaded class: com.android.okhttp.Request$Builder
Loaded class: com.android.okhttp.OkHttpClient
Loaded class: com.android.okhttp.internal.http.AuthenticatorAdapter
Loaded class: com.android.okhttp.okio.Buffer
Loaded class: [Lcom.android.okhttp.HttpUrl$Builder$ParseResult;
Loaded class: [Lorg.apache.http.Header;
Loaded class: [Lcom.android.okhttp.Protocol;
Loaded class: [Lcom.android.okhttp.ConnectionSpec;
Loaded class: [Lcom.android.okhttp.TlsVersion;
Loaded class: [Lcom.android.okhttp.CipherSuite;
Class enumeration complete.

It can be seen that it uses the org.apache.http and com.android.okhttp libraries. Therefore, we can write hook code—for example, using OkHttp's Request and Response:

Java.perform(function() {
    var OkHttpRequestBuilder = Java.use('com.android.okhttp.Request$Builder');

    OkHttpRequestBuilder.build.implementation = function() {
        var request = this.build();
        var url = request.url().toString();
        console.log("[OkHttp] Request URL: " + url);

        // Print headers
        var headers = request.headers();
        for (var i = 0; i < headers.size(); i++) {
            console.log("[OkHttp] Header: " + headers.name(i) + ": " + headers.value(i));
        }

        return request;
    };

    var OkHttpClient = Java.use('com.android.okhttp.OkHttpClient');
    OkHttpClient.newCall.overload('com.android.okhttp.Request').implementation = function(request) {
        console.log("[OkHttp] Making request to: " + request.url().toString());
        return this.newCall(request);
    };
});

Then run:

frida -U -n com.bidau.nkngl -l monitor_network.js

Then I found an error: frida-server wasn't running. So I had to download the corresponding version of frida-server from GitHub, push it to the phone, and then start the server.

HWSTF:/data/local/tmp # ./frida-server-16.4.8-android-arm64 
unable to stat file for the executable "/memfd:frida-helper-32 (deleted)": No such file or directory
^CHWSTF:/data/local/tmp # 

This time, running the script again, it ran for a while but produced no output:

> frida -U -n com.bidau.nkngl -l monitor_network.js

     ____
    / _  |   Frida 16.4.8 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to STF AL10 (id=xxx)
                                                                                
[STF AL10::com.bidau.nkngl ]->

So I opted for faster static analysis, using jadx-gui to open the APK file. Based on the practical training experience from June this year, most of the business logic in the Java code is usually in the service class. I opened com.nantu.nengl.service.MyLocalService and found the following code:

    public boolean a(List<com.nantu.nengl.a.b> list) {
        if (list == null || list.size() == 0) {
            return true;
        }
        JSONObject jSONObject = new JSONObject();
        try {
            jSONObject.put("action", "openAppLogFromShuaji");
            JSONObject jSONObject2 = new JSONObject();
            jSONObject2.put("imei", com.nantu.nengl.c.d.a(this));
            jSONObject2.put("appverCode", f.a().a(this));
            jSONObject2.put("channelid", f.f45a);
            jSONObject2.put("imsi", com.nantu.nengl.c.d.b(this));
            jSONObject2.put("androidver", Build.VERSION.SDK_INT);
            JSONArray jSONArray = new JSONArray();
            for (int i = 0; i < list.size(); i++) {
                com.nantu.nengl.a.b bVar = list.get(i);
                if (bVar != null) {
                    JSONObject jSONObject3 = new JSONObject();
                    jSONObject3.put("p", bVar.b());
                    jSONObject3.put("m", bVar.c());
                    jSONObject3.put("nf", bVar.d());
                    jSONObject3.put("o", bVar.a());
                    jSONArray.put(jSONObject3);
                }
            }
            jSONObject2.put("applist", jSONArray);
            b.b("sendActiveApp l = " + jSONArray.toString());
            jSONObject.put("data", com.nantu.nengl.c.a.a(jSONObject2.toString(), "SJ@WWW.7TU.CN_AM"));
            return com.nantu.nengl.c.c.a(jSONObject.toString());
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e2) {
            e2.printStackTrace();
            return false;
        }
    }

It turns out this was an app I had previously installed on the phone called 奇兔刷机. The app is still sitting in my recovery partition, so it seems there's probably no issue.

com.android.vending

But I still needed something to demonstrate Frida's capabilities, so I chose the Play Store, with the package name com.android.vending, keeping the hook script the same.

However, this time running it resulted in an error:

> frida -U -n com.android.vending -l monitor_network.js

     ____
    / _  |   Frida 16.4.8 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to STF AL10 (id=xxx)
Failed to spawn: unable to find process with name 'com.android.vending'

This problem isn't actually hard to solve. You can simply get the Play Store's PID and use it for hooking. After refreshing the Play Store a few times, you'll see the results:

> frida -U -p 19507 -l monitor_network.js

     ____
    / _  |   Frida 16.4.8 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to STF AL10 (id=xxx)

[STF AL10::PID::19507 ]-> [OkHttp] Header: Host: play.googleapis.com                                          
[OkHttp] Header: Connection: Keep-Alive                                                        
[OkHttp] Header: Accept-Encoding: gzip                                                               
[OkHttp] Header: Content-Length: 7913                                       
[OkHttp] Request URL: https://play.googleapis.com/play/log?format=raw&proto_v2=true             
[OkHttp] Header: Content-Encoding: gzip                                                             
[OkHttp] Header: Content-Type: application/x-gzip                                                    
[OkHttp] Header: User-Agent: Android-Finsky/42.2.27-23%20%5B0%5D%20%5BPR%5D%20660620715                                 
[OkHttp] Header: Authorization: Bearer ya29.m.CpYCAdJUhWdHMq07ko1_QNsNqX0-6Z-sSqLuep-11xDbDzGwmbv40T_07xA6gzicGOdtIRL6BdTI5JroLxax1-PsRCElhVFFthKPXEmG2AR12LAVPlHI8JmLjVh5mxng7oEE2qQroDGusu5RruzqkIFOQu06qFBCr......................................................................................................................................................0SWQyTtdD0blEqv--9e6-yV3gR6vGOXROTIRWhCCdS2LF7phuO84eAXRjx6kkM-YSDwgBEgcKAQQQjeoEGMHNBBogVmnWzORig8HgDXTx0_LY_IwnqMpxpyfFd9kGW0AYE_IiAggBKithQ2dZS0FTQVNBUk1TRlFIR1gyTWlaT25kXzQ0anJwSjZHaklHMUxtSFBB
...

And that's a wrap! 🎉

updated on 2025-7-28

Nearly a year later, my old phone finally came in handy when I tried to capture traffic from an app—though it didn't actually solve the problem I was facing. For details, see this link.