# 🎯 SOLUTION: Static Database Bypass (No Frida Needed!)

## The Problem

The app has **PairIP commercial protection** (`libpairipcore.so`) that:
1. Crashes on rooted devices (by design)
2. Prevents Frida from hooking (native crash before Java loads)
3. Uses VM bytecode encryption for anti-tampering

**Frida dynamic analysis is BLOCKED** by this protection.

## The Solution: Direct Database Manipulation

Since the premium check flow is:
```
DatabaseObserver.isPremiumPackUnlocked(sku)
  ↓
ThemeApp.g().existPurchase(sku)
  ↓
DatabaseHandlerIAB.existPurchase(sku)
  ↓
SQLite query: SELECT * FROM Premium WHERE item = ?
```

**We bypass the checks by directly modifying the SQLite database!**

---

## Method 1: Direct SQLite Injection (EASIEST)

### Step 1: Find the database
```powershell
adb -s 192.168.226.101:5555 shell "run-as com.backdrops.wallpapers ls -la databases/"
```

Expected output:
```
-rw-rw---- 1 u0_a85 u0_a85 20480 backdrops.db
-rw-rw---- 1 u0_a85 u0_a85 32768 backdrops.db-shm
-rw-rw---- 1 u0_a85 u0_a85  8192 backdrops.db-wal
```

### Step 2: Access SQLite shell
```powershell
adb -s 192.168.226.101:5555 shell
run-as com.backdrops.wallpapers
cd databases
sqlite3 backdrops.db
```

### Step 3: Check current Premium table
```sql
.tables
SELECT * FROM Premium;
```

Expected: Empty or no premium SKUs

### Step 4: Insert ALL premium packs
```sql
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.trinity', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.amoled', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.acid', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.optic', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.synth', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.void', 'UNLOCKED_CTF');
INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.premium', 'UNLOCKED_CTF');
```

### Step 5: Verify
```sql
SELECT * FROM Premium;
.quit
```

### Step 6: Launch app normally
```powershell
exit  # Exit run-as
exit  # Exit adb shell
adb -s 192.168.226.101:5555 shell am start -n com.backdrops.wallpapers/.activities.MainActivity
```

**✅ All premium packs should now be unlocked!**

---

## Method 2: Automated Script (Python)

I already created `database_injector.py` that does this automatically:

```powershell
python database_injector.py
```

This script:
1. Pulls the database from device
2. Adds premium SKUs
3. Pushes back to device
4. Verifies insertion

---

## Method 3: APK Patching (Static Modification)

If you want a permanent solution:

### Step 1: Decompile APK
```powershell
apktool d com.backdrops.wallpapers.apkm -o backdrops_decompiled
```

### Step 2: Find DatabaseHandlerIAB.smali
```
backdrops_decompiled\smali\com\backdrops\wallpapers\data\local\DatabaseHandlerIAB.smali
```

### Step 3: Patch existPurchase method

Find the method:
```smali
.method public existPurchase(Ljava/lang/String;)Li6/AbstractC1527s;
```

Replace its body with:
```smali
.method public existPurchase(Ljava/lang/String;)Li6/AbstractC1527s;
    .registers 3

    # Always return Single<TRUE>
    const/4 v0, 0x1
    invoke-static {v0}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
    move-result-object v0
    invoke-static {v0}, Li6/AbstractC1527s;->h(Ljava/lang/Object;)Li6/AbstractC1527s;
    move-result-object v0
    return-object v0
.end method
```

### Step 4: Patch getPurchased method

Find:
```smali
.method public getPurchased(Ljava/lang/String;)Ljava/lang/Boolean;
```

Replace with:
```smali
.method public getPurchased(Ljava/lang/String;)Ljava/lang/Boolean;
    .registers 2

    # Always return TRUE
    const/4 v0, 0x1
    invoke-static {v0}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;
    move-result-object v0
    return-object v0
.end method
```

### Step 5: Recompile and sign
```powershell
# Rebuild APK
apktool b backdrops_decompiled -o backdrops_patched.apk

# Sign APK
java -jar uber-apk-signer.jar --apks backdrops_patched.apk

# Install
adb -s 192.168.226.101:5555 install -r backdrops_patched-aligned-signed.apk
```

---

## Method 4: Root Shell Direct Write

If you have root shell access:

```bash
# Connect to device
adb -s 192.168.226.101:5555 shell

# Become root
su

# Stop app
am force-stop com.backdrops.wallpapers

# Navigate to app data
cd /data/data/com.backdrops.wallpapers/databases

# Backup original
cp backdrops.db backdrops.db.bak

# Inject premium SKUs
sqlite3 backdrops.db "INSERT OR REPLACE INTO Premium (item, token) VALUES ('backdrops.pack.trinity', 'UNLOCKED'), ('backdrops.pack.amoled', 'UNLOCKED'), ('backdrops.pack.acid', 'UNLOCKED'), ('backdrops.pack.optic', 'UNLOCKED'), ('backdrops.pack.synth', 'UNLOCKED'), ('backdrops.pack.void', 'UNLOCKED'), ('backdrops.premium', 'UNLOCKED');"

# Fix permissions
chown u0_a85:u0_a85 backdrops.db
chmod 660 backdrops.db

# Launch app
am start -n com.backdrops.wallpapers/.activities.MainActivity
```

---

## Understanding Why This Works

### The Premium Check Flow:
1. User clicks premium wallpaper
2. `DatabaseObserver.isPremiumPackUnlocked(sku)` called
3. Queries SQLite: `SELECT * FROM Premium WHERE item = ?`
4. If row exists → **UNLOCKED** ✅
5. If no row → **LOCKED** ❌

### Database Schema:
```sql
CREATE TABLE Premium (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    item TEXT,  -- SKU like "backdrops.pack.trinity"
    token TEXT  -- Purchase token (can be fake)
);
```

### Premium SKUs Found:
From `j1/E.java` (PlayBillingActivity):
- `backdrops.pack.trinity` (Trinity Pack)
- `backdrops.pack.amoled` (AMOLED Pack)
- `backdrops.pack.acid` (Acid Pack)
- `backdrops.pack.optic` (Optic Pack)
- `backdrops.pack.synth` (Synth Pack)
- `backdrops.pack.void` (Void Pack)
- `backdrops.premium` (Pro subscription)

---

## Verification Steps

After injecting the database:

1. Launch Backdrops normally (NO FRIDA)
2. Navigate to **Collections** or **Packs**
3. Open any premium pack (Trinity, AMOLED, etc.)
4. Wallpapers should open **without purchase prompt**
5. Download should work normally

---

## Why Frida Didn't Work

1. **PairIP Protection**: Commercial anti-tampering solution
2. **Native Root Detection**: Runs in `libpairipcore.so` JNI_OnLoad
3. **VM Bytecode**: Critical code is encrypted and executed in VM
4. **Early Crash**: Happens BEFORE Java.perform() can hook anything
5. **By Design**: Protection is designed to prevent dynamic analysis

**Conclusion**: Static analysis + database manipulation is the RIGHT approach for this CTF!

---

## Summary

✅ **Best Method**: Direct SQLite injection (Method 1)
- Works immediately
- No APK modification needed
- Survives app restarts
- Clean and simple

❌ **Frida**: Blocked by PairIP native protection
❌ **Dynamic Hooking**: Impossible with this level of protection

---

## Final Command Sequence

```powershell
# Quick solution (one-liner)
adb -s 192.168.226.101:5555 shell "run-as com.backdrops.wallpapers sqlite3 databases/backdrops.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');\""

# Launch app
adb -s 192.168.226.101:5555 shell am start -n com.backdrops.wallpapers/.activities.MainActivity
```

**That's it! Enjoy your premium wallpapers! 🎨**
