Skip to content

APK Decompilation Guide

piekstra edited this page Feb 7, 2026 · 1 revision

APK Decompilation Guide

This guide documents how the Kasa Android APK was decompiled to reverse-engineer the V2 API. Use this process when TP-Link releases app updates that may change the API.

Prerequisites

Tools

  • adb (Android Debug Bridge) - for pulling the APK from a device
  • jadx (Dex to Java decompiler) - for decompiling the APK to readable Java

Install on macOS

brew install android-platform-tools  # adb
brew install jadx                     # jadx

Android Device Setup

  1. Enable Developer Options: Settings > About Phone > tap Build Number 7 times
  2. Enable USB Debugging: Settings > Developer Options > USB Debugging
  3. Connect phone via USB and authorize the computer when prompted

Step 1: Find and Pull the APK

# List packages to find Kasa
adb shell pm list packages | grep -i kasa
# Output: package:com.tplink.kasa_android

# Get the APK path
adb shell pm path com.tplink.kasa_android
# Output: package:/data/app/~~HASH~~/com.tplink.kasa_android-HASH==/base.apk

# Pull the APK
adb pull /data/app/~~HASH~~/com.tplink.kasa_android-HASH==/base.apk kasa.apk

# Check the version
adb shell dumpsys package com.tplink.kasa_android | grep versionName
# Output: versionName=3.4.451

Step 2: Decompile with jadx

jadx --deobfuscation-min-length 3 \
     --deobfuscation-max-length 64 \
     --output-dir kasa-decompiled \
     kasa.apk

This produces:

  • kasa-decompiled/sources/ - Decompiled Java source code
  • kasa-decompiled/resources/ - Assets, layouts, configs

The decompilation takes several minutes and produces ~1GB of output.

Key Files to Examine

Configuration

File Contains
resources/assets/services_config.json cloudUrl, appType defaults
resources/assets/sdkconfig.xml AccessKey, SecretKey, device type lists

Authentication

File Contains
sources/com/tplink/cloud/api/AccountV2Api.java All V2 account API endpoints (Retrofit interface)
sources/com/tplink/cloud/bean/account/params/LoginV2Params.java Login request fields
sources/com/tplink/cloud/bean/account/result/LoginV2Result.java Login response fields (token, MFA, etc.)
sources/com/tplink/cloud/bean/account/params/CheckMFACodeParams.java MFA verification params
sources/com/tplink/cloud/bean/common/CloudParams.java V1 method/params wrapper (deprecated)
sources/com/tplink/cloud/bean/common/CloudResult.java API response wrapper

Request Signing & HTTP

File Contains
sources/p401o7/C29914q.java Query parameter interceptor (appName, termID, token, etc.)
sources/p401o7/C29915r.java HMAC-SHA1 signing interceptor
sources/p401o7/C29918u.java Retrofit client builder (interceptor chain, Gson config)
sources/com/tplinkra/tplink/appserver/internal/AppServerHttpClientV2FA.java SDK HTTP client (alternative code path)
sources/com/tplinkra/tplink/appserver/internal/AppServerHttpClientHelper.java Signature computation helper

Device Commands

File Contains
sources/com/tplinkra/smartplug/hsall/api/TPSmartPlugCommand.java All smart plug commands
sources/com/tplinkra/light/lball/api/TPSmartBulbCommand.java All smart bulb commands
sources/com/tplinkra/tplink/appserver/internal/AppServerHelperV2FA.java Login flow via SDK path

Repository (Retrofit calls)

File Contains
sources/com/tplink/libcloud/repository/TCAccountRepository.java Account operations (login, MFA, etc.)
sources/com/tplink/libcloud/repository/TCDeviceRepository.java Device operations

Understanding Obfuscated Code

The decompiled code uses ProGuard obfuscation. Key patterns:

  • Class names like C29914q: Obfuscated class names. jadx renames them with a prefix.
  • Annotations: Retrofit annotations are obfuscated but recognizable by usage:
    • @InterfaceC2596o = @POST (Retrofit URL annotation)
    • @InterfaceC2592k = @Headers (HTTP headers)
    • @InterfaceC2582a = @Body (request body)
    • @InterfaceC2600s = @Path (URL path parameter)
    • @InterfaceC2606y = @Url (full URL)
  • Method names like m104820b: Obfuscated methods. Read the logic, not the name.

Tips for Future Updates

  1. Compare versions: When a new APK version drops, decompile it and diff against the previous version's key files
  2. Watch for new interceptors: The interceptor chain in C29918u.java determines what gets added to requests
  3. Check sdkconfig.xml: If the AccessKey/SecretKey changes, signing will break
  4. New API endpoints: Look at AccountV2Api.java for new annotations/methods
  5. New device types: Check sdkconfig.xml for the device type lists, and look for new command classes

Searching the Decompiled Code

# Find all API endpoint URLs
grep -r "api/v2/" kasa-decompiled/sources/ --include="*.java" -l

# Find error code constants
grep -r "20677\|20651\|20655\|23003" kasa-decompiled/sources/ --include="*.java"

# Find HMAC/signing related code
grep -r "HmacSHA1\|Content-MD5\|X-Authorization" kasa-decompiled/sources/ --include="*.java"

# Find device command strings
grep -r "set_relay_state\|get_sysinfo\|transition_light_state" kasa-decompiled/sources/ --include="*.java"

Clone this wiki locally