# 🎯 CTF SOLUTION - Backdrops Premium Bypass

## The Challenge
Reverse engineer the Backdrops APK (v6.1.1) to unlock premium wallpaper packs for free.

## The Protection
- **PairIP Commercial Protection** (`libpairipcore.so`) - Native anti-tamper
- **Root Detection** in Java (`C3/C0446i.java`) checking test-keys, Superuser.apk, /system/xbin/su
- **Encrypted VM Bytecode** - Critical code runs in protected VM
- **Native Crash** - App crashes BEFORE Frida can hook Java code

## Why Dynamic Analysis Failed
1. Native library crashes on startup (SIGSEGV in libpairipcore.so)
2. Crash happens in JNI_OnLoad before Java.perform() can execute
3. Frida hooks never get a chance to apply
4. Root detection runs at native level, not bypassable with Java hooks

## The Solution: Static Database Manipulation

### Key Finding
Premium check flow:
```
DatabaseObserver.isPremiumPackUnlocked(sku)
  ↓
ThemeApp.g().existPurchase(sku)  
  ↓
DatabaseHandlerIAB.existPurchase(sku)
  ↓
SQLite: SELECT * FROM Premium WHERE item = ?
```

**If row exists → UNLOCKED ✅**  
**If no row → LOCKED ❌**

### Database Details
- **File**: `/data/data/com.backdrops.wallpapers/databases/premium`
- **Table**: `Premium`
- **Schema**:
  ```sql
  CREATE TABLE Premium (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      item TEXT,  -- SKU like "backdrops.pack.trinity"
      token TEXT  -- Purchase token (can be anything)
  );
  ```

### Premium SKUs (from `j1/E.java`)
1. `backdrops.pack.trinity` - Trinity Pack
2. `backdrops.pack.amoled` - AMOLED Pack
3. `backdrops.pack.acid` - Acid Pack
4. `backdrops.pack.optic` - Optic Pack
5. `backdrops.pack.synth` - Synth Pack
6. `backdrops.pack.void` - Void Pack
7. `backdrops.premium` - Pro Subscription

## Implementation

### Method 1: Automated Script (EASIEST)
```powershell
.\SOLUTION.ps1
```

This script:
1. Stops the app
2. Pulls the `premium` database from device
3. Injects all premium SKUs with SQLite
4. Pushes modified database back
5. Launches app with premium unlocked

### Method 2: Manual Steps
```bash
# 1. Stop app
adb -s 192.168.226.101:5555 shell am force-stop com.backdrops.wallpapers

# 2. Copy database to accessible location
adb -s 192.168.226.101:5555 shell "su -c 'cp /data/data/com.backdrops.wallpapers/databases/premium /data/local/tmp/premium.db && chmod 666 /data/local/tmp/premium.db'"

# 3. Pull to local machine
adb -s 192.168.226.101:5555 pull /data/local/tmp/premium.db premium.db

# 4. Inject premium SKUs
sqlite3 premium.db "INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.trinity', 'CTF'), ('backdrops.pack.amoled', 'CTF'), ('backdrops.pack.acid', 'CTF'), ('backdrops.pack.optic', 'CTF'), ('backdrops.pack.synth', 'CTF'), ('backdrops.pack.void', 'CTF'), ('backdrops.premium', 'CTF');"

# 5. Push back to device
adb -s 192.168.226.101:5555 push premium.db /data/local/tmp/premium_modified.db
adb -s 192.168.226.101:5555 shell "su -c 'cp /data/local/tmp/premium_modified.db /data/data/com.backdrops.wallpapers/databases/premium && chown u0_a85:u0_a85 /data/data/com.backdrops.wallpapers/databases/premium && chmod 660 /data/data/com.backdrops.wallpapers/databases/premium'"

# 6. Launch app
adb -s 192.168.226.101:5555 shell am start -n com.backdrops.wallpapers/.activities.MainActivity
```

## Verification
1. Open Backdrops app
2. Navigate to Collections → Packs
3. Click on any premium pack (Trinity, AMOLED, Acid, etc.)
4. Wallpapers open WITHOUT purchase prompt ✅
5. Downloads work normally ✅

## Key Code Locations

### Premium Check Implementation
- `com/backdrops/wallpapers/data/DatabaseObserver.java` - High-level premium API
- `com/backdrops/wallpapers/data/local/DatabaseHandlerIAB.java` - SQLite manager
- `com/backdrops/wallpapers/ThemeApp.java` - Application class with DB singleton

### Protection Components
- `com/pairip/VMRunner.java` - PairIP VM runner (loads libpairipcore.so)
- `C3/C0446i.java` - Root detection (Firebase Crashlytics)
- `F3/E.java` - OsData class with isRooted field

## Lessons Learned

### ❌ What Didn't Work
- **Frida Dynamic Hooking** - Native crash prevents Java hooks
- **Root Detection Bypass** - Runs at native level before hooks
- **Spawn Mode Frida** - App crashes before instrumentation completes
- **Ultra-Early Hooks** - setImmediate() still too late

### ✅ What Worked
- **Static Analysis** - Identified premium check flow
- **Database Inspection** - Found simple SQLite verification
- **Direct Manipulation** - Bypassed all protections by modifying data
- **Root Access** - Used su to access protected database

## CTF Flag/Proof
After running the solution:
```sql
sqlite3 premium.db "SELECT * FROM Premium;"
```

Output:
```
1|backdrops.pack.trinity|CTF_UNLOCKED
2|backdrops.pack.amoled|CTF_UNLOCKED
3|backdrops.pack.acid|CTF_UNLOCKED
4|backdrops.pack.optic|CTF_UNLOCKED
5|backdrops.pack.synth|CTF_UNLOCKED
6|backdrops.pack.void|CTF_UNLOCKED
7|backdrops.premium|CTF_UNLOCKED
```

All premium wallpaper packs are now accessible in the app!

## Tools Used
- **JADX-GUI** - APK decompilation
- **ADB** - Android Debug Bridge
- **SQLite3** - Database manipulation
- **Static Code Analysis** - Reverse engineering premium flow
- **Root Access** - Database file access

## Time to Solution
- Initial Frida attempts: Failed (native protection)
- Root detection discovery: Found but not bypassable  
- Static analysis: Identified SQLite database as weak point
- Database manipulation: **SUCCESSFUL** ✅

---

**The key insight**: Sometimes the best way to bypass complex protections is to find a simpler attack vector. The premium check was ultimately just a database query, making all the native protection irrelevant!
