Package Manager (package) Log Documentation
Learning to Extract Package Manager Logs
Introduction
The Package Manager service (package) maintains comprehensive records of all applications installed on an Android device. This tutorial will guide you through extracting and understanding package manager logs for forensic analysis.
Prerequisites
- Android device with USB debugging enabled
- ADB (Android Debug Bridge) installed
- Basic command line knowledge
- Text editor for viewing large files
Step 1: Basic Package Log Extraction
Connect your device and verify ADB connection:
bash
adb devices
# Expected output:
# List of devices attached
# ABC123DEF456 device
Extract the complete package manager dump:
bash
# Create evidence directory
mkdir package_evidence
cd package_evidence
# Extract full package information
adb shell dumpsys package > package_full_dump.txt
# Extract specific sections
adb shell dumpsys package packages > installed_packages.txt
adb shell dumpsys package permissions > permissions.txt
adb shell dumpsys package providers > content_providers.txt
Step 2: Understanding the Output Structure
Open package_full_dump.txt and observe the main sections:
Package Manager state:
...
Packages:
Package [com.android.chrome] (4a5b6c7d):
userId=10120
pkg=Package{4a5b6c7d com.android.chrome}
codePath=/data/app/com.android.chrome-1
resourcePath=/data/app/com.android.chrome-1
versionCode=440509834 targetSdk=31
versionName=94.0.4606.85
firstInstallTime=2023-01-15-10:30:45
lastUpdateTime=2023-10-20-14:22:33
signatures=PackageSignatures{5e6f7a8b version:2, signatures:[9c8d9e0f], past signatures:[]}
installPermissions:
android.permission.INTERNET: granted=true
android.permission.ACCESS\_NETWORK\_STATE: granted=true
Step 3: First Analysis Exercise
Let's find all applications installed in the last 30 days:
bash
# Get current timestamp
CURRENT_TIME=$(date +%s000)
THIRTY_DAYS_AGO=$((CURRENT_TIME - 2592000000))
# Extract recent installations
grep -B5 "firstInstallTime=" package_full_dump.txt | \
awk -v cutoff="$THIRTY_DAYS_AGO" '
/Package \[/ {pkg=$0}
/firstInstallTime=/ {
gsub(/.*firstInstallTime=/, "")
if ($1 > cutoff) print pkg, "installed:", $0
}'
Understanding Key Fields
- Package Identification
Package [com.example.app]- Package name (unique identifier)userId- System user ID assigned to the appversionCode- Numeric version for updatesversionName- Human-readable version- Timestamps (in milliseconds since epoch)
firstInstallTime- When first installedlastUpdateTime- Most recent update- Installation Details
codePath- Where APK is storedinstaller- Package that installed this appsignatures- Developer certificates
Working with Package Manager Logs
How to Extract Specific Timeframes
Find Apps Installed on Specific Date
bash
# Extract apps installed on January 15, 2024
TARGET_DATE="2024-01-15"
grep -B10 -A5 "firstInstallTime=.*$TARGET_DATE" installed_packages.txt > apps_installed_$TARGET_DATE.txt
Find Apps Updated Within Date Range
bash
# Find apps updated between two dates
START_DATE=$(date -d "2024-01-01" +%s000)
END_DATE=$(date -d "2024-01-31" +%s000)
awk -v start="$START_DATE" -v end="$END_DATE" '
/Package \[/ {pkg=$0}
/lastUpdateTime=/ {
time=$0
gsub(/.*lastUpdateTime=/, "", time)
if (time >= start && time \<= end) {
print pkg
print "Updated:", strftime("%Y-%m-%d %H:%M:%S", time/1000)
}
}
' installed_packages.txt
How to Filter for Specific Events
Find Sideloaded Apps (Non-Play Store)
bash
# Extract installer information
adb shell dumpsys package packages | \
grep -B20 "installerPackageName=" | \
grep -E "Package \[|installerPackageName=" > installer_info.txt
# Find non-Google Play installations
grep -B1 "installerPackageName=" installer_info.txt | \
grep -v "com.android.vending" | \
grep -v "installerPackageName=null" > sideloaded_apps.txt
Find Apps with Dangerous Permissions
bash
# Define dangerous permissions
DANGEROUS_PERMS="CAMERA|RECORD_AUDIO|READ_SMS|READ_CONTACTS|ACCESS_FINE_LOCATION"
# Extract apps with these permissions
grep -B30 -E "$DANGEROUS_PERMS.*granted=true" installed_packages.txt | \
grep -E "Package \[|$DANGEROUS_PERMS.*granted=true" > apps_dangerous_permissions.txt
How to Correlate with Other Logs
Cross-Reference with Usage Stats
bash
# Extract package names from both sources
grep "Package \[" installed_packages.txt | \
sed 's/.*\[//' | sed 's/\].*//' | sort > installed_apps.list
adb shell dumpsys usagestats | \
grep "package=" | \
sed 's/.*package=//' | sed 's/ .*//' | sort -u > used_apps.list
# Find installed but never used apps
comm -23 installed_apps.list used_apps.list > never_used_apps.txt
# Find usage of uninstalled apps
comm -13 installed_apps.list used_apps.list > uninstalled_but_used.txt
Correlate with Battery Stats
bash
# Get package UIDs
grep -A1 "Package \[" installed_packages.txt | \
grep "userId=" > package_uids.txt
# Extract battery usage by UID
adb shell dumpsys batterystats --charged | \
grep "UID " > battery_by_uid.txt
# Match packages to battery usage
while read line; do
uid=$(echo $line | grep -o "userId=[0-9]*" | cut -d= -f2)
pkg=$(echo $line | grep -o "\[.*\]" | tr -d "[]")
battery=$(grep "UID $uid:" battery_by_uid.txt)
if [ ! -z "$battery" ]; then
echo "Package: $pkg"
echo "$battery"
echo "---"
fi
done \< package_uids.txt
How to Identify Anomalies
Detect Hidden System Apps
bash
# Find disabled system apps
adb shell dumpsys package packages | \
grep -B5 "enabled=false" | \
grep -E "Package \[|enabled=false" > disabled_apps.txt
# Find apps hidden from launcher
adb shell dumpsys package packages | \
grep -B20 "LAUNCHER" | \
grep -v "category.LAUNCHER" | \
grep "Package \[" > hidden_apps.txt
Identify Suspicious Installers
bash
# Extract all unique installers
grep "installerPackageName=" installed_packages.txt | \
sort -u | \
grep -v "com.android.vending" | \
grep -v "com.google.android.packageinstaller" | \
grep -v "null" > unusual_installers.txt
# Find apps installed by suspicious installers
while read installer; do
echo "Apps installed by $installer:"
grep -B20 "$installer" installed_packages.txt | grep "Package \["
echo "---"
done \< unusual_installers.txt
REFERENCE - Package Manager Log Structure
Complete Field Definitions
Package Entry Structure
Package [package.name] (hash):
userId=10120 # Assigned Linux user ID
pkg=Package{hash package.name} # Internal reference
codePath=/data/app/package.name-1 # APK location
resourcePath=/data/app/package.name-1 # Resources location
legacyNativeLibraryDir=/data/app/package.name-1/lib # Native libraries
primaryCpuAbi=arm64-v8a # Primary CPU architecture
secondaryCpuAbi=null # Secondary CPU architecture
versionCode=1234 minSdk=21 targetSdk=31 # Version information
versionName=1.2.3 # User-visible version
splits=[base] # APK splits
apkSigningVersion=2 # Signature scheme version
applicationInfo=ApplicationInfo{hash package.name}
flags=[ ... ] # System flags
privateFlags=[ ... ] # Private system flags
dataDir=/data/user/0/package.name # App data directory
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
timeStamp=2024-01-15 10:30:45 # Build timestamp
firstInstallTime=2024-01-15 10:30:45 # First installation
lastUpdateTime=2024-01-20 14:22:33 # Last update
signatures=PackageSignatures{hash version:2, signatures:[...]}
installPermissions: # Install-time permissions
permission.name: granted=true/false
requestedPermissions: # All requested permissions
permission.name
install permissions: # Granted install permissions
permission.name: granted=true, flags=0x0
User 0: ceDataInode=12345 installed=true hidden=false suspended=false
gids=[3003, 1028, 1015] # Group IDs
runtime permissions: # Runtime permissions
permission.name: granted=true/false, flags=0x0
Permission Structure
Permission [permission.name]
package=package.name # Defining package
type=normal|dangerous|signature # Permission level
protectionLevel=0x2 # Protection flags
perm=Permission{hash permission.name}
Shared User Structure
SharedUser [android.uid.shared] (hash):
userId=10000 # Shared user ID
gids=[1000, 1001] # Group IDs
packages=[package1, package2] # Packages sharing UID
Data Types and Formats
| Field | Type | Format | Example |
|---|---|---|---|
| Package name | String | Reverse domain | com.example.app |
| userId | Integer | 10000+ for user apps | 10120 |
| versionCode | Long | Incremental number | 1234567 |
| Timestamp | Long | Milliseconds since epoch | 1705309845000 |
| Permissions | String | Dot notation | android.permission.CAMERA |
| Signature | Hex | SHA-256 hash | 9c8d9e0f... |
| Flags | Hex/Binary | Bitwise flags | 0x20000 |
| APK Path | String | Filesystem path | /data/app/... |
Retention Periods
| Data Type | Retention | Notes |
|---|---|---|
| Package entries | Until uninstalled | Survives factory reset if system app |
| Installation time | Permanent | Never updated after first install |
| Update history | Last update only | Previous update times overwritten |
| Permissions | Current state | Historical grants not preserved |
| Signatures | Current version | Old signatures in pastSignatures |
| Disabled state | Current state | No history of enable/disable |
Sample Outputs with Annotations
Standard User App
Package [com.whatsapp] (a1b2c3d4): # WhatsApp package
userId=10142 # High UID \= user app
versionCode=231234 targetSdk=31 # Recent target SDK
firstInstallTime=2023-05-20-08:15:30 # Installation date
lastUpdateTime=2024-01-18-19:45:22 # Recently updated
installerPackageName=com.android.vending # Play Store install
signatures=PackageSignatures{5e6f7a8b} # Developer signature
installPermissions:
android.permission.INTERNET: granted=true
android.permission.CAMERA: granted=true # Camera access
android.permission.RECORD\_AUDIO: granted=true \# Microphone
Sideloaded App
Package [com.unknown.app] (e5f6a7b8): # Unknown package
userId=10201
versionCode=1 targetSdk=19 # Old target SDK (red flag)
firstInstallTime=2024-01-19-23:45:00 # Late night install
lastUpdateTime=2024-01-19-23:45:00 # Never updated
installerPackageName=com.android.packageinstaller # Sideloaded
signatures=PackageSignatures{1a2b3c4d} # Unknown signature
requestedPermissions: # Excessive permissions
android.permission.READ_SMS
android.permission.SEND_SMS
android.permission.READ_CONTACTS
android.permission.CAMERA
android.permission.RECORD\_AUDIO
Quick Reference Commands
bash
# Essential Package Manager Commands
adb shell dumpsys package # Full dump
adb shell dumpsys package packages # All packages
adb shell dumpsys package permissions # All permissions
adb shell dumpsys package providers # Content providers
adb shell dumpsys package [package.name] # Specific package
adb shell dumpsys package r # Permission registry
adb shell dumpsys package pref # Preferred activities
# Filtered Extractions
adb shell dumpsys package packages | grep -A50 "Package \["
adb shell dumpsys package | grep -E "firstInstall|lastUpdate"
adb shell dumpsys package | grep -B5 "installerPackage"
adb shell dumpsys package | grep -A20 "userId="
# Analysis Commands
adb shell pm list packages -f # Package file locations
adb shell pm list packages -d # Disabled packages
adb shell pm list packages -e # Enabled packages
adb shell pm list packages -s # System packages
adb shell pm list packages -3 # Third-party packages
adb shell pm list packages -i # Package installers
adb shell pm list packages -u # Uninstalled packages
Understanding Package Manager Logs
Why Package Manager Logs Exist
The Package Manager Service (PMS) is a critical Android system service responsible for:
- Application Lifecycle Management
- Installing, updating, and uninstalling applications
- Managing APK files and application data
- Tracking version information for updates
- Security Enforcement
- Managing application permissions
- Verifying application signatures
- Enforcing security policies
- System Integration
- Resolving application components (activities, services)
- Managing shared libraries and features
- Handling content providers and data sharing
How Android Generates Package Data
Data Generation Flow
APK Installation Request
↓
Package Manager Service
↓
├── Signature Verification
├── Permission Analysis
├── UID Assignment
└── Storage Allocation
↓
Package Database Update
↓
System Broadcast (PACKAGE_ADDED)
Data Sources
- APK Manifest - App declarations and requirements
- System Policy - Security and permission rules
- User Actions - Install/uninstall/disable events
- System Events - Updates, resets, user switches
Storage Locations
/data/system/packages.xml- Main package database/data/system/packages.list- Simple package list/data/system/users/*/package-restrictions.xml- User-specific settings
Forensic Significance
High-Value Forensic Artifacts
- Installation Timeline
- Establishes when apps were first present on device
- Cannot be modified without root access
- Survives app updates
- Update Patterns
- Indicates device usage periods
- Shows app maintenance behavior
- May reveal time zone changes
- Permission Grants
- Shows what capabilities apps had
- Indicates user security awareness
- Critical for privacy investigations
- Installation Sources
- Play Store vs sideloading
- Enterprise deployment detection
- Potential malware vectors
Investigative Applications
| Investigation Type | Relevant Package Data |
|---|---|
| Timeline Analysis | firstInstallTime, lastUpdateTime |
| Malware Detection | Signatures, permissions, installer |
| User Behavior | Installed apps, disabled apps |
| Data Theft | Apps with storage/network permissions |
| Corporate Espionage | Enterprise apps, certificates |
| Child Safety | Age-inappropriate apps, hidden apps |
Relationship to Other Logs
Direct Relationships
Package Manager ←→ Usage Stats
└─ Package names link usage data
Package Manager ←→ Battery Stats
└─ UIDs link power consumption
Package Manager ←→ App Ops
└─ Permissions link to usage logs
Package Manager ←→ Activity Manager
└─ Components link to running processes
Correlation Opportunities
- With Usage Stats
- Find installed but unused apps (dormant malware?)
- Verify app presence during reported usage
- With Battery Stats
- Match high battery use to specific apps
- Identify apps running without user knowledge
- With Network Stats
- Link network usage to installed apps
- Find apps with unexpected network activity
- With Notifications
- Verify app was installed when notification sent
- Check notification permissions
Legal Considerations
Admissibility Factors
- Reliability
- Package manager data comes directly from Android OS
- Well-documented and consistent across versions
- Courts generally accept as reliable
- Timestamp Accuracy
- Uses system time (verify accuracy)
- Millisecond precision
- UTC internally, displayed in local time
- Immutability
- Cannot be modified without root
- Changes require system-level access
- Signatures prevent tampering
Privacy Implications
- Package names may reveal personal interests
- Medical, dating, financial apps particularly sensitive
- Consider redaction in reports
Chain of Custody Requirements
bash
# Document extraction
echo "=== Package Manager Extraction \===" | tee -a extraction_log.txt
echo "Date: $(date)" | tee -a extraction_log.txt
echo "Examiner: $EXAMINER_NAME" | tee -a extraction_log.txt
echo "Device: $(adb shell getprop ro.product.model)" | tee -a extraction_log.txt
echo "Android Version: $(adb shell getprop ro.build.version.release)" | tee -a extraction_log.txt
# Extract with verification
adb shell dumpsys package | tee package_dump.txt | sha256sum > package_dump.sha256
# Verify integrity later
sha256sum -c package_dump.sha256
Common Challenges and Solutions
| Challenge | Solution |
|---|---|
| Timestamp interpretation | Convert from epoch, note timezone |
| Missing installer info | May indicate manual install or system app |
| Signature verification | Use external tools like apksigner |
| Hidden apps | Check enabled=false and missing LAUNCHER |
| Version tracking | versionCode is authoritative, not versionName |
| UID correlation | Apps may share UIDs (sharedUserId) |
Advanced Analysis Techniques
Signature Analysis for App Authenticity
bash
# Extract and verify signatures
PACKAGE="com.example.app"
adb shell dumpsys package $PACKAGE | grep -A5 "signatures=" > sig.txt
# Compare with known good signature
KNOWN_GOOD="a1b2c3d4..."
grep $KNOWN_GOOD sig.txt || echo "WARNING: Signature mismatch!"
Permission Escalation Detection
bash
# Track permission changes over time
# Save current state
adb shell dumpsys package packages > packages_$(date +%Y%m%d).txt
# Later, compare
diff packages_20240101.txt packages_20240120.txt | \
grep -E "permission.*granted" > permission_changes.txt