android-sdd 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/index.js +143 -0
  2. package/package.json +27 -0
  3. package/skills/Android Ecosystem/Baseline Profile Generator/SKILL.md +277 -0
  4. package/skills/Android Ecosystem/Glance/SKILL.md +315 -0
  5. package/skills/Android Platform/Configuration/SKILL.md +201 -0
  6. package/skills/Android Platform/Filesystem/SKILL.md +216 -0
  7. package/skills/Android Platform/Lifecycle/SKILL.md +233 -0
  8. package/skills/Android Platform/Manifest/SKILL.md +226 -0
  9. package/skills/Android Platform/Process Death Recovery/SKILL.md +214 -0
  10. package/skills/Android Platform/Resources/SKILL.md +234 -0
  11. package/skills/Android Platform/SavedStateHandle/SKILL.md +217 -0
  12. package/skills/Android Platform/State Restoration/SKILL.md +210 -0
  13. package/skills/Architecture/Bounded Context/SKILL.md +207 -0
  14. package/skills/Architecture/Clean Architecture/SKILL.md +229 -0
  15. package/skills/Architecture/Domain Modeling/SKILL.md +236 -0
  16. package/skills/Architecture/Entity Design/SKILL.md +243 -0
  17. package/skills/Architecture/Feature Isolation/SKILL.md +216 -0
  18. package/skills/Architecture/MVI/SKILL.md +224 -0
  19. package/skills/Architecture/MVVM/SKILL.md +198 -0
  20. package/skills/Architecture/Modularization/SKILL.md +194 -0
  21. package/skills/Architecture/Offline First/SKILL.md +249 -0
  22. package/skills/Architecture/Repository Pattern/SKILL.md +216 -0
  23. package/skills/Architecture/Side Effect Management/SKILL.md +278 -0
  24. package/skills/Architecture/State Management/SKILL.md +229 -0
  25. package/skills/Architecture/Unidirectional Data Flow/SKILL.md +196 -0
  26. package/skills/Architecture/Use Case Design/SKILL.md +244 -0
  27. package/skills/Architecture/Value Object/SKILL.md +226 -0
  28. package/skills/Build Infrastructure/Build Orchestration/SKILL.md +257 -0
  29. package/skills/Build Infrastructure/Dependency Compatibility Resolver/SKILL.md +259 -0
  30. package/skills/Build Infrastructure/Environment Validator/SKILL.md +311 -0
  31. package/skills/Build System/Build Cache/SKILL.md +233 -0
  32. package/skills/Build System/Build Flavor Strategy/SKILL.md +171 -0
  33. package/skills/Build System/Build Variant/SKILL.md +215 -0
  34. package/skills/Build System/Convention Plugin/SKILL.md +288 -0
  35. package/skills/Build System/Dependency Management/SKILL.md +261 -0
  36. package/skills/Build System/Gradle/SKILL.md +284 -0
  37. package/skills/Build System/Incremental Build/SKILL.md +199 -0
  38. package/skills/Build System/KAPT/SKILL.md +198 -0
  39. package/skills/Build System/KSP/SKILL.md +263 -0
  40. package/skills/Build System/Module Dependency Graph Validation/SKILL.md +223 -0
  41. package/skills/Build System/Specialized/C++/SKILL.md +308 -0
  42. package/skills/Build System/Specialized/JNI/SKILL.md +306 -0
  43. package/skills/Build System/Specialized/NDK/SKILL.md +264 -0
  44. package/skills/Build System/Version Catalog/SKILL.md +304 -0
  45. package/skills/Concurrency/Background Processing/SKILL.md +185 -0
  46. package/skills/Concurrency/Channel/SKILL.md +207 -0
  47. package/skills/Concurrency/Coroutine/SKILL.md +200 -0
  48. package/skills/Concurrency/Flow/SKILL.md +179 -0
  49. package/skills/Concurrency/Mutex Strategy/SKILL.md +185 -0
  50. package/skills/Concurrency/SharedFlow/SKILL.md +171 -0
  51. package/skills/Concurrency/StateFlow/SKILL.md +175 -0
  52. package/skills/Concurrency/Structured Concurrency/SKILL.md +197 -0
  53. package/skills/Concurrency/Synchronization Policy/SKILL.md +192 -0
  54. package/skills/Core Language/Annotation Processing/SKILL.md +224 -0
  55. package/skills/Core Language/DSL/SKILL.md +186 -0
  56. package/skills/Core Language/Extension Functions Design/SKILL.md +191 -0
  57. package/skills/Core Language/Immutability/SKILL.md +156 -0
  58. package/skills/Core Language/KMP/SKILL.md +182 -0
  59. package/skills/Core Language/Kotlin/SKILL.md +187 -0
  60. package/skills/Core Language/Reactive State Management/SKILL.md +228 -0
  61. package/skills/Core Language/Reactive Streams/SKILL.md +235 -0
  62. package/skills/Core Language/Serialization/SKILL.md +191 -0
  63. package/skills/Data Layer/Cache Strategy/SKILL.md +261 -0
  64. package/skills/Data Layer/Conflict Resolution/SKILL.md +248 -0
  65. package/skills/Data Layer/DAO/SKILL.md +225 -0
  66. package/skills/Data Layer/DTO Mapping/SKILL.md +269 -0
  67. package/skills/Data Layer/DataStore/SKILL.md +264 -0
  68. package/skills/Data Layer/Database Versioning Strategy/SKILL.md +215 -0
  69. package/skills/Data Layer/Encrypted Database/SKILL.md +212 -0
  70. package/skills/Data Layer/File Storage/SKILL.md +247 -0
  71. package/skills/Data Layer/Indexing/SKILL.md +184 -0
  72. package/skills/Data Layer/Key-Value Store Strategy/SKILL.md +185 -0
  73. package/skills/Data Layer/Merge Strategy/SKILL.md +240 -0
  74. package/skills/Data Layer/Migration/SKILL.md +243 -0
  75. package/skills/Data Layer/Paging/SKILL.md +264 -0
  76. package/skills/Data Layer/Proto DataStore/SKILL.md +250 -0
  77. package/skills/Data Layer/Room/SKILL.md +244 -0
  78. package/skills/Data Layer/SQLite/SKILL.md +255 -0
  79. package/skills/Data Layer/Sync Engine/SKILL.md +268 -0
  80. package/skills/Dependency Injection/Dagger/SKILL.md +283 -0
  81. package/skills/Dependency Injection/Hilt/SKILL.md +345 -0
  82. package/skills/Dependency Injection/Koin/SKILL.md +282 -0
  83. package/skills/Developer Experience/Detekt/SKILL.md +272 -0
  84. package/skills/Developer Experience/Lint Rule/SKILL.md +281 -0
  85. package/skills/Google Ecosystem/Analytics/SKILL.md +281 -0
  86. package/skills/Google Ecosystem/Crashlytics/SKILL.md +234 -0
  87. package/skills/Google Ecosystem/Firebase/SKILL.md +200 -0
  88. package/skills/Google Ecosystem/Firebase Messaging/SKILL.md +266 -0
  89. package/skills/Media/Audio/SKILL.md +257 -0
  90. package/skills/Media/Camera/SKILL.md +229 -0
  91. package/skills/Media/CameraX/SKILL.md +295 -0
  92. package/skills/Media/ExoPlayer/SKILL.md +258 -0
  93. package/skills/Media/Video/SKILL.md +228 -0
  94. package/skills/Meta Skills/Domain Error Model/SKILL.md +238 -0
  95. package/skills/Meta Skills/Error Handling/SKILL.md +255 -0
  96. package/skills/Meta Skills/Error Mapping/SKILL.md +232 -0
  97. package/skills/Meta Skills/Failure Strategy/SKILL.md +294 -0
  98. package/skills/Meta Skills/Migration Strategy/SKILL.md +305 -0
  99. package/skills/Meta Skills/User Friendly Errors/SKILL.md +334 -0
  100. package/skills/Navigation/Deep Navigation/SKILL.md +209 -0
  101. package/skills/Navigation/Navigation/SKILL.md +215 -0
  102. package/skills/Navigation/Nested Navigation/SKILL.md +214 -0
  103. package/skills/Networking/API Contract/SKILL.md +220 -0
  104. package/skills/Networking/Authentication/SKILL.md +210 -0
  105. package/skills/Networking/Certificate Pinning/SKILL.md +167 -0
  106. package/skills/Networking/Fallback Strategy/SKILL.md +182 -0
  107. package/skills/Networking/Ktor/SKILL.md +219 -0
  108. package/skills/Networking/Multipart Upload/SKILL.md +213 -0
  109. package/skills/Networking/OkHttp/SKILL.md +193 -0
  110. package/skills/Networking/REST/SKILL.md +178 -0
  111. package/skills/Networking/Rate Limiting/SKILL.md +170 -0
  112. package/skills/Networking/Retrofit/SKILL.md +241 -0
  113. package/skills/Networking/Retry-Backoff/SKILL.md +181 -0
  114. package/skills/Networking/Server-Sent Events (SSE)/SKILL.md +196 -0
  115. package/skills/Networking/WebSocket/SKILL.md +224 -0
  116. package/skills/Observability/Crash Reporting/SKILL.md +219 -0
  117. package/skills/Observability/Logging/SKILL.md +168 -0
  118. package/skills/Observability/Metrics/SKILL.md +227 -0
  119. package/skills/Observability/Structured Logging/SKILL.md +234 -0
  120. package/skills/Performance/ANR Prevention/SKILL.md +192 -0
  121. package/skills/Performance/Allocation Optimization/SKILL.md +179 -0
  122. package/skills/Performance/App Startup/SKILL.md +183 -0
  123. package/skills/Performance/Baseline Profile/SKILL.md +205 -0
  124. package/skills/Performance/Battery Optimization/SKILL.md +192 -0
  125. package/skills/Performance/Benchmark/SKILL.md +182 -0
  126. package/skills/Performance/Bitmap Optimization/SKILL.md +178 -0
  127. package/skills/Performance/Compose Optimization/SKILL.md +187 -0
  128. package/skills/Performance/Heap Management/SKILL.md +184 -0
  129. package/skills/Performance/Macrobenchmark/SKILL.md +214 -0
  130. package/skills/Performance/Memory Leak Prevention/SKILL.md +218 -0
  131. package/skills/Performance/Rendering Performance/SKILL.md +205 -0
  132. package/skills/Performance/Startup Optimization/SKILL.md +219 -0
  133. package/skills/Security/Biometric/SKILL.md +224 -0
  134. package/skills/Security/Certificate Transparency/SKILL.md +158 -0
  135. package/skills/Security/Cryptography/SKILL.md +244 -0
  136. package/skills/Security/Encrypted Storage/SKILL.md +273 -0
  137. package/skills/Security/Frida Detection/SKILL.md +230 -0
  138. package/skills/Security/Hook Detection/SKILL.md +197 -0
  139. package/skills/Security/Keystore/SKILL.md +272 -0
  140. package/skills/Security/Network Security Config/SKILL.md +186 -0
  141. package/skills/Security/Obfuscation/SKILL.md +226 -0
  142. package/skills/Security/Proguard/SKILL.md +202 -0
  143. package/skills/Security/R8/SKILL.md +234 -0
  144. package/skills/Security/Reverse Engineering Resistance/SKILL.md +267 -0
  145. package/skills/Security/Root Detection/SKILL.md +220 -0
  146. package/skills/Security/Secure Networking/SKILL.md +220 -0
  147. package/skills/System Integration/AlarmManager/SKILL.md +182 -0
  148. package/skills/System Integration/App Widget/SKILL.md +182 -0
  149. package/skills/System Integration/Deep Link/SKILL.md +187 -0
  150. package/skills/System Integration/Foreground Service/SKILL.md +212 -0
  151. package/skills/System Integration/Notification/SKILL.md +237 -0
  152. package/skills/System Integration/WorkManager/SKILL.md +256 -0
  153. package/skills/System Integration/clipboard/SKILL.md +155 -0
  154. package/skills/System Integration/share-intent/SKILL.md +182 -0
  155. package/skills/Testing/Compose Testing/SKILL.md +296 -0
  156. package/skills/Testing/Espresso/SKILL.md +292 -0
  157. package/skills/Testing/Fake Data/SKILL.md +245 -0
  158. package/skills/Testing/Integration Testing/SKILL.md +288 -0
  159. package/skills/Testing/Mocking/SKILL.md +229 -0
  160. package/skills/Testing/Snapshot Testing/SKILL.md +259 -0
  161. package/skills/Testing/UI Testing/SKILL.md +293 -0
  162. package/skills/Testing/Unit Testing/SKILL.md +309 -0
  163. package/skills/UI System/Bottom Sheet Patterns/SKILL.md +279 -0
  164. package/skills/UI System/Compose/SKILL.md +296 -0
  165. package/skills/UI System/Compose Animation/SKILL.md +281 -0
  166. package/skills/UI System/Compose Multiplatform/SKILL.md +261 -0
  167. package/skills/UI System/Compose Navigation/SKILL.md +255 -0
  168. package/skills/UI System/Compose Performance/SKILL.md +274 -0
  169. package/skills/UI System/Design System/SKILL.md +217 -0
  170. package/skills/UI System/Empty State Strategy/SKILL.md +208 -0
  171. package/skills/UI System/Keyboard Navigation/SKILL.md +214 -0
  172. package/skills/UI System/Loading Strategy/SKILL.md +254 -0
  173. package/skills/UI System/Material 3/SKILL.md +279 -0
  174. package/skills/UI System/RTL/SKILL.md +179 -0
  175. package/src/index.ts +182 -0
  176. package/tsconfig.json +19 -0
@@ -0,0 +1,202 @@
1
+ ---
2
+ name: proguard
3
+ description: >
4
+ ProGuard rules reference for Android apps.
5
+ Load this skill when writing or debugging -keep rules, understanding
6
+ ProGuard rule syntax, maintaining proguard-rules.pro, or resolving
7
+ runtime crashes caused by missing keep rules.
8
+ ---
9
+
10
+ # ProGuard
11
+
12
+ ## Overview
13
+ ProGuard is the rule language used by both the legacy ProGuard tool and its successor R8. In modern Android projects, you write ProGuard-syntax rules in `proguard-rules.pro`, and R8 consumes them. Understanding the rule syntax is essential for preventing runtime crashes in release builds.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - ProGuard rules **whitelist** — everything is removed unless kept
20
+ - Rules are **additive** — you cannot un-keep something kept by another rule
21
+ - Prefer **specific rules** over broad ones — broad rules defeat shrinking
22
+ - Rules affect **shrinking, obfuscation, and optimization** independently
23
+ - Test on a real device with a release/minified build before shipping
24
+
25
+ ---
26
+
27
+ ## Rule Syntax Reference
28
+
29
+ ```proguard
30
+ # Keep a class and all its members
31
+ -keep class com.example.MyClass { *; }
32
+
33
+ # Keep a class name only (members may still be removed/renamed)
34
+ -keep class com.example.MyClass
35
+
36
+ # Keep members but allow class renaming
37
+ -keepclassmembers class com.example.MyClass {
38
+ public void myMethod();
39
+ private String myField;
40
+ }
41
+
42
+ # Keep class if it has certain members (conditional keep)
43
+ -keepclasseswithmembers class * {
44
+ public <init>(android.content.Context);
45
+ }
46
+
47
+ # Keep class name if it has certain members (class name kept, members may be renamed)
48
+ -keepclasseswithmembernames class * {
49
+ native <methods>;
50
+ }
51
+
52
+ # Keep attributes (metadata)
53
+ -keepattributes *Annotation*
54
+ -keepattributes Signature
55
+ -keepattributes SourceFile,LineNumberTable
56
+ -keepattributes Exceptions
57
+
58
+ # Suppress warnings (use sparingly)
59
+ -dontwarn com.example.third.party.**
60
+
61
+ # Suppress notes
62
+ -dontnote com.example.third.party.**
63
+
64
+ # Rename source file attribute (for stack trace clarity)
65
+ -renamesourcefileattribute SourceFile
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Wildcards
71
+
72
+ ```proguard
73
+ # * — matches any single package component or partial name (not dots)
74
+ -keep class com.example.*.Model { *; } # matches com.example.user.Model
75
+ # NOT com.example.user.detail.Model
76
+
77
+ # ** — matches any number of package components (including dots)
78
+ -keep class com.example.**.Model { *; } # matches both
79
+
80
+ # *** — matches any type (primitive or object)
81
+ # % — matches any primitive type
82
+ # <fields> — all fields
83
+ # <methods> — all methods
84
+ # <init> — constructors
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Common Rules by Library
90
+
91
+ ```proguard
92
+ # ── Retrofit ──────────────────────────────────────────────────────────────
93
+ -keepattributes Signature
94
+ -keepattributes Exceptions
95
+ -keep interface * {
96
+ @retrofit2.http.* <methods>;
97
+ }
98
+ -dontwarn retrofit2.**
99
+
100
+ # ── OkHttp ────────────────────────────────────────────────────────────────
101
+ -dontwarn okhttp3.**
102
+ -dontwarn okio.**
103
+ -keep class okhttp3.** { *; }
104
+ -keep interface okhttp3.** { *; }
105
+
106
+ # ── Gson ──────────────────────────────────────────────────────────────────
107
+ -keepclassmembers class * {
108
+ @com.google.gson.annotations.SerializedName <fields>;
109
+ }
110
+ -keep class com.example.app.data.remote.dto.** { *; }
111
+
112
+ # ── kotlinx.serialization ─────────────────────────────────────────────────
113
+ -keepattributes *Annotation*, InnerClasses
114
+ -dontnote kotlinx.serialization.AnnotationsKt
115
+ -keepclassmembers class kotlinx.serialization.json.** {
116
+ *** Companion;
117
+ }
118
+
119
+ # ── Room ──────────────────────────────────────────────────────────────────
120
+ -keep class * extends androidx.room.RoomDatabase
121
+ -keep @androidx.room.Entity class * { *; }
122
+ -keep @androidx.room.Dao interface * { *; }
123
+
124
+ # ── Hilt / Dagger ─────────────────────────────────────────────────────────
125
+ -keep class dagger.** { *; }
126
+ -keep class javax.inject.** { *; }
127
+ -keep @dagger.hilt.android.HiltAndroidApp class *
128
+ -keep @dagger.hilt.android.AndroidEntryPoint class *
129
+ -keep @dagger.hilt.InstallIn class *
130
+
131
+ # ── Parcelable ────────────────────────────────────────────────────────────
132
+ -keep class * implements android.os.Parcelable {
133
+ public static final android.os.Parcelable$Creator *;
134
+ }
135
+
136
+ # ── Enum ──────────────────────────────────────────────────────────────────
137
+ -keepclassmembers enum * {
138
+ public static **[] values();
139
+ public static ** valueOf(java.lang.String);
140
+ }
141
+
142
+ # ── Firebase ──────────────────────────────────────────────────────────────
143
+ -keep class com.google.firebase.** { *; }
144
+ -keep class com.google.android.gms.** { *; }
145
+ -dontwarn com.google.firebase.**
146
+
147
+ # ── Crashlytics ───────────────────────────────────────────────────────────
148
+ -keepattributes SourceFile,LineNumberTable
149
+ -keep public class * extends java.lang.Exception
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Diagnosing Missing Keep Rules
155
+
156
+ ```bash
157
+ # Run release build and check logcat for:
158
+ # E/AndroidRuntime: java.lang.ClassNotFoundException: com.example.MyClass
159
+ # → Add: -keep class com.example.MyClass { *; }
160
+
161
+ # E/AndroidRuntime: java.lang.NoSuchMethodException: myMethod
162
+ # → Add: -keepclassmembers class com.example.MyClass { void myMethod(); }
163
+
164
+ # Check usage.txt to see what was removed:
165
+ # app/build/outputs/mapping/release/usage.txt
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Rule Debugging
171
+
172
+ ```proguard
173
+ # ✅ Print which rules were applied (outputs to build logs)
174
+ -printconfiguration build/outputs/mapping/release/configuration.txt
175
+
176
+ # ✅ Print which classes were kept
177
+ -printseeds build/outputs/mapping/release/seeds.txt
178
+
179
+ # ✅ Print which code was removed
180
+ -printusage build/outputs/mapping/release/usage.txt
181
+
182
+ # ✅ Print the mapping
183
+ -printmapping build/outputs/mapping/release/mapping.txt
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Anti-Patterns
189
+
190
+ - `-keep class com.example.** { *; }` — keeps all code, no shrinking benefit
191
+ - Writing rules without testing the release build — issues only surface at runtime
192
+ - `-dontwarn **` — suppresses all warnings including real problems
193
+ - Forgetting `-keepattributes Signature` — breaks Retrofit generic type resolution
194
+ - Not keeping DTO fields with Gson — deserialized objects have null fields in release
195
+
196
+ ---
197
+
198
+ ## Related Skills
199
+ - `r8` — R8 configuration and full mode
200
+ - `obfuscation` — obfuscation strategy and when to apply it
201
+ - `build-variant` — applying different rules per build type
202
+ - `gradle` — build configuration
@@ -0,0 +1,234 @@
1
+ ---
2
+ name: r8
3
+ description: >
4
+ R8 compiler for Android app shrinking, obfuscation, and optimization.
5
+ Load this skill when configuring R8 rules, understanding how R8 differs
6
+ from ProGuard, enabling full mode, troubleshooting R8-related build or
7
+ runtime issues, or optimizing APK/AAB size with R8.
8
+ ---
9
+
10
+ # R8
11
+
12
+ ## Overview
13
+ R8 is Android's default code shrinker, obfuscator, and optimizer — replacing ProGuard since AGP 3.4. R8 runs as part of the build pipeline and performs three tasks in one pass: **shrinking** (removes unused code), **obfuscation** (renames identifiers), and **optimization** (inlines, removes dead branches, optimizes bytecode).
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - R8 is enabled via `isMinifyEnabled = true` — not a separate tool invocation
20
+ - R8 Full Mode (`-fullmode`) is more aggressive — requires more explicit keep rules
21
+ - R8 consumes the same `-keep` rules as ProGuard — existing rules work
22
+ - R8 produces a `mapping.txt` — required for deobfuscating crash stack traces
23
+ - Test release builds — R8 transformations can break reflection-heavy code
24
+
25
+ ---
26
+
27
+ ## Build Configuration
28
+
29
+ ```kotlin
30
+ // ✅ Standard R8 setup
31
+ android {
32
+ buildTypes {
33
+ release {
34
+ isMinifyEnabled = true
35
+ isShrinkResources = true // removes unused resources (requires minify)
36
+ proguardFiles(
37
+ getDefaultProguardFile("proguard-android-optimize.txt"), // base rules
38
+ "proguard-rules.pro" // app-specific rules
39
+ )
40
+ }
41
+ }
42
+
43
+ // ✅ Enable R8 full mode for maximum shrinking
44
+ // Add to gradle.properties:
45
+ // android.enableR8.fullMode=true
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## R8 vs ProGuard
52
+
53
+ | Feature | ProGuard | R8 |
54
+ |---|---|---|
55
+ | Shrinking | ✅ | ✅ |
56
+ | Obfuscation | ✅ | ✅ |
57
+ | Optimization | Basic | Advanced (inlining, constant propagation) |
58
+ | Build speed | Slower | Faster (single pass) |
59
+ | Kotlin support | Limited | Full |
60
+ | Full mode | ❌ | ✅ (opt-in) |
61
+ | Default since | AGP < 3.4 | AGP 3.4+ |
62
+
63
+ ---
64
+
65
+ ## R8 Full Mode
66
+
67
+ ```properties
68
+ # gradle.properties — enables more aggressive shrinking
69
+ android.enableR8.fullMode=true
70
+ ```
71
+
72
+ ```proguard
73
+ # Full mode removes default constructors — keep them explicitly if needed
74
+ -keepclassmembers class com.example.app.data.remote.dto.** {
75
+ <init>(); # keep no-arg constructor for deserialization
76
+ <fields>;
77
+ }
78
+
79
+ # Full mode is stricter about interface default methods
80
+ -keep interface com.example.app.domain.repository.** { *; }
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Essential Keep Rules
86
+
87
+ ```proguard
88
+ # ============================================================
89
+ # Reflection — anything accessed via reflection must be kept
90
+ # ============================================================
91
+ -keepclassmembers class * {
92
+ @com.google.gson.annotations.SerializedName <fields>;
93
+ }
94
+
95
+ # ============================================================
96
+ # kotlinx.serialization
97
+ # ============================================================
98
+ -keepattributes *Annotation*, InnerClasses
99
+ -keepclasseswithmembers class * {
100
+ @kotlinx.serialization.Serializable *;
101
+ }
102
+
103
+ # ============================================================
104
+ # Preserve line numbers for crash reports
105
+ # ============================================================
106
+ -keepattributes SourceFile,LineNumberTable
107
+ -renamesourcefileattribute SourceFile
108
+
109
+ # ============================================================
110
+ # Keep generic signatures (needed by Retrofit)
111
+ # ============================================================
112
+ -keepattributes Signature
113
+
114
+ # ============================================================
115
+ # Native methods
116
+ # ============================================================
117
+ -keepclasseswithmembernames class * {
118
+ native <methods>;
119
+ }
120
+
121
+ # ============================================================
122
+ # Custom views (used in XML layouts)
123
+ # ============================================================
124
+ -keep public class * extends android.view.View {
125
+ public <init>(android.content.Context);
126
+ public <init>(android.content.Context, android.util.AttributeSet);
127
+ public <init>(android.content.Context, android.util.AttributeSet, int);
128
+ }
129
+
130
+ # ============================================================
131
+ # Suppress warnings for known-safe libraries
132
+ # ============================================================
133
+ -dontwarn kotlin.reflect.jvm.internal.**
134
+ -dontwarn org.slf4j.**
135
+ ```
136
+
137
+ ---
138
+
139
+ ## R8 Optimization Examples
140
+
141
+ ```kotlin
142
+ // R8 inlines small functions — no performance penalty for utility wrappers
143
+ // Before optimization:
144
+ fun isValidEmail(email: String) = email.contains("@")
145
+
146
+ // R8 may inline this at call sites:
147
+ if (isValidEmail(input)) { ... }
148
+ // → if (input.contains("@")) { ... }
149
+
150
+ // R8 removes unreachable code:
151
+ if (BuildConfig.DEBUG) {
152
+ Log.d(TAG, "Debug only") // removed entirely in release build
153
+ }
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Checking What R8 Removed
159
+
160
+ ```bash
161
+ # ✅ Check which classes/methods were removed
162
+ # build/outputs/mapping/release/usage.txt — lists removed code
163
+
164
+ # ✅ Check final APK contents
165
+ # Android Studio → Build → Analyze APK
166
+
167
+ # ✅ R8 produces these files in build/outputs/mapping/release/:
168
+ # mapping.txt — obfuscated → original name mapping
169
+ # seeds.txt — classes/members that matched -keep rules
170
+ # usage.txt — code removed by shrinking
171
+ # configuration.txt — merged ProGuard rules applied
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Library AAR Keep Rules
177
+
178
+ ```proguard
179
+ # ✅ If publishing an AAR library, define consumer rules
180
+ # In library module: src/main/proguard-consumer-rules.pro
181
+ # These are automatically applied to apps that use the library
182
+
183
+ -keep public class com.example.mylibrary.PublicApi { *; }
184
+ -keep public interface com.example.mylibrary.Callback { *; }
185
+ ```
186
+
187
+ ```kotlin
188
+ // ✅ Reference consumer rules in library build.gradle.kts
189
+ android {
190
+ defaultConfig {
191
+ consumerProguardFiles("proguard-consumer-rules.pro")
192
+ }
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Troubleshooting Checklist
199
+
200
+ ```
201
+ R8 build succeeds but app crashes at runtime:
202
+ 1. Check logcat for ClassNotFoundException, NoSuchMethodException
203
+ 2. Add -keep rule for the missing class/method
204
+ 3. Rebuild and test again
205
+
206
+ R8 build fails:
207
+ 1. Check build output for "R8: error" messages
208
+ 2. Look for conflicting keep rules
209
+ 3. Try disabling full mode temporarily
210
+
211
+ APK too large after R8:
212
+ 1. Enable isShrinkResources = true
213
+ 2. Check if -keep rules are too broad
214
+ 3. Use Android Studio APK Analyzer to identify large classes
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Anti-Patterns
220
+
221
+ - `isMinifyEnabled = false` in release — ships unoptimized, unobfuscated code
222
+ - Broad `-keep com.example.app.** { *; }` rules — keeps entire package, defeats shrinking
223
+ - Not saving `mapping.txt` from each release — crashes become undecodable
224
+ - Only testing debug builds — R8 transformations only apply in release
225
+ - Using ProGuard when R8 is available — R8 is faster and more capable
226
+
227
+ ---
228
+
229
+ ## Related Skills
230
+ - `obfuscation` — obfuscation rules and strategy
231
+ - `proguard` — ProGuard rules reference for older setups
232
+ - `build-variant` — managing release/debug build types
233
+ - `gradle` — build configuration
234
+ - `reverse-engineering-resistance` — combining R8 with other protections
@@ -0,0 +1,267 @@
1
+ ---
2
+ name: reverse-engineering-resistance
3
+ description: >
4
+ Reverse engineering resistance for Android apps.
5
+ Load this skill when designing a defense-in-depth security strategy,
6
+ combining multiple anti-tampering measures, protecting sensitive algorithms,
7
+ implementing APK integrity checks, or hardening an app against static analysis.
8
+ ---
9
+
10
+ # Reverse Engineering Resistance
11
+
12
+ ## Overview
13
+ Reverse engineering resistance is not a single technique — it's a layered strategy. Attackers use static analysis (decompiling the APK), dynamic analysis (runtime hooks, Frida), and debugging. No single measure stops a determined attacker, but raising the cost and complexity of an attack is a meaningful defense.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - **Defense in depth** — layer multiple techniques; no single measure is sufficient
20
+ - **Detect and respond** — detect analysis attempts and fail-secure
21
+ - **Move secrets server-side** — anything in the APK can be extracted
22
+ - **Obfuscate detection logic** — easy-to-read detection code is easy to bypass
23
+ - **Server-side integrity** — Play Integrity API provides the strongest client attestation
24
+
25
+ ---
26
+
27
+ ## Defense Layers
28
+
29
+ ```
30
+ Layer 1: Build-time protection
31
+ → R8 obfuscation + shrinking
32
+ → String encryption
33
+ → Resource obfuscation
34
+
35
+ Layer 2: Runtime integrity checks
36
+ → APK signature verification
37
+ → Debugger detection
38
+ → Emulator detection
39
+ → Root detection
40
+ → Hook detection (Xposed, Frida)
41
+
42
+ Layer 3: Server-side attestation
43
+ → Play Integrity API
44
+ → Certificate pinning
45
+ → Short-lived tokens
46
+ ```
47
+
48
+ ---
49
+
50
+ ## APK Signature Verification
51
+
52
+ ```kotlin
53
+ // ✅ Verify the app is signed with the expected certificate
54
+ class ApkIntegrityChecker @Inject constructor(
55
+ @ApplicationContext private val context: Context
56
+ ) {
57
+ // Get your signing cert hash:
58
+ // keytool -printcert -file CERT.RSA | grep SHA256
59
+ private val expectedCertHash = "AA:BB:CC:DD:..." // replace with actual hash
60
+
61
+ fun isSignatureValid(): Boolean {
62
+ return try {
63
+ val packageInfo = context.packageManager.getPackageInfo(
64
+ context.packageName,
65
+ PackageManager.GET_SIGNING_CERTIFICATES
66
+ )
67
+ val signingInfo = packageInfo.signingInfo
68
+ val signatures = signingInfo?.apkContentsSigners ?: return false
69
+
70
+ signatures.any { signature ->
71
+ val digest = MessageDigest.getInstance("SHA-256")
72
+ val certHash = digest.digest(signature.toByteArray())
73
+ val hashHex = certHash.joinToString(":") { "%02X".format(it) }
74
+ hashHex == expectedCertHash
75
+ }
76
+ } catch (e: Exception) {
77
+ false
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Debugger Detection
86
+
87
+ ```kotlin
88
+ // ✅ Detect if a debugger is attached
89
+ object DebuggerDetector {
90
+ fun isDebuggerAttached(): Boolean =
91
+ android.os.Debug.isDebuggerConnected() ||
92
+ android.os.Debug.waitingForDebugger()
93
+
94
+ fun isDebuggableBuild(): Boolean =
95
+ BuildConfig.DEBUG ||
96
+ (android.os.Debug.isDebuggerConnected())
97
+
98
+ // ✅ Check android:debuggable in manifest at runtime
99
+ fun isManifestDebuggable(context: Context): Boolean {
100
+ val appInfo = context.applicationInfo
101
+ return (appInfo.flags and android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0
102
+ }
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Emulator Detection
109
+
110
+ ```kotlin
111
+ // ✅ Detect common Android emulators
112
+ object EmulatorDetector {
113
+ fun isEmulator(): Boolean =
114
+ checkBuildProperties() || checkEmulatorFiles() || checkTelephony()
115
+
116
+ private fun checkBuildProperties(): Boolean {
117
+ val indicators = listOf(
118
+ Build.FINGERPRINT.startsWith("generic"),
119
+ Build.FINGERPRINT.startsWith("unknown"),
120
+ Build.MODEL.contains("google_sdk", ignoreCase = true),
121
+ Build.MODEL.contains("Emulator", ignoreCase = true),
122
+ Build.MODEL.contains("Android SDK built for x86", ignoreCase = true),
123
+ Build.MANUFACTURER.contains("Genymotion", ignoreCase = true),
124
+ Build.HARDWARE.contains("goldfish", ignoreCase = true),
125
+ Build.HARDWARE.contains("ranchu", ignoreCase = true),
126
+ Build.PRODUCT.contains("sdk_gphone", ignoreCase = true),
127
+ Build.PRODUCT.contains("vbox86p", ignoreCase = true)
128
+ )
129
+ return indicators.any { it }
130
+ }
131
+
132
+ private fun checkEmulatorFiles(): Boolean {
133
+ val emulatorFiles = listOf(
134
+ "/dev/socket/qemud",
135
+ "/dev/qemu_pipe",
136
+ "/system/lib/libc_malloc_debug_qemu.so",
137
+ "/sys/qemu_trace",
138
+ "/system/bin/qemu-props"
139
+ )
140
+ return emulatorFiles.any { File(it).exists() }
141
+ }
142
+
143
+ private fun checkTelephony(): Boolean {
144
+ // IMEI "000000000000000" is used by many emulators
145
+ return Build.SERIAL == "unknown" || Build.SERIAL == "0"
146
+ }
147
+ }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## String Obfuscation Pattern
153
+
154
+ ```kotlin
155
+ // ✅ Don't store sensitive strings as plain constants
156
+ // ❌ Bad — visible in decompiled APK
157
+ private const val API_SECRET = "my_secret_key_12345"
158
+
159
+ // ✅ Better — obfuscate with simple XOR (raise the bar, not a crypto solution)
160
+ object StringObfuscator {
161
+ private val key = byteArrayOf(0x4A, 0x3F, 0x2E, 0x1D, 0x5C)
162
+
163
+ fun decode(encoded: ByteArray): String {
164
+ return String(ByteArray(encoded.size) { i ->
165
+ (encoded[i].toInt() xor key[i % key.size].toInt()).toByte()
166
+ })
167
+ }
168
+ }
169
+
170
+ // ✅ Best — keep secrets server-side entirely; fetch at runtime with auth
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Tamper Response Strategy
176
+
177
+ ```kotlin
178
+ // ✅ Consolidated tamper check at app startup
179
+ class TamperDetectionService @Inject constructor(
180
+ private val apkIntegrityChecker: ApkIntegrityChecker,
181
+ private val rootDetector: RootDetector,
182
+ private val hookDetector: HookDetector,
183
+ private val fridaDetector: FridaDetector
184
+ ) {
185
+ sealed interface TamperStatus {
186
+ data object Clean : TamperStatus
187
+ data class Compromised(val reasons: List<String>) : TamperStatus
188
+ }
189
+
190
+ suspend fun evaluate(): TamperStatus = withContext(Dispatchers.IO) {
191
+ val reasons = mutableListOf<String>()
192
+
193
+ if (!apkIntegrityChecker.isSignatureValid()) reasons.add("invalid_signature")
194
+ if (DebuggerDetector.isDebuggerAttached()) reasons.add("debugger_attached")
195
+ if (EmulatorDetector.isEmulator()) reasons.add("emulator")
196
+ if (rootDetector.check().isRooted) reasons.add("rooted")
197
+ if (hookDetector.check().isHooked) reasons.add("hooked")
198
+ if (fridaDetector.check().isDetected) reasons.add("frida")
199
+
200
+ if (reasons.isEmpty()) TamperStatus.Clean
201
+ else TamperStatus.Compromised(reasons)
202
+ }
203
+ }
204
+
205
+ // ✅ Response options per risk level
206
+ fun respondToTamper(status: TamperStatus, sensitivity: AppSensitivity) {
207
+ if (status is TamperStatus.Compromised) {
208
+ when (sensitivity) {
209
+ AppSensitivity.HIGH -> {
210
+ // Banking, health: terminate
211
+ showTamperDialog()
212
+ finishAndRemoveTask()
213
+ }
214
+ AppSensitivity.MEDIUM -> {
215
+ // Restrict sensitive features only
216
+ disableSensitiveFeatures()
217
+ logThreatToServer(status.reasons)
218
+ }
219
+ AppSensitivity.LOW -> {
220
+ // Log silently
221
+ logThreatToServer(status.reasons)
222
+ }
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Play Integrity API (Strongest Attestation)
231
+
232
+ ```kotlin
233
+ // ✅ Use Play Integrity for server-verified device integrity
234
+ // The server receives and verifies a signed token from Google
235
+ // Token contains: appIntegrity, deviceIntegrity, accountDetails
236
+
237
+ suspend fun requestIntegrityToken(context: Context, nonce: String): Result<String> =
238
+ runCatching {
239
+ val manager = IntegrityManagerFactory.create(context)
240
+ val request = IntegrityTokenRequest.builder().setNonce(nonce).build()
241
+ manager.requestIntegrityToken(request).await().token()
242
+ }
243
+
244
+ // Server checks:
245
+ // deviceRecognitionVerdict: MEETS_STRONG_INTEGRITY → real unmodified device
246
+ // appIntegrityVerdict: PLAY_RECOGNIZED → APK matches Play store version
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Anti-Patterns
252
+
253
+ - Relying on obfuscation alone — determined attackers can re-analyze obfuscated code
254
+ - Storing API secrets in APK — use server-side secrets with authenticated access
255
+ - Android `debuggable=true` in release builds — allows trivial debugging and memory inspection
256
+ - Single-point detection — check at startup only; also check before each sensitive operation
257
+ - No server-side validation — all client-side checks are bypassable given enough effort
258
+
259
+ ---
260
+
261
+ ## Related Skills
262
+ - `root-detection` — rooted device detection
263
+ - `hook-detection` — Xposed/LSPosed detection
264
+ - `frida-detection` — Frida dynamic instrumentation detection
265
+ - `obfuscation` — R8 obfuscation configuration
266
+ - `certificate-pinning` — network-level protection
267
+ - `cryptography` — protecting sensitive data