From 42d95b8105c3173f42915792ebc101187e88acc9 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 16:55:41 +0200 Subject: [PATCH 01/14] feat: bump Android SDK to 18.3.0 --- library/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 0e34177..911dc0e 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -77,7 +77,7 @@ kotlin { languageSettings.optIn("kotlin.ExperimentalMultiplatform") dependencies{ - implementation("com.aheaditec.talsec.security:TalsecSecurity-Community-KMP:18.0.4") + implementation("com.aheaditec.talsec.security:TalsecSecurity-Community-KMP:18.3.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0") implementation("androidx.startup:startup-runtime:1.2.0") implementation("androidx.annotation:annotation:1.9.1") From ab2cdd20ef388c9e114f1d072046e0f033e75a51 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 16:57:21 +0200 Subject: [PATCH 02/14] feat!: rename reason to reasons in SuspiciousAppInfo --- .../kotlin/com/jetbrains/example/ui/MalwareBottomSheet.kt | 2 +- .../kotlin/utils/malware_data_processor.android.kt | 4 ++-- library/src/commonMain/kotlin/model/suspicious_app_info.kt | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/ui/MalwareBottomSheet.kt b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/ui/MalwareBottomSheet.kt index cce38fb..112081e 100644 --- a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/ui/MalwareBottomSheet.kt +++ b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/ui/MalwareBottomSheet.kt @@ -139,7 +139,7 @@ private fun MalwareAppItem(app: SuspiciousAppInfo) { color = MaterialTheme.colorScheme.onSurfaceVariant, ) Text( - text = "Reason: ${app.reason}", + text = "Reasons: ${app.reasons.joinToString(", ")}", style = MaterialTheme.typography.bodySmall, color = ThreatRed, ) diff --git a/library/src/androidMain/kotlin/utils/malware_data_processor.android.kt b/library/src/androidMain/kotlin/utils/malware_data_processor.android.kt index ac12779..eb8f7aa 100644 --- a/library/src/androidMain/kotlin/utils/malware_data_processor.android.kt +++ b/library/src/androidMain/kotlin/utils/malware_data_processor.android.kt @@ -17,7 +17,7 @@ internal fun processMalwareData( return nativeList.mapNotNull { nativeInfo -> try { val pInfo = nativeInfo.packageInfo - val reason = nativeInfo.reason + val reasons = nativeInfo.reasons val permissions = nativeInfo.permissions val packageName = pInfo.packageName @@ -36,7 +36,7 @@ internal fun processMalwareData( SuspiciousAppInfo( packageInfo = commonPackageInfo, - reason = reason, + reasons = reasons, permissions = permissions ?: emptySet() ) } catch (e: Exception) { diff --git a/library/src/commonMain/kotlin/model/suspicious_app_info.kt b/library/src/commonMain/kotlin/model/suspicious_app_info.kt index 426f58c..8ac458a 100644 --- a/library/src/commonMain/kotlin/model/suspicious_app_info.kt +++ b/library/src/commonMain/kotlin/model/suspicious_app_info.kt @@ -4,12 +4,12 @@ package com.freeraspkmp.model * Contains information about a suspicious app. * * @param packageInfo Information about the suspicious package. - * @param reason The reason why the app is considered suspicious. - * @param permissions A set of suspicious permissions held by the app. Populated when reason is `suspiciousPermission`. + * @param reasons The reasons why the app is considered suspicious. + * @param permissions A set of suspicious permissions held by the app. Populated when reasons contain `suspiciousPermission`. */ data class SuspiciousAppInfo( val packageInfo: PackageInfo, - val reason: String, + val reasons: Set, val permissions: Set = emptySet() ) From 767a41643c7eed9e8b89733be666e102a5756fc6 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 17:00:34 +0200 Subject: [PATCH 03/14] feat!: deprecate old malware config fields --- .../src/androidMain/kotlin/utils/config_mapper.android.kt | 1 + library/src/commonMain/kotlin/model/config/android_config.kt | 1 + library/src/commonMain/kotlin/model/config/malware_config.kt | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index f2e81b3..d84404f 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -4,6 +4,7 @@ import com.aheaditec.talsec_security.security.api.TalsecConfig import com.freeraspkmp.model.config.freeraspConfig import com.freeraspkmp.model.exception.FreeraspKMPException +@Suppress("DEPRECATION") fun freeraspConfig.toNativeConfig(): TalsecConfig { val androidConfig = this.androidConfig ?: throw FreeraspKMPException("AndroidConfig is required on the Android platform but was null.") diff --git a/library/src/commonMain/kotlin/model/config/android_config.kt b/library/src/commonMain/kotlin/model/config/android_config.kt index 2d4eb6b..98b1a65 100644 --- a/library/src/commonMain/kotlin/model/config/android_config.kt +++ b/library/src/commonMain/kotlin/model/config/android_config.kt @@ -12,5 +12,6 @@ data class AndroidConfig( val packageName: String, val certificateHashes: List, val supportedAlternativeStores: List = emptyList(), + @Deprecated("Use SuspiciousAppDetectionConfig instead") val malwareConfig: MalwareConfig? = null ) diff --git a/library/src/commonMain/kotlin/model/config/malware_config.kt b/library/src/commonMain/kotlin/model/config/malware_config.kt index 30a12d5..c1ccd5a 100644 --- a/library/src/commonMain/kotlin/model/config/malware_config.kt +++ b/library/src/commonMain/kotlin/model/config/malware_config.kt @@ -8,9 +8,14 @@ package com.freeraspkmp.model.config * @param suspiciousPermissions A list of suspicious permission groups. * @param whitelistedInstallationSources A list of whitelisted installation sources. */ +@Deprecated("Use SuspiciousAppDetectionConfig instead") data class MalwareConfig ( + @Deprecated("Use SuspiciousAppDetectionConfig instead") val blacklistedPackageNames: List = emptyList(), + @Deprecated("Use SuspiciousAppDetectionConfig instead") val blacklistedHashes: List = emptyList(), + @Deprecated("Use SuspiciousAppDetectionConfig instead") val suspiciousPermissions: List> = emptyList(), + @Deprecated("Use SuspiciousAppDetectionConfig instead") val whitelistedInstallationSources: List = emptyList() ) \ No newline at end of file From 50f051e85987efa087563402b7f1a6e3b9528d01 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 17:20:03 +0200 Subject: [PATCH 04/14] feat: add SuspiciousAppDetectionConfig to API --- .../kotlin/com/jetbrains/example/App.kt | 6 +-- .../kotlin/utils/config_mapper.android.kt | 45 +++++++++++++++++- .../kotlin/model/config/android_config.kt | 6 ++- .../config/suspicious_app_detection_config.kt | 47 +++++++++++++++++++ 4 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt diff --git a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt index 242f891..9c9999b 100644 --- a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt +++ b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt @@ -12,7 +12,7 @@ import com.freeraspkmp.model.FreeRaspEvent import com.freeraspkmp.model.SuspiciousAppInfo import com.freeraspkmp.model.config.AndroidConfig import com.freeraspkmp.model.config.IOSConfig -import com.freeraspkmp.model.config.MalwareConfig +import com.freeraspkmp.model.config.SuspiciousAppDetectionConfig import com.freeraspkmp.model.config.freeraspConfig import com.jetbrains.example.model.initialChecks import com.jetbrains.example.model.toCheckId @@ -33,8 +33,8 @@ fun App() { androidConfig = AndroidConfig( packageName = "com.jetbrains.example", certificateHashes = listOf("K/iFV7+CypnATFWcrUVM6aUIB5gnU2xwzRJOiKJJqPw="), - malwareConfig = MalwareConfig( - blacklistedPackageNames = listOf("com.google.android.youtube") + suspiciousAppDetectionConfig = SuspiciousAppDetectionConfig( + packageNames = listOf("com.google.android.youtube") ) ), iosConfig = IOSConfig( diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index d84404f..0ac7e29 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -1,8 +1,16 @@ package com.freeraspkmp.android.utils import com.aheaditec.talsec_security.security.api.TalsecConfig +import com.freeraspkmp.model.config.MalwareScanScope +import com.freeraspkmp.model.config.ReasonMode +import com.freeraspkmp.model.config.ScopeType +import com.freeraspkmp.model.config.SuspiciousAppDetectionConfig import com.freeraspkmp.model.config.freeraspConfig import com.freeraspkmp.model.exception.FreeraspKMPException +import com.aheaditec.talsec_security.security.api.SuspiciousAppDetectionConfig as NativeSuspiciousAppDetectionConfig +import com.aheaditec.talsec_security.security.api.MalwareScanScope as NativeMalwareScanScope +import com.aheaditec.talsec_security.security.api.ScopeType as NativeScopeType +import com.aheaditec.talsec_security.security.api.ReasonMode as NativeReasonMode @Suppress("DEPRECATION") fun freeraspConfig.toNativeConfig(): TalsecConfig { @@ -44,7 +52,42 @@ fun freeraspConfig.toNativeConfig(): TalsecConfig { whitelistedInstallationSources(malware.whitelistedInstallationSources.toTypedArray()) } } + + androidConfig.suspiciousAppDetectionConfig?.let { + suspiciousAppDetection(it.toNative()) + } } return builder.build() -} \ No newline at end of file +} + +internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetectionConfig = + NativeSuspiciousAppDetectionConfig( + packageNames = packageNames?.toSet(), + hashes = hashes?.toSet(), + requestedPermissions = requestedPermissions?.map { it.toSet() }?.toSet(), + grantedPermissions = grantedPermissions?.map { it.toSet() }?.toSet(), + malwareScanScope = malwareScanScope?.toNative(), + reasonMode = reasonMode?.toNative() + ) + +internal fun MalwareScanScope.toNative(): NativeMalwareScanScope = + NativeMalwareScanScope( + scanScope = scanScope.toNative(), + trustedInstallSources = trustedInstallSources?.toSet() + ) + +internal fun ScopeType.toNative(): NativeScopeType = + when (this) { + ScopeType.SIDELOADED_ONLY -> NativeScopeType.SIDELOADED_ONLY + ScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM -> NativeScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM + ScopeType.SIDELOADED_AND_OEM -> NativeScopeType.SIDELOADED_AND_OEM + ScopeType.SIDELOADED_AND_SYSTEM_AND_OEM -> NativeScopeType.SIDELOADED_AND_SYSTEM_AND_OEM + ScopeType.ALL -> NativeScopeType.ALL + } + +internal fun ReasonMode.toNative(): NativeReasonMode = + when (this) { + ReasonMode.ALL -> NativeReasonMode.ALL + ReasonMode.HIGHEST_CONFIDENCE -> NativeReasonMode.HIGHEST_CONFIDENCE + } diff --git a/library/src/commonMain/kotlin/model/config/android_config.kt b/library/src/commonMain/kotlin/model/config/android_config.kt index 98b1a65..8cb7084 100644 --- a/library/src/commonMain/kotlin/model/config/android_config.kt +++ b/library/src/commonMain/kotlin/model/config/android_config.kt @@ -6,12 +6,14 @@ package com.freeraspkmp.model.config * @param packageName The expected package name of the app. * @param certificateHashes A list of expected certificate hashes in base64. * @param supportedAlternativeStores A list of package names for supported alternative stores. - * @param malwareConfig Configuration for malware detection. + * @param malwareConfig Deprecated. Use [suspiciousAppDetectionConfig] instead. + * @param suspiciousAppDetectionConfig Configuration for malware detection. */ data class AndroidConfig( val packageName: String, val certificateHashes: List, val supportedAlternativeStores: List = emptyList(), @Deprecated("Use SuspiciousAppDetectionConfig instead") - val malwareConfig: MalwareConfig? = null + val malwareConfig: MalwareConfig? = null, + val suspiciousAppDetectionConfig: SuspiciousAppDetectionConfig? = null ) diff --git a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt new file mode 100644 index 0000000..08ee18c --- /dev/null +++ b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt @@ -0,0 +1,47 @@ +package com.freeraspkmp.model.config + +/** + * Scope of installed apps included in the malware scan. + */ +enum class ScopeType { + SIDELOADED_ONLY, + SIDELOADED_AND_SYSTEM_EXCLUDE_OEM, + SIDELOADED_AND_OEM, + SIDELOADED_AND_SYSTEM_AND_OEM, + ALL +} + +/** + * Controls how detection reasons are reported on a suspicious app. + */ +enum class ReasonMode { ALL, HIGHEST_CONFIDENCE } + +/** + * Defines which installed apps should be scanned for malware. + * + * @param scanScope The set of apps to include in the scan. + * @param trustedInstallSources Installation sources whose apps should be excluded from the scan. + */ +data class MalwareScanScope( + val scanScope: ScopeType, + val trustedInstallSources: List? = null +) + +/** + * Configuration for malware detection. Replaces [MalwareConfig]. + * + * @param packageNames Package names of known malicious apps. + * @param hashes Certificate hashes of known malicious apps. + * @param requestedPermissions Groups of permissions an app must request to be flagged as suspicious. + * @param grantedPermissions Groups of permissions an app must be granted to be flagged as suspicious. + * @param malwareScanScope Defines which apps are scanned. + * @param reasonMode Controls how detection reasons are reported. + */ +data class SuspiciousAppDetectionConfig( + val packageNames: List? = null, + val hashes: List? = null, + val requestedPermissions: List>? = null, + val grantedPermissions: List>? = null, + val malwareScanScope: MalwareScanScope? = null, + val reasonMode: ReasonMode? = null +) From afc8bd1794507803d8e54bb7a798312bef87c0b6 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 17:20:49 +0200 Subject: [PATCH 05/14] chore: update changelog for 1.2.0 --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++++++++++++++ library/build.gradle.kts | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6717852..dfdc777 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.0] - 2026-05-07 + +- Android SDK version: 18.3.0 +- iOS SDK version: 6.14.4 + +### Breaking + +- `SuspiciousAppInfo.reason` (String) renamed to `reasons` (Set) +- Value `"blacklist"` in `reasons` renamed to `"blocklist"` + +### Kotlin Multiplatform + +#### Deprecated + +- `blacklistedPackageNames`, `blacklistedHashes`, `suspiciousPermissions`, `whitelistedInstallationSources` are deprecated but remain functional — use `SuspiciousAppDetectionConfig` instead + +### Android + +#### Added + +- Added a new sub-check for `HMA` detection to the root detector +- Added a new sub-check for `KernelSU` detection to the root detector +- Added a new sub-check for `Frida Server` detection to the hook detector +- Added Huawei App Market provider to HMA detection queries +- New API class `SuspiciousAppDetectionConfig` that can be used to configure malware detection +- New API for malware detection configuration in `TalsecConfig`, see `TalsecConfig.Builder#suspiciousAppDetection` + +#### Fixed + +- Fixed `VerifyError` caused by `JaCoCo` bytecode instrumentation +- Fixed a potential cause of crash in the multi-instance detector +- Fixed crash caused by unhandled `SecurityException` thrown by `UsageStatsManager` in root detection +- Fixed manifest merge conflicts in HMA detection providers +- Fixed Java interoperability of `ScreenProtector` methods +- Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0) + +#### Changed + +- Fine-tuned `KernelSU` detection +- Fine-tuned hook detection +- Fine-tuned location spoofing detection +- Modified malware incident log structure for better aggregation +- Old malware configuration API methods in `TalsecConfig.Builder` tagged as deprecated (but remain functional): `blacklistedPackageNames`, `blacklistedHashes`, `suspiciousPermissions`, `whitelistedInstallationSources` + ## [1.1.0] - 2025-03-25 - Android SDK version: 18.0.4 diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 911dc0e..77146af 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -19,7 +19,7 @@ fun getVariable(name: String): String { group = "com.aheaditec.talsec.security" -version = "1.1.0" +version = "1.2.0" kotlin { targets.all { compilations.all { From 3615253484b9b9eb022648d1cf4ddb922d6025a5 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Thu, 7 May 2026 17:25:05 +0200 Subject: [PATCH 06/14] fix: pass trustedInstallSources as List in mapper --- library/src/androidMain/kotlin/utils/config_mapper.android.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index 0ac7e29..3b3b66d 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -74,7 +74,7 @@ internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetecti internal fun MalwareScanScope.toNative(): NativeMalwareScanScope = NativeMalwareScanScope( scanScope = scanScope.toNative(), - trustedInstallSources = trustedInstallSources?.toSet() + trustedInstallSources = trustedInstallSources ) internal fun ScopeType.toNative(): NativeScopeType = From 0b4155cd0ad073520fc7ced53b6c0f4dbe45fb06 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Fri, 15 May 2026 16:51:44 +0200 Subject: [PATCH 07/14] refactor: tighten SuspiciousAppDetectionConfig defaults --- .../src/androidMain/kotlin/utils/config_mapper.android.kt | 4 ++-- .../model/config/suspicious_app_detection_config.kt | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index 3b3b66d..cca97f7 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -67,8 +67,8 @@ internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetecti hashes = hashes?.toSet(), requestedPermissions = requestedPermissions?.map { it.toSet() }?.toSet(), grantedPermissions = grantedPermissions?.map { it.toSet() }?.toSet(), - malwareScanScope = malwareScanScope?.toNative(), - reasonMode = reasonMode?.toNative() + malwareScanScope = malwareScanScope.toNative(), + reasonMode = reasonMode.toNative() ) internal fun MalwareScanScope.toNative(): NativeMalwareScanScope = diff --git a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt index 08ee18c..373833c 100644 --- a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt +++ b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt @@ -28,20 +28,22 @@ data class MalwareScanScope( ) /** - * Configuration for malware detection. Replaces [MalwareConfig]. + * Configuration for malware detection. * * @param packageNames Package names of known malicious apps. * @param hashes Certificate hashes of known malicious apps. * @param requestedPermissions Groups of permissions an app must request to be flagged as suspicious. * @param grantedPermissions Groups of permissions an app must be granted to be flagged as suspicious. * @param malwareScanScope Defines which apps are scanned. + * Defaults to [MalwareScanScope] with [ScopeType.SIDELOADED_ONLY]. * @param reasonMode Controls how detection reasons are reported. + * Defaults to [ReasonMode.HIGHEST_CONFIDENCE]. */ data class SuspiciousAppDetectionConfig( val packageNames: List? = null, val hashes: List? = null, val requestedPermissions: List>? = null, val grantedPermissions: List>? = null, - val malwareScanScope: MalwareScanScope? = null, - val reasonMode: ReasonMode? = null + val malwareScanScope: MalwareScanScope = MalwareScanScope(ScopeType.SIDELOADED_ONLY), + val reasonMode: ReasonMode = ReasonMode.HIGHEST_CONFIDENCE ) From e7c98b77e3dca10ec4afa4d296cb37582aa04288 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Fri, 15 May 2026 16:53:08 +0200 Subject: [PATCH 08/14] feat!: remove deprecated MalwareConfig API --- .../kotlin/utils/config_mapper.android.kt | 24 ------------------- .../kotlin/model/config/android_config.kt | 3 --- .../kotlin/model/config/malware_config.kt | 21 ---------------- 3 files changed, 48 deletions(-) delete mode 100644 library/src/commonMain/kotlin/model/config/malware_config.kt diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index cca97f7..7b64faf 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -12,7 +12,6 @@ import com.aheaditec.talsec_security.security.api.MalwareScanScope as NativeMalw import com.aheaditec.talsec_security.security.api.ScopeType as NativeScopeType import com.aheaditec.talsec_security.security.api.ReasonMode as NativeReasonMode -@Suppress("DEPRECATION") fun freeraspConfig.toNativeConfig(): TalsecConfig { val androidConfig = this.androidConfig ?: throw FreeraspKMPException("AndroidConfig is required on the Android platform but was null.") @@ -30,29 +29,6 @@ fun freeraspConfig.toNativeConfig(): TalsecConfig { supportedAlternativeStores(it.toTypedArray()) } - androidConfig.malwareConfig?.let { malware -> - if(malware.blacklistedPackageNames.isNotEmpty()) - { - blacklistedPackageNames(malware.blacklistedPackageNames.toTypedArray()) - } - if(malware.blacklistedHashes.isNotEmpty()) - { - blacklistedHashes(malware.blacklistedHashes.toTypedArray()) - } - if (malware.suspiciousPermissions.isNotEmpty()) - { - val nativePermissions = malware.suspiciousPermissions - .map { innerList -> innerList.toTypedArray() } - .toTypedArray() - - suspiciousPermissions(nativePermissions) - } - if(malware.whitelistedInstallationSources.isNotEmpty()) - { - whitelistedInstallationSources(malware.whitelistedInstallationSources.toTypedArray()) - } - } - androidConfig.suspiciousAppDetectionConfig?.let { suspiciousAppDetection(it.toNative()) } diff --git a/library/src/commonMain/kotlin/model/config/android_config.kt b/library/src/commonMain/kotlin/model/config/android_config.kt index 8cb7084..b081bb1 100644 --- a/library/src/commonMain/kotlin/model/config/android_config.kt +++ b/library/src/commonMain/kotlin/model/config/android_config.kt @@ -6,14 +6,11 @@ package com.freeraspkmp.model.config * @param packageName The expected package name of the app. * @param certificateHashes A list of expected certificate hashes in base64. * @param supportedAlternativeStores A list of package names for supported alternative stores. - * @param malwareConfig Deprecated. Use [suspiciousAppDetectionConfig] instead. * @param suspiciousAppDetectionConfig Configuration for malware detection. */ data class AndroidConfig( val packageName: String, val certificateHashes: List, val supportedAlternativeStores: List = emptyList(), - @Deprecated("Use SuspiciousAppDetectionConfig instead") - val malwareConfig: MalwareConfig? = null, val suspiciousAppDetectionConfig: SuspiciousAppDetectionConfig? = null ) diff --git a/library/src/commonMain/kotlin/model/config/malware_config.kt b/library/src/commonMain/kotlin/model/config/malware_config.kt deleted file mode 100644 index c1ccd5a..0000000 --- a/library/src/commonMain/kotlin/model/config/malware_config.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.freeraspkmp.model.config - -/** - * Configuration for malware detection. - * - * @param blacklistedPackageNames A list of blacklisted package names. - * @param blacklistedHashes A list of blacklisted app certificate hashes. - * @param suspiciousPermissions A list of suspicious permission groups. - * @param whitelistedInstallationSources A list of whitelisted installation sources. - */ -@Deprecated("Use SuspiciousAppDetectionConfig instead") -data class MalwareConfig ( - @Deprecated("Use SuspiciousAppDetectionConfig instead") - val blacklistedPackageNames: List = emptyList(), - @Deprecated("Use SuspiciousAppDetectionConfig instead") - val blacklistedHashes: List = emptyList(), - @Deprecated("Use SuspiciousAppDetectionConfig instead") - val suspiciousPermissions: List> = emptyList(), - @Deprecated("Use SuspiciousAppDetectionConfig instead") - val whitelistedInstallationSources: List = emptyList() -) \ No newline at end of file From fbb9bc74af38cd24b3228e3156ba4ca719ab3fbf Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Fri, 15 May 2026 16:56:27 +0200 Subject: [PATCH 09/14] chore: bump to 2.0.0 --- CHANGELOG.md | 11 +++-------- library/build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfdc777..f272cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.2.0] - 2026-05-07 +## [2.0.0] - 2026-05-15 - Android SDK version: 18.3.0 - iOS SDK version: 6.14.4 @@ -14,12 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `SuspiciousAppInfo.reason` (String) renamed to `reasons` (Set) - Value `"blacklist"` in `reasons` renamed to `"blocklist"` - -### Kotlin Multiplatform - -#### Deprecated - -- `blacklistedPackageNames`, `blacklistedHashes`, `suspiciousPermissions`, `whitelistedInstallationSources` are deprecated but remain functional — use `SuspiciousAppDetectionConfig` instead +- Removed `MalwareConfig` and `AndroidConfig.malwareConfig` +- `SuspiciousAppDetectionConfig.malwareScanScope` and `reasonMode` are now non-null with defaults `MalwareScanScope(ScopeType.SIDELOADED_ONLY)` and `ReasonMode.HIGHEST_CONFIDENCE` ### Android @@ -47,7 +43,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fine-tuned hook detection - Fine-tuned location spoofing detection - Modified malware incident log structure for better aggregation -- Old malware configuration API methods in `TalsecConfig.Builder` tagged as deprecated (but remain functional): `blacklistedPackageNames`, `blacklistedHashes`, `suspiciousPermissions`, `whitelistedInstallationSources` ## [1.1.0] - 2025-03-25 diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 77146af..911be4d 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -19,7 +19,7 @@ fun getVariable(name: String): String { group = "com.aheaditec.talsec.security" -version = "1.2.0" +version = "2.0.0" kotlin { targets.all { compilations.all { From b75092fce132615eee28a52119d68cc4046c53ca Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Fri, 15 May 2026 17:06:38 +0200 Subject: [PATCH 10/14] fix: use positional args for native SDK constructors --- .../kotlin/utils/config_mapper.android.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index 7b64faf..7c64653 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -39,18 +39,18 @@ fun freeraspConfig.toNativeConfig(): TalsecConfig { internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetectionConfig = NativeSuspiciousAppDetectionConfig( - packageNames = packageNames?.toSet(), - hashes = hashes?.toSet(), - requestedPermissions = requestedPermissions?.map { it.toSet() }?.toSet(), - grantedPermissions = grantedPermissions?.map { it.toSet() }?.toSet(), - malwareScanScope = malwareScanScope.toNative(), - reasonMode = reasonMode.toNative() + packageNames?.toSet(), + hashes?.toSet(), + requestedPermissions?.map { it.toSet() }?.toSet(), + grantedPermissions?.map { it.toSet() }?.toSet(), + malwareScanScope.toNative(), + reasonMode.toNative() ) internal fun MalwareScanScope.toNative(): NativeMalwareScanScope = NativeMalwareScanScope( - scanScope = scanScope.toNative(), - trustedInstallSources = trustedInstallSources + scanScope.toNative(), + trustedInstallSources ) internal fun ScopeType.toNative(): NativeScopeType = From 51cfb17a08f7dee2e5514a88d84fc0db5c1345b9 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Fri, 15 May 2026 17:49:14 +0200 Subject: [PATCH 11/14] chore: example app malware config update --- .../kotlin/com/jetbrains/example/App.kt | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt index 9c9999b..75d2e8f 100644 --- a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt +++ b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt @@ -12,6 +12,9 @@ import com.freeraspkmp.model.FreeRaspEvent import com.freeraspkmp.model.SuspiciousAppInfo import com.freeraspkmp.model.config.AndroidConfig import com.freeraspkmp.model.config.IOSConfig +import com.freeraspkmp.model.config.MalwareScanScope +import com.freeraspkmp.model.config.ReasonMode +import com.freeraspkmp.model.config.ScopeType import com.freeraspkmp.model.config.SuspiciousAppDetectionConfig import com.freeraspkmp.model.config.freeraspConfig import com.jetbrains.example.model.initialChecks @@ -34,7 +37,24 @@ fun App() { packageName = "com.jetbrains.example", certificateHashes = listOf("K/iFV7+CypnATFWcrUVM6aUIB5gnU2xwzRJOiKJJqPw="), suspiciousAppDetectionConfig = SuspiciousAppDetectionConfig( - packageNames = listOf("com.google.android.youtube") + packageNames = listOf("com.google.android.youtube"), + hashes = listOf("FgvSehLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0u"), + requestedPermissions = listOf( + listOf( + "android.permission.INTERNET", + "android.permission.ACCESS_COARSE_LOCATION", + ), + listOf("android.permission.BLUETOOTH"), + listOf("android.permission.BATTERY_STATS"), + ), + grantedPermissions = listOf( + listOf("android.permission.ACCESS_FINE_LOCATION"), + ), + malwareScanScope = MalwareScanScope( + scanScope = ScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM, + trustedInstallSources = listOf("com.apkpure.aegon"), + ), + reasonMode = ReasonMode.HIGHEST_CONFIDENCE, ) ), iosConfig = IOSConfig( From a22549444922b4702792f3664a45a2fd53f146c4 Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Tue, 19 May 2026 17:43:52 +0200 Subject: [PATCH 12/14] refactor: rename MalwareScanScope to ScanScope --- .../src/commonMain/kotlin/com/jetbrains/example/App.kt | 4 ++-- .../src/androidMain/kotlin/utils/config_mapper.android.kt | 6 +++--- .../model/config/suspicious_app_detection_config.kt | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt index 75d2e8f..c01269f 100644 --- a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt +++ b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt @@ -12,7 +12,7 @@ import com.freeraspkmp.model.FreeRaspEvent import com.freeraspkmp.model.SuspiciousAppInfo import com.freeraspkmp.model.config.AndroidConfig import com.freeraspkmp.model.config.IOSConfig -import com.freeraspkmp.model.config.MalwareScanScope +import com.freeraspkmp.model.config.ScanScope import com.freeraspkmp.model.config.ReasonMode import com.freeraspkmp.model.config.ScopeType import com.freeraspkmp.model.config.SuspiciousAppDetectionConfig @@ -50,7 +50,7 @@ fun App() { grantedPermissions = listOf( listOf("android.permission.ACCESS_FINE_LOCATION"), ), - malwareScanScope = MalwareScanScope( + scanScope = ScanScope( scanScope = ScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM, trustedInstallSources = listOf("com.apkpure.aegon"), ), diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index 7c64653..95bd372 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -1,7 +1,7 @@ package com.freeraspkmp.android.utils import com.aheaditec.talsec_security.security.api.TalsecConfig -import com.freeraspkmp.model.config.MalwareScanScope +import com.freeraspkmp.model.config.ScanScope import com.freeraspkmp.model.config.ReasonMode import com.freeraspkmp.model.config.ScopeType import com.freeraspkmp.model.config.SuspiciousAppDetectionConfig @@ -43,11 +43,11 @@ internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetecti hashes?.toSet(), requestedPermissions?.map { it.toSet() }?.toSet(), grantedPermissions?.map { it.toSet() }?.toSet(), - malwareScanScope.toNative(), + scanScope.toNative(), reasonMode.toNative() ) -internal fun MalwareScanScope.toNative(): NativeMalwareScanScope = +internal fun ScanScope.toNative(): NativeMalwareScanScope = NativeMalwareScanScope( scanScope.toNative(), trustedInstallSources diff --git a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt index 373833c..2b4f3ad 100644 --- a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt +++ b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt @@ -22,7 +22,7 @@ enum class ReasonMode { ALL, HIGHEST_CONFIDENCE } * @param scanScope The set of apps to include in the scan. * @param trustedInstallSources Installation sources whose apps should be excluded from the scan. */ -data class MalwareScanScope( +data class ScanScope( val scanScope: ScopeType, val trustedInstallSources: List? = null ) @@ -34,8 +34,8 @@ data class MalwareScanScope( * @param hashes Certificate hashes of known malicious apps. * @param requestedPermissions Groups of permissions an app must request to be flagged as suspicious. * @param grantedPermissions Groups of permissions an app must be granted to be flagged as suspicious. - * @param malwareScanScope Defines which apps are scanned. - * Defaults to [MalwareScanScope] with [ScopeType.SIDELOADED_ONLY]. + * @param scanScope Defines which apps are scanned. + * Defaults to [ScanScope] with [ScopeType.SIDELOADED_ONLY]. * @param reasonMode Controls how detection reasons are reported. * Defaults to [ReasonMode.HIGHEST_CONFIDENCE]. */ @@ -44,6 +44,6 @@ data class SuspiciousAppDetectionConfig( val hashes: List? = null, val requestedPermissions: List>? = null, val grantedPermissions: List>? = null, - val malwareScanScope: MalwareScanScope = MalwareScanScope(ScopeType.SIDELOADED_ONLY), + val scanScope: ScanScope = ScanScope(ScopeType.SIDELOADED_ONLY), val reasonMode: ReasonMode = ReasonMode.HIGHEST_CONFIDENCE ) From 24369145a1b0da95e447482c8c36584a6479036c Mon Sep 17 00:00:00 2001 From: martinzigrai Date: Wed, 27 May 2026 16:14:54 +0200 Subject: [PATCH 13/14] docs: update changelog --- CHANGELOG.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f272cfe..f454de4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,10 +21,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Added -- Added a new sub-check for `HMA` detection to the root detector -- Added a new sub-check for `KernelSU` detection to the root detector -- Added a new sub-check for `Frida Server` detection to the hook detector -- Added Huawei App Market provider to HMA detection queries - New API class `SuspiciousAppDetectionConfig` that can be used to configure malware detection - New API for malware detection configuration in `TalsecConfig`, see `TalsecConfig.Builder#suspiciousAppDetection` @@ -32,15 +28,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed `VerifyError` caused by `JaCoCo` bytecode instrumentation - Fixed a potential cause of crash in the multi-instance detector -- Fixed crash caused by unhandled `SecurityException` thrown by `UsageStatsManager` in root detection -- Fixed manifest merge conflicts in HMA detection providers - Fixed Java interoperability of `ScreenProtector` methods - Fixed Kotlin classpath conflicts in SDK dependency resolution (Kotlin 2.0.0) #### Changed -- Fine-tuned `KernelSU` detection -- Fine-tuned hook detection - Fine-tuned location spoofing detection - Modified malware incident log structure for better aggregation From 248ec226ab8c7493a20756f1dc08cb5eb2a24889 Mon Sep 17 00:00:00 2001 From: Tomas Psota Date: Thu, 28 May 2026 15:16:15 +0200 Subject: [PATCH 14/14] Rename ScanScope.scanScope property to scopeType Co-authored-by: Cursor --- .../src/commonMain/kotlin/com/jetbrains/example/App.kt | 2 +- library/src/androidMain/kotlin/utils/config_mapper.android.kt | 2 +- .../kotlin/model/config/suspicious_app_detection_config.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt index c01269f..5e39a64 100644 --- a/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt +++ b/example/composeApp/src/commonMain/kotlin/com/jetbrains/example/App.kt @@ -51,7 +51,7 @@ fun App() { listOf("android.permission.ACCESS_FINE_LOCATION"), ), scanScope = ScanScope( - scanScope = ScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM, + scopeType = ScopeType.SIDELOADED_AND_SYSTEM_EXCLUDE_OEM, trustedInstallSources = listOf("com.apkpure.aegon"), ), reasonMode = ReasonMode.HIGHEST_CONFIDENCE, diff --git a/library/src/androidMain/kotlin/utils/config_mapper.android.kt b/library/src/androidMain/kotlin/utils/config_mapper.android.kt index 95bd372..028939a 100644 --- a/library/src/androidMain/kotlin/utils/config_mapper.android.kt +++ b/library/src/androidMain/kotlin/utils/config_mapper.android.kt @@ -49,7 +49,7 @@ internal fun SuspiciousAppDetectionConfig.toNative(): NativeSuspiciousAppDetecti internal fun ScanScope.toNative(): NativeMalwareScanScope = NativeMalwareScanScope( - scanScope.toNative(), + scopeType.toNative(), trustedInstallSources ) diff --git a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt index 2b4f3ad..01c9845 100644 --- a/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt +++ b/library/src/commonMain/kotlin/model/config/suspicious_app_detection_config.kt @@ -19,11 +19,11 @@ enum class ReasonMode { ALL, HIGHEST_CONFIDENCE } /** * Defines which installed apps should be scanned for malware. * - * @param scanScope The set of apps to include in the scan. + * @param scopeType The set of apps to include in the scan. * @param trustedInstallSources Installation sources whose apps should be excluded from the scan. */ data class ScanScope( - val scanScope: ScopeType, + val scopeType: ScopeType, val trustedInstallSources: List? = null )