@leejungkiin/awkit 1.0.2 → 1.0.4

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.
@@ -5,33 +5,26 @@ skill: smali-to-kotlin
5
5
 
6
6
  # /reverse-android — Android APK Reverse Engineering Workflow
7
7
 
8
- > **Skill được dùng:** `smali-to-kotlin`
9
- > **Tech Stack:** Kotlin + Jetpack Compose + Hilt + Retrofit + Room + Coroutines
8
+ > **Skill:** `smali-to-kotlin` | **Tech:** Kotlin + Compose + Hilt + Retrofit + Room
10
9
  > **Philosophy:** "Read Smali to understand WHAT & WHY → Write Kotlin for HOW"
11
10
 
12
11
  ---
13
12
 
14
13
  ## ⚡ QUICK START
15
14
 
16
- User cung cấp một trong các input sau:
17
- - Đường dẫn thư mục Apktool output
18
- - File `AndroidManifest.xml` (để bắt đầu từ Step 1)
19
- - Nói: "Tôi muốn reverse engineer APK này"
20
-
21
- Workflow sẽ dẫn dắt từng bước — **không bao giờ nhảy cóc**.
15
+ User cung cấp: Apktool output dir, `AndroidManifest.xml`, hoặc nói "reverse engineer APK này".
16
+ Workflow dẫn dắt từng bước — **không bao giờ nhảy cóc**.
22
17
 
23
18
  ---
24
19
 
25
- ## 🔵 Session Setup (Chạy 1 lần khi bắt đầu)
20
+ ## 🔵 Session Setup
26
21
 
27
22
  ### Bước 0.1: Khởi tạo session state
28
23
 
29
- Tạo và track session state trong suốt quá trình:
30
-
31
24
  ```yaml
32
25
  reverse_session:
33
- project_name: "[TBD - lấy từ manifest]"
34
- apktool_dir: "[path user cung cấp]"
26
+ project_name: "[TBD - từ manifest]"
27
+ apktool_dir: "[path]"
35
28
  current_step: 0
36
29
  library_report_done: false
37
30
  manifest_analyzed: false
@@ -42,665 +35,37 @@ reverse_session:
42
35
 
43
36
  ### Bước 0.2: Xác nhận input
44
37
 
45
- Hỏi user (nếu chưa cung cấp):
46
-
47
38
  ```
48
39
  🔧 Android Reverse Engineering bắt đầu!
49
40
 
50
41
  Em cần biết:
51
- 1. Thư mục Apktool output ở đâu? (vd: ~/decompiled/com.example.app/)
52
- 2. Tên app gốc gì? (nếu biết)
53
- 3. Package name original? (vd: com.example.myapp)
54
-
55
- Nếu chưa chạy Apktool, dùng lệnh:
56
- apktool d your-app.apk -o ./decompiled/
57
- ```
58
-
59
- ---
60
-
61
- ## 📦 Step 0: Library Scanner (BẮT BUỘC — Không được bỏ qua)
62
-
63
- > **Mục tiêu:** Nhận diện toàn bộ thư viện trước khi code bất kỳ thứ gì.
64
- > **Reference:** `skills/smali-to-kotlin/library-patterns.md`
65
-
66
- ### Bước 0.3: Quét Smali directories
67
-
68
- User chạy lệnh sau hoặc AI đọc cấu trúc thư mục:
69
-
70
- ```bash
71
- # Liệt kê top-level packages trong smali/
72
- find [apktool_dir]/smali -maxdepth 3 -type d | sed 's|[apktool_dir]/smali/||' | sort
73
-
74
- # Multi-dex apps (smali_classes2, smali_classes3...)
75
- find [apktool_dir] -name "smali*" -maxdepth 1 -type d
76
- find [apktool_dir]/smali_classes2 -maxdepth 3 -type d 2>/dev/null | sort
77
-
78
- # Native libraries
79
- find [apktool_dir]/lib -name "*.so" 2>/dev/null
80
-
81
- # Assets
82
- ls [apktool_dir]/assets/ 2>/dev/null
83
- ```
84
-
85
- ### Bước 0.4: Phân tích và tạo Library Detection Report
86
-
87
- Dùng patterns từ `library-patterns.md`, phân loại từng package:
88
-
89
- ```markdown
90
- ## 📦 Library Detection Report — [App Name]
91
-
92
- ### ✅ Reuse (Thêm vào build.gradle)
93
- | Library | Package Detected | Recommended Version | Notes |
94
- |---------|-----------------|--------------------|----|
95
- | Retrofit | com/squareup/retrofit2 | 2.9.0 | Keep |
96
- | OkHttp | com/squareup/okhttp3 | 4.12.0 | Keep |
97
- | [...] | [...] | [...] | [...] |
98
-
99
- ### 🔄 Replace (Legacy — cần đổi)
100
- | Old Library | Package Detected | Modern Replacement |
101
- |-------------|-----------------|-------------------|
102
- | Volley | com/android/volley | Retrofit + OkHttp |
103
- | AsyncTask | android.os.AsyncTask | Coroutines |
104
- | [...] | [...] | [...] |
105
-
106
- ### 🔵 Firebase/Google SDKs
107
- | SDK | Package Detected | Action |
108
- |-----|-----------------|--------|
109
- | Firebase Analytics | com/google/firebase/analytics | Add latest |
110
- | [...] | [...] | [...] |
111
-
112
- ### 📱 Native (.so) — Giữ nguyên
113
- | File | Architecture | Notes |
114
- |------|-------------|-------|
115
- | lib*.so | arm64-v8a | JNI bridge needed |
116
-
117
- ### 🏷️ App Code (Rebuild in Kotlin)
118
- | Package | Estimated Module |
119
- |---------|-----------------|
120
- | com/example/app/ui | Presentation layer |
121
- | com/example/app/data | Data layer |
122
-
123
- ### ❓ Unknown Packages (Cần điều tra thêm)
124
- | Package | Path | Possible Library |
125
- |---------|------|-----------------|
126
- | [...] | [...] | Custom? |
127
- ```
128
-
129
- ### Bước 0.5: User review và approve report
130
-
131
- ```
132
- 📦 Library Report đã sẵn sàng!
133
-
134
- Anh review và xác nhận:
135
- ✅ Danh sách "Reuse" có đúng không?
136
- 🔄 Có thư viện nào trong "Replace" mà anh muốn giữ không?
137
-
138
- Sau khi anh OK, em sẽ bắt đầu Step 1 (Manifest Analysis).
139
- ```
140
-
141
- > **GATE:** Không tiếp tục Step 1 khi chưa có user approval report.
142
-
143
- ---
144
-
145
- ## 📄 Step 1: AndroidManifest Analysis & Project Bootstrap
146
-
147
- > **Input:** `[apktool_dir]/AndroidManifest.xml`
148
- > **Reference:** `skills/smali-to-kotlin/SKILL.md` → Step 1
149
-
150
- ### Bước 1.1: Đọc và phân tích AndroidManifest.xml
151
-
152
- User cung cấp nội dung file hoặc AI đọc từ path. Trích xuất:
153
-
154
- ```yaml
155
- extract:
156
- - application_id: "com.example.app"
157
- - package_name: "com.example.app"
158
- - min_sdk: 21
159
- - target_sdk: 34
160
- - permissions:
161
- network: [INTERNET, ACCESS_NETWORK_STATE]
162
- storage: [READ_EXTERNAL_STORAGE]
163
- camera: [CAMERA]
164
- location: []
165
- other: []
166
- - entry_points:
167
- application_class: "com.example.app.MyApp"
168
- splash_activity: "com.example.app.SplashActivity"
169
- main_activity: "com.example.app.MainActivity"
170
- - components:
171
- activities: [list]
172
- services: [list]
173
- receivers: [list]
174
- providers: [list]
175
- - deep_links: [list of intent-filters with schemes]
176
- - features: [uses-feature list]
177
- ```
178
-
179
- ### Bước 1.2: Đề xuất project structure
180
-
181
- Xuất Clean Architecture structure dựa trên manifest analysis (xem template trong SKILL.md Step 1).
182
-
183
- Mapping activities → Compose screens:
184
-
185
- ```
186
- SplashActivity → presentation/screens/splash/SplashScreen.kt
187
- MainActivity → presentation/screens/main/MainScreen.kt
188
- LoginActivity → presentation/screens/auth/LoginScreen.kt
189
- [...]
190
- ```
191
-
192
- ### Bước 1.3: Tạo `build.gradle.kts` skeleton
193
-
194
- ```kotlin
195
- // app/build.gradle.kts
196
- plugins {
197
- alias(libs.plugins.android.application)
198
- alias(libs.plugins.kotlin.android)
199
- alias(libs.plugins.kotlin.compose)
200
- alias(libs.plugins.hilt.android)
201
- alias(libs.plugins.ksp)
202
- alias(libs.plugins.kotlin.serialization)
203
- }
204
-
205
- android {
206
- namespace = "[package_name]"
207
- compileSdk = [target_sdk]
208
-
209
- defaultConfig {
210
- applicationId = "[application_id]"
211
- minSdk = [min_sdk]
212
- targetSdk = [target_sdk]
213
- versionCode = 1
214
- versionName = "1.0.0"
215
- }
216
-
217
- buildFeatures {
218
- compose = true
219
- buildConfig = true
220
- }
221
- }
222
-
223
- dependencies {
224
- // Jetpack Compose BOM
225
- val composeBom = platform(libs.androidx.compose.bom)
226
- implementation(composeBom)
227
- implementation(libs.androidx.compose.ui)
228
- implementation(libs.androidx.compose.material3)
229
- implementation(libs.androidx.activity.compose)
230
- implementation(libs.androidx.lifecycle.viewmodel.compose)
231
- implementation(libs.androidx.navigation.compose)
232
-
233
- // Coroutines
234
- implementation(libs.kotlinx.coroutines.android)
235
-
236
- // Hilt DI
237
- implementation(libs.hilt.android)
238
- ksp(libs.hilt.compiler)
239
- implementation(libs.androidx.hilt.navigation.compose)
240
-
241
- // Network (từ Library Report)
242
- implementation(libs.retrofit)
243
- implementation(libs.okhttp)
244
- implementation(libs.okhttp.logging)
245
- implementation(libs.kotlinx.serialization.json)
246
-
247
- // Local Storage (từ Library Report)
248
- implementation(libs.room.runtime)
249
- implementation(libs.room.ktx)
250
- ksp(libs.room.compiler)
251
- implementation(libs.datastore.preferences)
252
-
253
- // Image Loading
254
- implementation(libs.coil.compose)
255
-
256
- // Logging
257
- implementation(libs.timber)
258
-
259
- // [Thêm các libs từ Library Report "Reuse" section]
260
- }
261
- ```
262
-
263
- ### ✅ Checkpoint Step 1
264
-
265
- ```markdown
266
- ## ✅ Step 1 Complete: Manifest Analysis & Bootstrap
267
-
268
- ### Extracted:
269
- - Package: [package_name]
270
- - Entry points: [list]
271
- - Permissions: [count] total
272
- - Screens to rebuild: [list from activities]
273
-
274
- ### Created:
275
- - Project structure proposal
276
- - build.gradle.kts skeleton
277
-
278
- ### ⏭️ Next: Step 2 — Data Layer Reconstruction
279
- - Hãy cung cấp Smali files cho: API calls, network models, database queries
280
- - Folders thường có: smali/[package]/network/, smali/[package]/model/, smali/[package]/data/
281
- ```
282
-
283
- ---
284
-
285
- ## 💾 Step 2: Data Layer Reconstruction
286
-
287
- > **Input:** Smali files cho network, models, database logic
288
- > **Reference:** `skills/smali-to-kotlin/SKILL.md` → Step 2
289
- > **Reading help:** `skills/smali-to-kotlin/smali-reading-guide.md`
290
-
291
- ### Bước 2.1: Network Layer
292
-
293
- Từ Smali, trích xuất và tạo:
294
-
295
- ```kotlin
296
- // data/remote/api/[Feature]Api.kt
297
- interface UserApi {
298
- @GET("users/{id}")
299
- suspend fun getUser(@Path("id") id: String): UserDto
300
-
301
- @POST("auth/login")
302
- suspend fun login(@Body request: LoginRequest): TokenDto
303
- }
304
- ```
305
-
306
- ### Bước 2.2: DTOs (Data Transfer Objects)
307
-
308
- ```kotlin
309
- // data/remote/dto/UserDto.kt
310
- @Serializable
311
- data class UserDto(
312
- @SerialName("user_id") val userId: String,
313
- @SerialName("full_name") val fullName: String,
314
- @SerialName("email") val email: String,
315
- // map từ Smali fields
316
- )
317
- ```
318
-
319
- ### Bước 2.3: Room Database (nếu app có local DB)
320
-
321
- ```kotlin
322
- // data/local/entity/UserEntity.kt
323
- @Entity(tableName = "users")
324
- data class UserEntity(
325
- @PrimaryKey val id: String,
326
- val name: String,
327
- val email: String
328
- )
329
-
330
- // data/local/dao/UserDao.kt
331
- @Dao
332
- interface UserDao {
333
- @Query("SELECT * FROM users WHERE id = :id")
334
- fun getUserById(id: String): Flow<UserEntity?>
335
-
336
- @Insert(onConflict = OnConflictStrategy.REPLACE)
337
- suspend fun insert(user: UserEntity)
338
- }
339
- ```
340
-
341
- ### Bước 2.4: Repository
42
+ 1. Thư mục Apktool output ở đâu?
43
+ 2. Tên app gốc? Package name?
342
44
 
343
- ```kotlin
344
- // domain/repository/UserRepository.kt (interface)
345
- interface UserRepository {
346
- fun getUser(id: String): Flow<Result<User>>
347
- suspend fun login(email: String, password: String): Result<Token>
348
- }
349
-
350
- // data/repository/UserRepositoryImpl.kt (implementation)
351
- @Singleton
352
- class UserRepositoryImpl @Inject constructor(
353
- private val api: UserApi,
354
- private val dao: UserDao
355
- ) : UserRepository {
356
- override fun getUser(id: String): Flow<Result<User>> = flow {
357
- // offline-first pattern
358
- }
359
- }
360
- ```
361
-
362
- ### ✅ Checkpoint Step 2
363
-
364
- ```markdown
365
- ## ✅ Step 2 Complete: Data Layer
366
-
367
- ### Created:
368
- - API interfaces: [list]
369
- - DTOs: [list]
370
- - Room entities + DAOs: [list if applicable]
371
- - Repositories: [list]
372
-
373
- ### Decisions:
374
- - [Key decisions documented]
375
-
376
- ### ⏭️ Next: Step 3 — Core Logic & Utils
377
- - Cung cấp Smali cho: encryption, hashing, date formatting, custom algorithms
45
+ Chưa chạy Apktool? → apktool d your-app.apk -o ./decompiled/
378
46
  ```
379
47
 
380
48
  ---
381
49
 
382
- ## 🧮 Step 3: Core Logic & Utils Reconstruction
383
-
384
- > **Input:** Smali for encryption, hashing, utils
385
- > **CRITICAL:** Output phải match 100% với app gốc
386
-
387
- ### Bước 3.1: Nhận diện utils cần rebuild
388
-
389
- Tìm trong Smali:
390
- ```
391
- - javax/crypto/Cipher → AES/DES encryption
392
- - java/security/MessageDigest → MD5/SHA hashing
393
- - android/util/Base64 → Base64 encoding
394
- - Custom loops với XOR, shift → custom obfuscation
395
- ```
396
-
397
- ### Bước 3.2: Tái tạo thành Kotlin objects
398
-
399
- ```kotlin
400
- // util/CryptoUtils.kt
401
- object CryptoUtils {
402
- fun hashMd5(input: String): String {
403
- val md = MessageDigest.getInstance("MD5")
404
- val digest = md.digest(input.toByteArray())
405
- return digest.joinToString("") { "%02x".format(it) }
406
- }
50
+ ## 📋 Pipeline Overview (7 Steps)
407
51
 
408
- fun encryptAes(data: String, key: String): String {
409
- val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
410
- // ... implement from Smali logic ...
411
- }
412
- }
413
- ```
52
+ | Step | Phase | Sub-workflow | Gate |
53
+ |------|-------|-------------|------|
54
+ | 0 | 📦 Library Scanner | [`/re-android-scan`](reverse-android-scan.md) | User approve report |
55
+ | 1 | 📄 Manifest & Bootstrap | [`/re-android-scan`](reverse-android-scan.md) | Checkpoint |
56
+ | 2 | 💾 Data Layer | [`/re-android-build`](reverse-android-build.md) | Checkpoint |
57
+ | 3 | 🧮 Core Logic & Utils | [`/re-android-build`](reverse-android-build.md) | Checkpoint |
58
+ | 4 | 🎨 UI & ViewModel | [`/re-android-build`](reverse-android-build.md) | Per-screen loop |
59
+ | 5 | 📦 SDK Integration | [`/re-android-build`](reverse-android-build.md) | Checkpoint |
60
+ | 6 | ✅ Parity Check | [`/re-android-build`](reverse-android-build.md) | Final QA |
414
61
 
415
- ### Bước 3.3: Unit Test verification
62
+ ### Execution Flow
416
63
 
417
- ```kotlin
418
- // Luôn tạo unit test cho crypto/hash functions!
419
- class CryptoUtilsTest {
420
- @Test
421
- fun `md5 hash matches original`() {
422
- // Test với known input/output từ app gốc
423
- assertEquals("expected_hash", CryptoUtils.hashMd5("test_input"))
424
- }
425
- }
426
64
  ```
427
-
428
- ### ✅ Checkpoint Step 3
429
-
430
- ---
431
-
432
- ## 🎨 Step 4: UI & ViewModel Reconstruction (Per Screen — Lặp lại)
433
-
434
- > **Input:** `res/layout/layout_xxx.xml` + Activity/Fragment Smali
435
- > **Lặp lại** cho MỌI màn hình trong danh sách từ Step 1
436
- > **Reference:** `skills/smali-to-kotlin/SKILL.md` → Step 4
437
-
438
- ### Bước 4.0: Chọn màn hình (theo thứ tự ưu tiên)
439
-
65
+ Session Setup → Step 0+1 (/re-android-scan) → Step 2-6 (/re-android-build)
440
66
  ```
441
- Thứ tự rebuild đề nghị:
442
- 1. SplashScreen (đơn giản nhất)
443
- 2. Auth screens (Login, Register, Forgot Password)
444
- 3. Main/Home screen
445
- 4. Detail screens
446
- 5. Settings / Profile
447
- ```
448
-
449
- ### Bước 4.1: Resource Extraction (On-Demand)
450
-
451
- Chỉ copy resources của màn hình này:
452
-
453
- ```markdown
454
- ### Resources cần thiết cho [ScreenName]:
455
- - Drawables: [ic_logo.xml, bg_login.png, ...]
456
- - Strings: [login_title, email_hint, password_hint, ...]
457
- - Colors: [primary_color, background_color, ...]
458
- - Dimens: [margin_standard, text_size_title, ...]
459
- - Fonts: [inter_regular.ttf, ...]
460
- ```
461
-
462
- ### Bước 4.2: XML Layout → Compose Migration
463
-
464
- Đọc layout XML, convert sang Compose composables:
465
-
466
- ```kotlin
467
- // presentation/screens/[screen]/[Screen]Screen.kt
468
- @Composable
469
- fun LoginScreen(
470
- viewModel: LoginViewModel = hiltViewModel(),
471
- onNavigateToHome: () -> Unit
472
- ) {
473
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
474
- val snackbarHostState = remember { SnackbarHostState() }
475
-
476
- LaunchedEffect(Unit) {
477
- viewModel.events.collectLatest { event ->
478
- when (event) {
479
- is LoginEvent.NavigateToHome -> onNavigateToHome()
480
- is LoginEvent.ShowError -> snackbarHostState.showSnackbar(event.message)
481
- }
482
- }
483
- }
484
-
485
- Scaffold(snackbarHost = { SnackbarHost(snackbarHostState) }) { padding ->
486
- LoginContent(
487
- uiState = uiState,
488
- onEmailChange = viewModel::onEmailChange,
489
- onPasswordChange = viewModel::onPasswordChange,
490
- onLoginClick = viewModel::login,
491
- modifier = Modifier.padding(padding)
492
- )
493
- }
494
- }
495
- ```
496
-
497
- ### Bước 4.3: ViewModel
498
-
499
- ```kotlin
500
- // presentation/screens/[screen]/[Screen]ViewModel.kt
501
- @HiltViewModel
502
- class LoginViewModel @Inject constructor(
503
- private val loginUseCase: LoginUseCase
504
- ) : ViewModel() {
505
-
506
- private val _uiState = MutableStateFlow(LoginUiState())
507
- val uiState: StateFlow<LoginUiState> = _uiState.asStateFlow()
508
-
509
- private val _events = MutableSharedFlow<LoginEvent>()
510
- val events: SharedFlow<LoginEvent> = _events.asSharedFlow()
511
-
512
- fun login() {
513
- viewModelScope.launch {
514
- _uiState.update { it.copy(isLoading = true) }
515
- loginUseCase(uiState.value.email, uiState.value.password)
516
- .onSuccess { _events.emit(LoginEvent.NavigateToHome) }
517
- .onFailure { _uiState.update { s -> s.copy(error = it.message) } }
518
- _uiState.update { it.copy(isLoading = false) }
519
- }
520
- }
521
- }
522
-
523
- data class LoginUiState(
524
- val email: String = "",
525
- val password: String = "",
526
- val isLoading: Boolean = false,
527
- val error: String? = null
528
- )
529
-
530
- sealed interface LoginEvent {
531
- data object NavigateToHome : LoginEvent
532
- data class ShowError(val message: String) : LoginEvent
533
- }
534
- ```
535
-
536
- ### ✅ Checkpoint Step 4 (Per Screen)
537
-
538
- ```markdown
539
- ## ✅ Step 4 Complete: [ScreenName]
540
-
541
- ### Resources extracted: [list]
542
- ### Files created:
543
- - [ScreenName]Screen.kt
544
- - [ScreenName]ViewModel.kt
545
- ### Next screen: [ScreenName] or Step 5 if all screens done
546
- ```
547
-
548
- > **Loop:** Quay lại Step 4.0 cho màn hình tiếp theo. Hoàn thành tất cả → Step 5.
549
67
 
550
- ---
551
-
552
- ## 📦 Step 5: Third-party SDK & Native Library Integration
553
-
554
- > **Input:** Library Report từ Step 0 (Approved Libraries)
555
-
556
- ### Bước 5.1: Native Libraries (.so)
557
-
558
- ```kotlin
559
- // Declare JNI bridge for each .so file
560
- class NativeBridge {
561
- companion object {
562
- init {
563
- System.loadLibrary("library_name")
564
- }
565
- }
566
-
567
- // Match exact C/C++ function signatures from .so
568
- external fun nativeMethod(param: String): ByteArray
569
- external fun nativeVersion(): String
570
- }
571
- ```
572
-
573
- ### Bước 5.2: Application class setup
574
-
575
- ```kotlin
576
- // App.kt
577
- @HiltAndroidApp
578
- class App : Application() {
579
- override fun onCreate() {
580
- super.onCreate()
581
- setupTimber()
582
- setupFirebase()
583
- }
584
-
585
- private fun setupTimber() {
586
- if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
587
- else Timber.plant(CrashReportingTree())
588
- }
589
-
590
- private fun setupFirebase() {
591
- // Firebase auto-initializes via manifest
592
- // Manual config if needed:
593
- // FirebaseApp.initializeApp(this)
594
- }
595
- }
596
- ```
597
-
598
- ### Bước 5.3: Hilt modules cho SDK dependencies
599
-
600
- ```kotlin
601
- // di/NetworkModule.kt
602
- @Module
603
- @InstallIn(SingletonComponent::class)
604
- object NetworkModule {
605
- @Provides @Singleton
606
- fun provideOkHttpClient(): OkHttpClient =
607
- OkHttpClient.Builder()
608
- .addInterceptor(AuthInterceptor())
609
- .addInterceptor(HttpLoggingInterceptor().apply {
610
- level = if (BuildConfig.DEBUG) BODY else NONE
611
- })
612
- .build()
613
-
614
- @Provides @Singleton
615
- fun provideRetrofit(okHttp: OkHttpClient): Retrofit =
616
- Retrofit.Builder()
617
- .baseUrl(BuildConfig.BASE_URL)
618
- .client(okHttp)
619
- .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
620
- .build()
621
- }
622
- ```
623
-
624
- ### ✅ Checkpoint Step 5
625
-
626
- ---
627
-
628
- ## ✅ Step 6: Parity Check & Quality Gate
629
-
630
- > **Mục tiêu:** Đảm bảo app mới hoạt động giống 100% app gốc
631
-
632
- ### Bước 6.1: Branch coverage từ Smali
633
-
634
- Tạo test checklist từ các `if-else` / `when` tìm thấy trong Smali:
635
-
636
- ```markdown
637
- ### Edge Cases cần test (từ Smali analysis):
638
- - [ ] Login với email trống
639
- - [ ] Login với password sai > 3 lần
640
- - [ ] Network timeout handling
641
- - [ ] Empty list state
642
- - [ ] Null response from server
643
- - [ ] App lifecycle (background/foreground)
644
- - [ ] [Custom cases từ specific Smali branches]
645
- ```
646
-
647
- ### Bước 6.2: API Parity verification
648
-
649
- ```
650
- Checklist:
651
- - [ ] Base URL matches original
652
- - [ ] Request headers identical (User-Agent, auth tokens, etc.)
653
- - [ ] Request body format matches (JSON field names, encoding)
654
- - [ ] Response parsing correct (all fields mapped)
655
- - [ ] Error responses handled
656
- ```
657
-
658
- ### Bước 6.3: Data parity
659
-
660
- ```
661
- Checklist:
662
- - [ ] Encryption output matches for same input
663
- - [ ] Hash values match for same input
664
- - [ ] Date/time formatting matches locale
665
- - [ ] Local storage read/write works correctly
666
- ```
667
-
668
- ### Bước 6.4: Build và test
669
-
670
- ```bash
671
- # Debug build
672
- ./gradlew assembleDebug
673
-
674
- # Unit tests
675
- ./gradlew test
676
-
677
- # Lint
678
- ./gradlew lint
679
- ```
680
-
681
- ### ✅ Final Checkpoint
682
-
683
- ```markdown
684
- ## 🎉 Reverse Engineering Complete!
685
-
686
- ### Summary:
687
- - Screens rebuilt: [count]
688
- - Libraries reused: [count]
689
- - Libraries replaced: [count]
690
- - Native libs integrated: [count]
691
-
692
- ### Test Results:
693
- - Unit tests: [pass/fail]
694
- - Lint: [pass/warnings]
695
-
696
- ### Known Differences from Original:
697
- - [Any intentional or unavoidable differences]
698
-
699
- ### ⏭️ Recommended Next Steps:
700
- 1. `/test` — Chạy full test suite
701
- 2. `/deploy` — Khi sẵn sàng release
702
- 3. `/code-janitor` — Dọn dẹp code trước merge
703
- ```
68
+ **Chạy tuần tự:** Xong `/re-android-scan` → chuyển sang `/re-android-build`.
704
69
 
705
70
  ---
706
71
 
@@ -716,7 +81,7 @@ never_do:
716
81
  - Mass-copy resources from APK (on-demand only)
717
82
  - Use deprecated libraries without replacement plan
718
83
  - Skip parity check for encryption utils
719
- - Proceed to next step without user confirmation at checkpoints
84
+ - Proceed to next step without user confirmation
720
85
 
721
86
  always_do:
722
87
  - Document decisions in session state
@@ -729,12 +94,13 @@ always_do:
729
94
 
730
95
  ## 🔗 Related
731
96
 
97
+ - **Sub-workflows:** [`/re-android-scan`](reverse-android-scan.md) · [`/re-android-build`](reverse-android-build.md)
732
98
  - **Skill:** `smali-to-kotlin` (core knowledge & rules)
733
99
  - **Library DB:** `skills/smali-to-kotlin/library-patterns.md`
734
100
  - **Smali Guide:** `skills/smali-to-kotlin/smali-reading-guide.md`
101
+ - **Sibling:** `/reverse-ios` (iOS counterpart)
735
102
  - **After RE done:** `/test`, `/deploy`, `/code-janitor`
736
- - **Future iOS version:** `smali-to-swift` skill + `/reverse-ios` workflow
737
103
 
738
104
  ---
739
105
 
740
- *reverse-android workflow v1.0.0 — Android APK RE Execution Flow*
106
+ *reverse-android workflow v2.0.0 — Modular RE Pipeline*