From eb14b6565a903c019c6477090a22b35a62d58a64 Mon Sep 17 00:00:00 2001 From: firmianay Date: Wed, 22 Nov 2023 22:29:57 +0800 Subject: [PATCH 1/4] add runtimeSDK --- .../kotlin/net/bytedance/security/app/AnalyzeStepByStep.kt | 4 ++-- src/main/kotlin/net/bytedance/security/app/RuleData.kt | 3 ++- .../kotlin/net/bytedance/security/app/StaticAnalyzeMain.kt | 3 +-- src/main/kotlin/net/bytedance/security/app/rules/Rules.kt | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/net/bytedance/security/app/AnalyzeStepByStep.kt b/src/main/kotlin/net/bytedance/security/app/AnalyzeStepByStep.kt index d1370e4..ef12b99 100644 --- a/src/main/kotlin/net/bytedance/security/app/AnalyzeStepByStep.kt +++ b/src/main/kotlin/net/bytedance/security/app/AnalyzeStepByStep.kt @@ -36,7 +36,7 @@ import kotlin.io.path.pathString import kotlin.streams.toList class AnalyzeStepByStep { - suspend fun loadRules(ruleList: String, targetSdk: Int): Rules { + suspend fun loadRules(ruleList: String, targetSdk: Int, minSdk: Int): Rules { val rulePathList = if (ruleList.isNotEmpty()) ruleList.split(",").map { "${getConfig().rulePath}/${it.trim()}" }.toList() else @@ -45,7 +45,7 @@ class AnalyzeStepByStep { }.filter { it.pathString.endsWith(".json") }.map { it.pathString } .toList() val rules = Rules(rulePathList, RuleFactory()) - rules.loadRules(targetSdk) + rules.loadRules(targetSdk, minSdk) return rules } diff --git a/src/main/kotlin/net/bytedance/security/app/RuleData.kt b/src/main/kotlin/net/bytedance/security/app/RuleData.kt index 3467dbf..f33f99d 100644 --- a/src/main/kotlin/net/bytedance/security/app/RuleData.kt +++ b/src/main/kotlin/net/bytedance/security/app/RuleData.kt @@ -125,7 +125,8 @@ data class RuleData( val ConstNumberMode: Boolean? = null, val targetNumberArr: List? = null, - val targetSdk: String = "", + val targetSdk: String = "", // 规则适用的targetSdk版本 + val runtimeSdk: String = "", // 规则适用的运行时系统版本 ) val defaultSourceReturn = SourceReturn() diff --git a/src/main/kotlin/net/bytedance/security/app/StaticAnalyzeMain.kt b/src/main/kotlin/net/bytedance/security/app/StaticAnalyzeMain.kt index a0d6974..e8a4594 100644 --- a/src/main/kotlin/net/bytedance/security/app/StaticAnalyzeMain.kt +++ b/src/main/kotlin/net/bytedance/security/app/StaticAnalyzeMain.kt @@ -54,12 +54,11 @@ object StaticAnalyzeMain { profiler.parseApk.end() profiler.preProcessor.start() - val rules = v3.loadRules(argumentConfig.rules, AndroidUtils.TargetSdk) + val rules = v3.loadRules(argumentConfig.rules, AndroidUtils.TargetSdk, AndroidUtils.MinSdk) logInfo("rules loaded") val ctx = v3.createContext(rules) profiler.preProcessor.end() - if (getConfig().doWholeProcessMode) { PLUtils.createWholeProgramAnalyze(ctx) } diff --git a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt index 81e8970..87e1780 100644 --- a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt +++ b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt @@ -30,7 +30,7 @@ import java.nio.file.Paths class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForContext { val allRules: MutableList = ArrayList() - suspend fun loadRules(targetSdk: Int? = null) { + suspend fun loadRules(targetSdk: Int, minSdk: Int) { rulePaths.forEach { val jsonStr = loadConfigOrQuit(it) val rules = Json.parseToJsonElement(jsonStr) @@ -40,7 +40,8 @@ class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForC ruleData.sanitize = ruleData.sanitizer ruleData.sanitizer = null } - if (targetSdk == null || targetSdk in parseSdkVersion(ruleData.targetSdk)) { + if ((targetSdk == -1 || targetSdk in parseSdkVersion(ruleData.targetSdk)) && + (minSdk == -1 || parseSdkVersion("$minSdk:").any { it in parseSdkVersion(ruleData.runtimeSdk) })) { val rule = factory.create(ruleName, ruleData) allRules.add(rule) } else { @@ -95,7 +96,7 @@ class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForC } } - fun parseSdkVersion(input: String): List { + private fun parseSdkVersion(input: String): List { val MIN_SDK_VERSION = 9 // Android 2.3 val MAX_SDK_VERSION = 50 // for future From 9c5a0c210ccdb492f61090dcd69a05b0644b2125 Mon Sep 17 00:00:00 2001 From: firmianay Date: Thu, 23 Nov 2023 09:24:02 +0800 Subject: [PATCH 2/4] add default value for test --- src/main/kotlin/net/bytedance/security/app/rules/Rules.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt index 87e1780..a2674aa 100644 --- a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt +++ b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt @@ -29,8 +29,9 @@ import java.nio.file.Paths class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForContext { val allRules: MutableList = ArrayList() + val UNLIMITED = -1 - suspend fun loadRules(targetSdk: Int, minSdk: Int) { + suspend fun loadRules(targetSdk: Int = UNLIMITED, minSdk: Int = UNLIMITED) { rulePaths.forEach { val jsonStr = loadConfigOrQuit(it) val rules = Json.parseToJsonElement(jsonStr) @@ -40,8 +41,8 @@ class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForC ruleData.sanitize = ruleData.sanitizer ruleData.sanitizer = null } - if ((targetSdk == -1 || targetSdk in parseSdkVersion(ruleData.targetSdk)) && - (minSdk == -1 || parseSdkVersion("$minSdk:").any { it in parseSdkVersion(ruleData.runtimeSdk) })) { + if ((targetSdk == UNLIMITED || targetSdk in parseSdkVersion(ruleData.targetSdk)) && + (minSdk == UNLIMITED || parseSdkVersion("$minSdk:").any { it in parseSdkVersion(ruleData.runtimeSdk) })) { val rule = factory.create(ruleName, ruleData) allRules.add(rule) } else { From ebb78da8222534dd9199895822111c9be9d8c257 Mon Sep 17 00:00:00 2001 From: firmianay Date: Thu, 14 Dec 2023 15:15:02 +0800 Subject: [PATCH 3/4] add test --- .../net/bytedance/security/app/rules/Rules.kt | 53 +++++++++---------- .../bytedance/security/app/rules/RulesTest.kt | 17 +++++- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt index a2674aa..b6f6c0b 100644 --- a/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt +++ b/src/main/kotlin/net/bytedance/security/app/rules/Rules.kt @@ -92,40 +92,39 @@ class Rules(val rulePaths: List, val factory: IRuleFactory) : IRulesForC throw Exception("read config file $path failed") } } - return jsonStr } - } - private fun parseSdkVersion(input: String): List { - val MIN_SDK_VERSION = 9 // Android 2.3 - val MAX_SDK_VERSION = 50 // for future + fun parseSdkVersion(input: String): List { + val MIN_SDK_VERSION = 9 // Android 2.3 + val MAX_SDK_VERSION = 50 // for future - if (input.isBlank() || input.trim() == ":") { - return (MIN_SDK_VERSION..MAX_SDK_VERSION).toList() - } - return input.split(Regex("[,\\s]+")).flatMap { part -> - when { - part.contains(":") -> { - val splitPart = part.split(":") - val hasStart = splitPart[0].isNotEmpty() - val hasEnd = splitPart[1].isNotEmpty() - when { - !hasStart && !hasEnd -> listOf() - !hasEnd -> { - (splitPart[0].toIntOrNull() ?: return@flatMap listOf())..MAX_SDK_VERSION - } - !hasStart -> { - (MIN_SDK_VERSION..(splitPart[1].toIntOrNull() ?: return@flatMap listOf())).toList() - } - else -> { - val start = splitPart[0].toIntOrNull() ?: return@flatMap listOf() - val end = splitPart[1].toIntOrNull() ?: return@flatMap listOf() - (start..end).toList() + if (input.isBlank() || input.trim() == ":") { + return (MIN_SDK_VERSION..MAX_SDK_VERSION).toList() + } + return input.split(Regex("[,\\s]+")).flatMap { part -> + when { + part.contains(":") -> { + val splitPart = part.split(":") + val hasStart = splitPart[0].isNotEmpty() + val hasEnd = splitPart[1].isNotEmpty() + when { + !hasStart && !hasEnd -> listOf() + !hasEnd -> { + (splitPart[0].toIntOrNull() ?: return@flatMap listOf())..MAX_SDK_VERSION + } + !hasStart -> { + (MIN_SDK_VERSION..(splitPart[1].toIntOrNull() ?: return@flatMap listOf())).toList() + } + else -> { + val start = splitPart[0].toIntOrNull() ?: return@flatMap listOf() + val end = splitPart[1].toIntOrNull() ?: return@flatMap listOf() + (start..end).toList() + } } } + else -> listOf(part.toIntOrNull() ?: return@flatMap listOf()) } - else -> listOf(part.toIntOrNull() ?: return@flatMap listOf()) } } } diff --git a/src/test/kotlin/net/bytedance/security/app/rules/RulesTest.kt b/src/test/kotlin/net/bytedance/security/app/rules/RulesTest.kt index b5cfa26..4b8fdc9 100644 --- a/src/test/kotlin/net/bytedance/security/app/rules/RulesTest.kt +++ b/src/test/kotlin/net/bytedance/security/app/rules/RulesTest.kt @@ -20,11 +20,11 @@ package net.bytedance.security.app.rules import kotlinx.coroutines.runBlocking import net.bytedance.security.app.getConfig import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.* import java.io.File internal class RulesTest { - fun createDefaultRules(): Rules { val rules = Rules( listOf( @@ -69,7 +69,22 @@ internal class RulesTest { println("const strings=${rules.constStringPatterns().toSortedSet().toList()}") println("fields=${rules.fields().toSortedSet().toList()}") println("new instances=${rules.newInstances().toSortedSet().toList()}") + } + @Test + fun testParseSdkVersion() { + assertEquals( + (9..50).toList(), + Rules.parseSdkVersion("") + ) + assertEquals( + (9..50).toList(), + Rules.parseSdkVersion(":") + ) + assertEquals( + (9..10).toList() + listOf(15) + (25..30).toList() + (45..50).toList(), + Rules.parseSdkVersion(":10, 15, 25:30, 45:") + ) } companion object { From d7dfb388940b1772a2dd5f4054b49b98ae1dfd07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E8=93=91=E7=83=9F=E9=9B=A8?= Date: Sat, 23 Dec 2023 15:06:54 +0800 Subject: [PATCH 4/4] Update EngineConfig.json5 --- config/EngineConfig.json5 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/config/EngineConfig.json5 b/config/EngineConfig.json5 index f536775..9755752 100644 --- a/config/EngineConfig.json5 +++ b/config/EngineConfig.json5 @@ -1580,7 +1580,17 @@ "ret" ] } + }, + "": { + "p0->p1": { + "I": [ + "p0" + ], + "O": [ + "p1" + ] + } } } } -} \ No newline at end of file +}