Quizzr Logo

API Reverse Engineering

Decompiling Mobile Binaries to Extract Hidden API Endpoints

Discover how to use JADX and Apktool to reverse Android and iOS binaries, revealing hardcoded URLs, API keys, and internal routing logic hidden in the source code.

SecurityAdvanced12 min read

The Hidden Blueprint: Why Static Analysis is Essential

Traditional API security testing often relies on dynamic analysis through intercepting proxies like Burp Suite or Charles. While effective for observing active traffic, this method only reveals endpoints triggered during manual navigation. It fails to expose hidden administrative routes, beta features, or dormant endpoints intended for future releases.

Static analysis fills this gap by examining the compiled binary directly to understand the full application surface. By reversing the code, engineers can discover hardcoded environment variables and internal routing logic. This approach identifies how the application constructs requests before they are even sent over the wire.

The methodology involves converting machine-readable instructions back into a human-readable format. For Android, this means reversing the Dalvik Executable format back into Java or Kotlin code. For iOS, it involves disassembling Mach-O binaries into assembly or pseudo-C code to find logic patterns.

Static analysis is not just about finding hidden strings; it is about reconstructing the mental model of the original developers to predict where vulnerabilities might exist.

The Limitations of Traffic Sniffing

Intercepting network traffic is frequently thwarted by modern security implementations such as Certificate Pinning. When pinning is active, the application refuses to establish a connection if the certificate does not match a hardcoded hash. This makes dynamic observation impossible without first patching the binary.

Furthermore, modern applications often use complex request signing algorithms to prevent tampering. Without access to the source code, understanding how these signatures are generated is nearly impossible. Static analysis allows us to locate the exact cryptographic functions used for these security headers.

The Android Deconstruction Pipeline

Android applications are distributed as APK or AAB files, which are essentially specialized ZIP archives. These archives contain the compiled bytecode in DEX files, along with resources and a manifest. To understand the API interaction, we must decompress these assets and convert the bytecode into a navigable format.

Apktool is the industry standard for unpacking the manifest and resource files. It decodes the binary XML files into a readable format and converts DEX files into Smali code. Smali is an intermediate representation that is useful for patching but difficult for high-level logic analysis.

For a higher-level view, JADX is the preferred tool for converting DEX files back into Java source code. It provides a searchable interface that allows developers to jump between class definitions and method calls. This makes it significantly easier to trace the flow of data from a user interface component to a network request.

  • Apktool: Best for resource analysis and binary patching to bypass security controls.
  • JADX: Best for understanding business logic and mapping internal API routing.
  • Ghidra: Used for analyzing native libraries written in C or C++ via the Java Native Interface.

Reconstructing the Networking Layer

Most modern Android applications use the Retrofit library for managing API interactions. Retrofit uses Java interfaces to define endpoints, which makes them very easy to identify during static analysis. These interfaces typically contain annotations that reveal the HTTP method, the path, and the required parameters.

When searching the decompiled source, looking for the @GET or @POST annotations is the fastest way to map the API surface. Even if the code is obfuscated, these annotations often remain intact to allow the library to function. This provides a clear list of all server-side functions the app is capable of calling.

javaReconstructed Retrofit Interface
1// This is an example of what a reversed Retrofit interface looks like in JADX
2public interface UserApiService {
3    @POST("api/v2/auth/login")
4    @Headers({"X-Platform: Android", "Content-Type: application/json"})
5    Call<LoginResponse> authenticateUser(@Body LoginRequest request);
6
7    @GET("api/v2/user/profile/{uid}")
8    Call<UserProfile> getUserData(@Path("uid") String userId, @Header("Authorization") String token);
9
10    @DELETE("api/v2/internal/debug_cleanup")
11    Call<Void> triggerInternalCleanup(); // This endpoint might not be visible in a proxy
12}

The iOS Perspective and Mach-O Analysis

Reversing iOS applications presents different challenges because they are compiled to native machine code for ARM64 architectures. Unlike the intermediate bytecode of Android, iOS binaries must be analyzed using disassemblers. This requires a deeper understanding of assembly language and the Objective-C or Swift runtime.

The first step is often decrypting the application binary, as apps downloaded from the App Store are encrypted with FairPlay DRM. Tools like Clutch or Frida-ios-dump are used on jailbroken devices to dump the decrypted Mach-O file. Once decrypted, the binary can be loaded into tools like Hopper Disassembler or Ghidra.

iOS apps written in Objective-C are particularly verbose in their metadata. Even in compiled form, the binary contains the names of classes and methods. This allows researchers to search for terms like API, Client, or Network to find the logic responsible for communicating with the backend.

Analyzing Swift Binaries

Swift is more difficult to reverse than Objective-C because it does not rely as heavily on dynamic message passing. However, Swift still leaves clues in the form of name mangling and metadata. Dedicated Swift demanglers can help turn complex symbols back into readable function signatures.

Focusing on the imports is a highly effective strategy for iOS. If an application imports the Network or Foundation frameworks, you can set breakpoints on common networking functions like URLSession. This allows you to inspect the arguments and discover the endpoints being targeted during execution.

We use cookies

Necessary cookies keep the site working. Analytics and ads help us improve and fund Quizzr. You can manage your preferences.