├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── pull_request_template.md
└── workflows
│ ├── flutter-ci.yml
│ └── issue_watcher.yaml
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── app
│ │ │ │ └── talsec
│ │ │ │ └── free_malware_detection
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── lib
├── app.dart
├── home
│ ├── providers
│ │ ├── providers.dart
│ │ ├── threat_notifier.dart
│ │ └── threat_state.dart
│ ├── views
│ │ ├── home_page.dart
│ │ ├── malware_bottom_sheet.dart
│ │ └── views.dart
│ └── widgets
│ │ ├── app_icon.dart
│ │ ├── dismiss_background.dart
│ │ ├── malware_item.dart
│ │ ├── spinning_icon.dart
│ │ ├── status_tile.dart
│ │ └── widgets.dart
├── main.dart
└── services
│ ├── services.dart
│ └── talsec_service.dart
├── pubspec.lock
└── pubspec.yaml
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: talsec-app
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | If applicable, steps to reproduce the behavior.
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Screenshots**
20 | If applicable, add screenshots to help explain your problem.
21 |
22 | **Please complete the following information:**
23 | - Device: [e.g. Samsung Galaxy A50]
24 | - OS version: [e.g. Android 12]
25 | - Version of freeRASP: [e.g. 6.0.0]
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: talsec-app
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # .freeMalwareDetection
2 |
3 |
4 |
5 | ## Pre-release checklist
6 | - [ ] 🔎 Malware detection works
7 | - [ ] 📝 Whitelisting works
8 | - [ ] 📝 Logging works
9 | - [ ] 📋 Changelog updated
10 | - [ ] ➡️ `pubspec.yaml` version updated
11 |
12 |
13 | ## Post-release checklist
14 | - [ ] 📝 GitHub release
15 |
16 | ## Type of Changes
17 |
18 | - [ ] ✨ New feature (non-breaking change which adds functionality)
19 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
20 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
21 | - [ ] 🧹 Code refactor
22 | - [ ] ✅ Build configuration change
23 | - [ ] 📝 Documentation
24 | - [ ] 🗑️ Chore
25 |
26 | ## Description
27 |
28 |
37 |
--------------------------------------------------------------------------------
/.github/workflows/flutter-ci.yml:
--------------------------------------------------------------------------------
1 | name: Flutter CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths-ignore:
8 | - '**/*.md'
9 | - '.github/**'
10 | pull_request:
11 | branches:
12 | - main
13 | paths-ignore:
14 | - '**/*.md'
15 | - '.github/**'
16 |
17 | workflow_dispatch:
18 |
19 | env:
20 | FLUTTER_VERSION: 3.24.0
21 |
22 | jobs:
23 | lint:
24 | runs-on: ubuntu-latest
25 | steps:
26 | - name: 📚 Git Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: 🐦 Setup Flutter
30 | uses: subosito/flutter-action@v2.16.0
31 | with:
32 | channel: stable
33 | flutter-version: ${{ env.FLUTTER_VERSION }}
34 | cache: true
35 |
36 | - name: ✂ Format Code
37 | run: dart format --set-exit-if-changed .
38 |
39 | - name: 📊 Analyze Code
40 | run: flutter analyze --fatal-infos --fatal-warnings .
41 |
42 | build-android:
43 | runs-on: ubuntu-latest
44 |
45 | steps:
46 | - name: 📚 Git Checkout
47 | uses: actions/checkout@v4
48 |
49 | - name: 🐦 Setup Flutter
50 | uses: subosito/flutter-action@v2.16.0
51 | with:
52 | channel: stable
53 | flutter-version: ${{ env.FLUTTER_VERSION }}
54 | cache: true
55 |
56 | - name: 🤖 Build Android app
57 | run: flutter build apk --release
58 |
--------------------------------------------------------------------------------
/.github/workflows/issue_watcher.yaml:
--------------------------------------------------------------------------------
1 | name: Issue watcher
2 | on:
3 | workflow_dispatch:
4 | schedule:
5 | # Date follows the cron syntax: https://en.wikipedia.org/wiki/Cron
6 | # Every Monday at 6:30 AM
7 | - cron: '30 6 * * 1'
8 |
9 | jobs:
10 | check_issues:
11 | uses: talsec/github-workflows/.github/workflows/issue_watcher.yml@master
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Symbolication related
35 | app.*.symbols
36 |
37 | # Obfuscation related
38 | app.*.map.json
39 |
40 | # Android Studio will place build artifacts here
41 | /android/app/debug
42 | /android/app/profile
43 | /android/app/release
44 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: "a14f74ff3a1cbd521163c5f03d68113d50af93d3"
8 | channel: "stable"
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
17 | base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
18 | - platform: android
19 | create_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
20 | base_revision: a14f74ff3a1cbd521163c5f03d68113d50af93d3
21 |
22 | # User provided section
23 |
24 | # List of Local paths (relative to this file) that should be
25 | # ignored by the migrate tool.
26 | #
27 | # Files that are not part of the templates will be ignored by default.
28 | unmanaged_files:
29 | - 'lib/main.dart'
30 | - 'ios/Runner.xcodeproj/project.pbxproj'
31 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [1.0.0] - 2024-11-08
9 | - Initial release
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Talsec
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # freeMalwareDetection for Flutter
4 |
5 | Enhance the security of your Android application with Free Malware Detection, a powerful feature designed to scan for malicious or suspicious apps. Leveraging various blacklists and security policies, this tool ensures your application remains protected from known threats, providing a secure environment for your users.
6 |
7 | ## Overview
8 |
9 | freeMalwareDetection is an easy-to-integrate SDK that operates asynchronously to safeguard your application without compromising performance. It runs scans in the background, ensuring that your app's performance remains unaffected while delivering comprehensive security checks. This SDK is freely available and designed for seamless integration with the freeRASP SDK, delivering a comprehensive security solution.
10 |
11 | Learn more about freemium freeMalwareDetection features at [GitHub main repository](https://github.com/talsec/freeMalwareDetection).
12 |
13 | ## :key: Key Advantages
14 |
15 | - **Asynchronous Scanning**: Perform malware scans in the background without impacting app performance.
16 | - **Threat Analysis**: Receive information about detected threats to better inform and protect your users.
17 | - **Simple Integration**: Easy-to-follow integration process with extensive documentation and support.
18 | - **Versatile Blacklisting**: Supports hash-based, package name-based, and permission-based blacklists for comprehensive threat detection.
19 | - **Seamless Operation**: Integrates smoothly with freeRASP SDK to provide an all-in-one security solution.
20 |
21 | ## 🎯 Features
22 |
23 | Free Malware Detection provides protection against potentially dangerous applications and behaviors, including:
24 |
25 | ✔️ Detection of apps with suspicious package names or hashes.
26 |
27 | ✔️ Blocking of apps with disallowed permissions.
28 |
29 | ✔️ Whitelisting of trusted installation sources to prevent unauthorized app installations.
30 |
31 | Visit our wiki to learn more about the specific checks performed and their impact on app security.
32 |
33 | ## 📖 Discover Official Documentation
34 |
35 | Explore our [GitBook page](https://docs.talsec.app/freemalwaredetection) for detailed guides, tutorials, and technical documentation.
36 |
37 | ## 🔗 Integration Guide
38 |
39 | To integrate Free Malware Detection, follow our step-by-step [Integration Guide](https://docs.talsec.app/freemalwaredetection/integration-guide/requirements). This guide provides all the details you need for a smooth setup process on any platform.
40 |
41 | ## ✨ Enhancements
42 |
43 | If you have any suggestions for improvement or notice anything that could be clarified in the new documentation, please open an issue. Your feedback helps us maintain high-quality resources for all users.
44 |
45 | You can check out the [project board](https://github.com/orgs/talsec/projects/3) here.
46 |
47 | ## :wave: Come and Be Part of the Community!
48 |
49 | Explore the **freeMalware Discussion section** for:
50 |
51 | - Support and Q&A :books:
52 | - Announcements :mega:
53 | - Community collaboration 🛠️
54 |
55 | :point_right: [Join the Discussion](https://github.com/talsec/freeMalwareDetection/discussions) :point_left:
56 |
57 | ## :page_facing_up: License
58 | This project is provided as freemium software, i.e. there is a fair usage policy that imposes some limitations on the free usage. The SDK software consists of open-source and binary parts, which is the property of Talsec. The open-source part is licensed under the MIT License - see the LICENSE file for details.
59 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:very_good_analysis/analysis_options.yaml
2 |
3 | linter:
4 | rules:
5 | public_member_api_docs: false
6 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | id "dev.flutter.flutter-gradle-plugin"
5 | }
6 |
7 | def localProperties = new Properties()
8 | def localPropertiesFile = rootProject.file("local.properties")
9 | if (localPropertiesFile.exists()) {
10 | localPropertiesFile.withReader("UTF-8") { reader ->
11 | localProperties.load(reader)
12 | }
13 | }
14 |
15 | def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
16 | if (flutterVersionCode == null) {
17 | flutterVersionCode = "1"
18 | }
19 |
20 | def flutterVersionName = localProperties.getProperty("flutter.versionName")
21 | if (flutterVersionName == null) {
22 | flutterVersionName = "1.0"
23 | }
24 |
25 | android {
26 | namespace = "app.talsec.free_malware_detection"
27 | compileSdk = flutter.compileSdkVersion
28 | ndkVersion = flutter.ndkVersion
29 |
30 | compileOptions {
31 | sourceCompatibility = JavaVersion.VERSION_1_8
32 | targetCompatibility = JavaVersion.VERSION_1_8
33 | }
34 |
35 | defaultConfig {
36 | applicationId = "app.talsec.free_malware_detection"
37 | // You can update the following values to match your application needs.
38 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
39 | minSdk = 23
40 | targetSdk = flutter.targetSdkVersion
41 | versionCode = flutterVersionCode.toInteger()
42 | versionName = flutterVersionName
43 | }
44 |
45 | buildTypes {
46 | release {
47 | // TODO: Add your own signing config for the release build.
48 | // Signing with the debug keys for now, so `flutter run --release` works.
49 | signingConfig = signingConfigs.debug
50 | }
51 | }
52 | }
53 |
54 | flutter {
55 | source = "../.."
56 | }
57 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/app/talsec/free_malware_detection/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package app.talsec.free_malware_detection
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity()
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talsec/freeMalwareDetection-Flutter/1f424b056baff2669c92a21fb503c7e15587b254/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talsec/freeMalwareDetection-Flutter/1f424b056baff2669c92a21fb503c7e15587b254/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talsec/freeMalwareDetection-Flutter/1f424b056baff2669c92a21fb503c7e15587b254/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talsec/freeMalwareDetection-Flutter/1f424b056baff2669c92a21fb503c7e15587b254/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talsec/freeMalwareDetection-Flutter/1f424b056baff2669c92a21fb503c7e15587b254/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = "../build"
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(":app")
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version "7.3.0" apply false
22 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false
23 | }
24 |
25 | include ":app"
26 |
--------------------------------------------------------------------------------
/lib/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:free_malware_detection/home/views/views.dart';
3 |
4 | /// The root widget of the application
5 | class App extends StatelessWidget {
6 | const App({super.key});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return MaterialApp(
11 | title: 'Flutter Demo',
12 | theme: ThemeData(primarySwatch: Colors.blue),
13 | home: const HomePage(),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/home/providers/providers.dart:
--------------------------------------------------------------------------------
1 | export 'threat_notifier.dart';
2 | export 'threat_state.dart';
3 |
--------------------------------------------------------------------------------
/lib/home/providers/threat_notifier.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_riverpod/flutter_riverpod.dart';
2 | import 'package:free_malware_detection/home/providers/threat_state.dart';
3 | import 'package:freerasp/freerasp.dart';
4 |
5 | /// Class responsible for setting up listeners to detected threats
6 | class ThreatNotifier extends AutoDisposeNotifier {
7 | @override
8 | ThreatState build() {
9 | _init();
10 | return ThreatState(detectedMalware: {}, isDetected: false);
11 | }
12 |
13 | void _init() {
14 | final threatCallback = ThreatCallback(onMalware: _updateMalware);
15 | Talsec.instance.attachListener(threatCallback);
16 | }
17 |
18 | void _updateMalware(List malware) {
19 | state = state.copyWith(
20 | detectedMalware: malware.nonNulls.toSet(),
21 | hasDetectedMalware: true,
22 | );
23 | }
24 |
25 | void removeMalware(SuspiciousAppInfo malware) {
26 | final malwareSet = state.detectedMalware..remove(malware);
27 | state = state.copyWith(detectedMalware: malwareSet);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/home/providers/threat_state.dart:
--------------------------------------------------------------------------------
1 | import 'package:freerasp/freerasp.dart';
2 |
3 | class ThreatState {
4 | ThreatState({
5 | required this.detectedMalware,
6 | required this.isDetected,
7 | });
8 |
9 | final Set detectedMalware;
10 | final bool isDetected;
11 |
12 | ThreatState copyWith({
13 | Set? detectedMalware,
14 | bool? hasDetectedMalware,
15 | }) {
16 | return ThreatState(
17 | detectedMalware: detectedMalware ?? this.detectedMalware,
18 | isDetected: hasDetectedMalware ?? isDetected,
19 | );
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/home/views/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_riverpod/flutter_riverpod.dart';
3 | import 'package:free_malware_detection/home/views/views.dart';
4 | import 'package:free_malware_detection/home/widgets/widgets.dart';
5 |
6 | import 'package:free_malware_detection/main.dart';
7 | import 'package:freerasp/freerasp.dart';
8 |
9 | /// The home page that displays the threats and results
10 | class HomePage extends ConsumerWidget {
11 | const HomePage({super.key});
12 |
13 | @override
14 | Widget build(BuildContext context, WidgetRef ref) {
15 | final threatState = ref.watch(threatProvider);
16 |
17 | return Scaffold(
18 | appBar: AppBar(title: const Text('freeMalwareDetection Demo')),
19 | body: SafeArea(
20 | child: Center(
21 | child: Column(
22 | mainAxisAlignment: MainAxisAlignment.center,
23 | children: [
24 | const StatusTile(
25 | title: '.freeRASP',
26 | subtitle: 'Up and running',
27 | icon: Icons.check_circle_outline_rounded,
28 | iconColor: Colors.green,
29 | ),
30 | StatusTile(
31 | title: '.freeMalwareDetection',
32 | subtitle: threatState.isDetected ? 'Scan done' : 'Scan running',
33 | icon: threatState.isDetected
34 | ? Icons.check_circle_outline_rounded
35 | : Icons.sync_outlined,
36 | iconColor:
37 | threatState.isDetected ? Colors.green : Colors.orange,
38 | isSpinning: !threatState.isDetected, // Spins if scan is running
39 | ),
40 | Visibility(
41 | visible: threatState.isDetected,
42 | child: OutlinedButton(
43 | onPressed: () => _showMalwareBottomSheet(
44 | context,
45 | threatState.detectedMalware.toList(),
46 | ref,
47 | ),
48 | child: Text(
49 | 'Show Results'.toUpperCase(),
50 | style: Theme.of(context).textTheme.labelLarge,
51 | ),
52 | ),
53 | ),
54 | ],
55 | ),
56 | ),
57 | ),
58 | );
59 | }
60 | }
61 |
62 | void _showMalwareBottomSheet(
63 | BuildContext context,
64 | List suspiciousApps,
65 | WidgetRef ref,
66 | ) {
67 | WidgetsBinding.instance.addPostFrameCallback((_) {
68 | showModalBottomSheet(
69 | context: context,
70 | isDismissible: false,
71 | enableDrag: false,
72 | isScrollControlled: true,
73 | builder: (BuildContext context) => MalwareBottomSheet(
74 | suspiciousApps: suspiciousApps,
75 | onDismiss: () => Navigator.pop(context),
76 | ),
77 | );
78 | });
79 | }
80 |
--------------------------------------------------------------------------------
/lib/home/views/malware_bottom_sheet.dart:
--------------------------------------------------------------------------------
1 | import 'package:android_intent_plus/android_intent.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_riverpod/flutter_riverpod.dart';
4 | import 'package:free_malware_detection/home/widgets/widgets.dart';
5 | import 'package:free_malware_detection/main.dart';
6 | import 'package:free_malware_detection/services/talsec_service.dart';
7 | import 'package:freerasp/freerasp.dart';
8 |
9 | /// Bottom sheet widget that displays malware information
10 | class MalwareBottomSheet extends ConsumerWidget {
11 | /// Represents malware information in the example app
12 | const MalwareBottomSheet({
13 | required this.suspiciousApps,
14 | required this.onDismiss,
15 | super.key,
16 | });
17 |
18 | /// List of suspicious apps
19 | final List suspiciousApps;
20 | final void Function()? onDismiss;
21 |
22 | @override
23 | Widget build(BuildContext context, WidgetRef ref) {
24 | final textTheme = Theme.of(context).textTheme;
25 | final suspiciousApps = ref.watch(threatProvider).detectedMalware.toList();
26 |
27 | return Container(
28 | height: double.infinity,
29 | padding: const EdgeInsets.all(8),
30 | child: Column(
31 | children: [
32 | Text('Suspicious Apps', style: textTheme.titleMedium),
33 | const SizedBox(height: 8),
34 | Expanded(
35 | child: ListView.builder(
36 | itemCount: suspiciousApps.length,
37 | itemBuilder: (_, index) {
38 | final item = suspiciousApps[index];
39 | return MalwareItem(
40 | packageInfo: item.packageInfo,
41 | reason: item.reason,
42 | onWhitelist: () {
43 | _removeItem(ref, item);
44 | TalsecService.whitelistApp(item);
45 | },
46 | onUninstall: () => _launchUninstall(item),
47 | onDismiss: () {
48 | _whitelistApp(item);
49 | _removeItem(ref, item);
50 | },
51 | );
52 | },
53 | ),
54 | ),
55 | const SizedBox(height: 16),
56 | SizedBox(
57 | width: double.infinity,
58 | child: FilledButton(
59 | onPressed: onDismiss,
60 | child: const Text('Dismiss'),
61 | ),
62 | ),
63 | ],
64 | ),
65 | );
66 | }
67 |
68 | void _removeItem(WidgetRef ref, SuspiciousAppInfo item) {
69 | ref.read(threatProvider.notifier).removeMalware(item);
70 | }
71 |
72 | Future _whitelistApp(SuspiciousAppInfo malware) async {
73 | await TalsecService.whitelistApp(malware);
74 | }
75 |
76 | Future _launchUninstall(SuspiciousAppInfo item) async {
77 | // Launch uninstall intent
78 | final packageName = item.packageInfo.packageName;
79 | await AndroidIntent(
80 | action: 'action_application_details_settings',
81 | data: 'package:$packageName',
82 | ).launch();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/home/views/views.dart:
--------------------------------------------------------------------------------
1 | export 'home_page.dart';
2 | export 'malware_bottom_sheet.dart';
3 |
--------------------------------------------------------------------------------
/lib/home/widgets/app_icon.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | /// Displays the app icon or a default warning icon if unavailable
6 | class AppIcon extends StatelessWidget {
7 | const AppIcon({super.key, this.base64Icon});
8 |
9 | final String? base64Icon;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | if (base64Icon == null) {
14 | return const Icon(Icons.warning, color: Colors.red);
15 | }
16 |
17 | return Padding(
18 | padding: const EdgeInsets.all(4),
19 | child: Image.memory(base64.decode(base64Icon!)),
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/lib/home/widgets/dismiss_background.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// Dismiss background widget with a customizable message
4 | class DismissBackground extends StatelessWidget {
5 | const DismissBackground({required this.message, super.key});
6 |
7 | final String message;
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | final textTheme = Theme.of(context).textTheme;
12 | return Container(
13 | color: Colors.amber,
14 | alignment: Alignment.centerLeft,
15 | padding: const EdgeInsets.only(left: 16),
16 | child: Row(
17 | children: [
18 | const Icon(Icons.close, color: Colors.white),
19 | const SizedBox(width: 8),
20 | Text(
21 | message.toUpperCase(),
22 | style: textTheme.labelLarge?.copyWith(color: Colors.white),
23 | ),
24 | ],
25 | ),
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/home/widgets/malware_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:free_malware_detection/home/widgets/widgets.dart';
3 | import 'package:freerasp/freerasp.dart';
4 |
5 | extension on PackageInfo {
6 | String get validAppName => appName ?? packageName;
7 | }
8 |
9 | /// List tile widget that displays malware information
10 | class MalwareItem extends StatelessWidget {
11 | /// Represents malware information in the example app
12 | const MalwareItem({
13 | required this.packageInfo,
14 | required this.reason,
15 | this.onWhitelist,
16 | this.onUninstall,
17 | this.onDismiss,
18 | super.key,
19 | });
20 |
21 | final PackageInfo packageInfo;
22 | final String reason;
23 | final void Function()? onWhitelist;
24 | final void Function()? onUninstall;
25 | final void Function()? onDismiss;
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return Dismissible(
30 | key: ValueKey(packageInfo.packageName),
31 | onDismissed: (_) => onDismiss?.call(),
32 | direction: DismissDirection.startToEnd,
33 | background: const DismissBackground(message: 'Dismiss'),
34 | child: ExpansionTile(
35 | tilePadding: const EdgeInsets.all(8),
36 | title: Text(packageInfo.validAppName),
37 | leading: AppIcon(base64Icon: packageInfo.appIcon),
38 | children: [
39 | ListTile(
40 | title: const Text('Package Name'),
41 | subtitle: Text(packageInfo.packageName),
42 | ),
43 | ListTile(
44 | title: const Text('Installation Source'),
45 | subtitle: Text(packageInfo.installationSource ?? 'Unknown'),
46 | ),
47 | ListTile(
48 | title: const Text('Version'),
49 | subtitle: Text(packageInfo.version ?? 'Unknown'),
50 | ),
51 | ListTile(
52 | title: const Text('Detection Reason'),
53 | subtitle: Text(reason),
54 | ),
55 | OverflowBar(
56 | alignment: MainAxisAlignment.end,
57 | children: [
58 | TextButton(
59 | onPressed: () => onWhitelist?.call(),
60 | child: const Text('Whitelist'),
61 | ),
62 | TextButton(
63 | onPressed: () => onUninstall?.call(),
64 | child: const Text('Uninstall'),
65 | ),
66 | ],
67 | ),
68 | ],
69 | ),
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lib/home/widgets/spinning_icon.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SpinningIcon extends StatefulWidget {
4 | const SpinningIcon({
5 | required this.icon,
6 | required this.iconColor,
7 | super.key,
8 | });
9 |
10 | final IconData icon;
11 | final Color iconColor;
12 |
13 | @override
14 | State createState() => _SpinningIconState();
15 | }
16 |
17 | class _SpinningIconState extends State
18 | with SingleTickerProviderStateMixin {
19 | late final AnimationController _controller = AnimationController(
20 | duration: const Duration(milliseconds: 1000),
21 | vsync: this,
22 | )..repeat();
23 |
24 | late final Animation _curvedAnimation = CurvedAnimation(
25 | parent: _controller,
26 | curve: Curves.decelerate,
27 | );
28 |
29 | @override
30 | void dispose() {
31 | _controller.dispose(); // Dispose of the controller to free resources
32 | super.dispose();
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return RotationTransition(
38 | turns: _curvedAnimation,
39 | child: Icon(widget.icon, color: widget.iconColor),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/home/widgets/status_tile.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:free_malware_detection/home/widgets/widgets.dart';
3 |
4 | class StatusTile extends StatelessWidget {
5 | const StatusTile({
6 | required this.title,
7 | required this.subtitle,
8 | required this.icon,
9 | required this.iconColor,
10 | super.key,
11 | this.isSpinning = false,
12 | });
13 |
14 | final String title;
15 | final String subtitle;
16 | final IconData icon;
17 | final Color iconColor;
18 | final bool isSpinning;
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return ListTile(
23 | trailing: isSpinning
24 | ? SpinningIcon(icon: icon, iconColor: iconColor)
25 | : Icon(icon, color: iconColor),
26 | title: Text(title),
27 | subtitle: Text(subtitle),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/home/widgets/widgets.dart:
--------------------------------------------------------------------------------
1 | export 'app_icon.dart';
2 | export 'dismiss_background.dart';
3 | export 'malware_item.dart';
4 | export 'spinning_icon.dart';
5 | export 'status_tile.dart';
6 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: public_member_api_docs, avoid_redundant_argument_values
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_riverpod/flutter_riverpod.dart';
5 | import 'package:free_malware_detection/app.dart';
6 | import 'package:free_malware_detection/home/providers/providers.dart';
7 | import 'package:free_malware_detection/services/talsec_service.dart';
8 |
9 | /// Represents current state of the threats detectable by freeRASP
10 | final threatProvider =
11 | NotifierProvider.autoDispose(
12 | ThreatNotifier.new,
13 | );
14 |
15 | Future main() async {
16 | WidgetsFlutterBinding.ensureInitialized();
17 | await TalsecService.initialize();
18 | runApp(const ProviderScope(child: App()));
19 | }
20 |
--------------------------------------------------------------------------------
/lib/services/services.dart:
--------------------------------------------------------------------------------
1 | export 'talsec_service.dart';
2 |
--------------------------------------------------------------------------------
/lib/services/talsec_service.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: avoid_redundant_argument_values
2 |
3 | import 'package:freerasp/freerasp.dart';
4 |
5 | class TalsecService {
6 | static Future initialize() async {
7 | final config = TalsecConfig(
8 | androidConfig: AndroidConfig(
9 | // ❗️ Do not retrieve any package information dynamically using
10 | // ❗️ package_info_plus or similar packages. These can return false
11 | // ❗️ information when the app is spoofed.
12 | packageName: 'app.talsec.free_malware_detection',
13 | signingCertHashes: ['AKoRuyLMM91E7lX/Zqp3u4jMmd0A7hH/Iqozu0TMVd0='],
14 | supportedStores: ['com.sec.android.app.samsungapps'],
15 | malwareConfig: MalwareConfig(
16 | // Let app detect itself as malware
17 | blacklistedPackageNames: ['app.talsec.free_malware_detection'],
18 | // Apps CANNOT have these (groups) of permissions
19 | suspiciousPermissions: [
20 | [
21 | 'android.permission.CAMERA',
22 | ],
23 | /* OR */
24 | [
25 | 'android.permission.READ_SMS',
26 | /* AND */
27 | 'android.permission.READ_CONTACTS',
28 | ],
29 | ],
30 | ),
31 | ),
32 | watcherMail: 'your_mail@example.com',
33 | isProd: true,
34 | );
35 |
36 | await Talsec.instance.start(config);
37 | }
38 |
39 | static Future whitelistApp(SuspiciousAppInfo malware) async {
40 | await Talsec.instance.addToWhitelist(malware.packageInfo.packageName);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | android_intent_plus:
5 | dependency: "direct main"
6 | description:
7 | name: android_intent_plus
8 | sha256: e1c62bb41c90e15083b7fb84dc327fe90396cc9c1445b55ff1082144fabfb4d9
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "4.0.3"
12 | async:
13 | dependency: transitive
14 | description:
15 | name: async
16 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.11.0"
20 | boolean_selector:
21 | dependency: transitive
22 | description:
23 | name: boolean_selector
24 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "2.1.1"
28 | characters:
29 | dependency: transitive
30 | description:
31 | name: characters
32 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.3.0"
36 | clock:
37 | dependency: transitive
38 | description:
39 | name: clock
40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.1.1"
44 | collection:
45 | dependency: transitive
46 | description:
47 | name: collection
48 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.18.0"
52 | convert:
53 | dependency: transitive
54 | description:
55 | name: convert
56 | sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "3.1.2"
60 | fake_async:
61 | dependency: transitive
62 | description:
63 | name: fake_async
64 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "1.3.1"
68 | flutter:
69 | dependency: "direct main"
70 | description: flutter
71 | source: sdk
72 | version: "0.0.0"
73 | flutter_plugin_android_lifecycle:
74 | dependency: transitive
75 | description:
76 | name: flutter_plugin_android_lifecycle
77 | sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda"
78 | url: "https://pub.dev"
79 | source: hosted
80 | version: "2.0.22"
81 | flutter_riverpod:
82 | dependency: "direct main"
83 | description:
84 | name: flutter_riverpod
85 | sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1"
86 | url: "https://pub.dev"
87 | source: hosted
88 | version: "2.6.1"
89 | flutter_test:
90 | dependency: "direct dev"
91 | description: flutter
92 | source: sdk
93 | version: "0.0.0"
94 | freerasp:
95 | dependency: "direct main"
96 | description:
97 | name: freerasp
98 | sha256: f18b728a54b27d1dfc4666df27a12d04da4943072c65f3ad06a648f877979ba7
99 | url: "https://pub.dev"
100 | source: hosted
101 | version: "6.8.0"
102 | json_annotation:
103 | dependency: transitive
104 | description:
105 | name: json_annotation
106 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
107 | url: "https://pub.dev"
108 | source: hosted
109 | version: "4.9.0"
110 | leak_tracker:
111 | dependency: transitive
112 | description:
113 | name: leak_tracker
114 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
115 | url: "https://pub.dev"
116 | source: hosted
117 | version: "10.0.5"
118 | leak_tracker_flutter_testing:
119 | dependency: transitive
120 | description:
121 | name: leak_tracker_flutter_testing
122 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "3.0.5"
126 | leak_tracker_testing:
127 | dependency: transitive
128 | description:
129 | name: leak_tracker_testing
130 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
131 | url: "https://pub.dev"
132 | source: hosted
133 | version: "3.0.1"
134 | matcher:
135 | dependency: transitive
136 | description:
137 | name: matcher
138 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
139 | url: "https://pub.dev"
140 | source: hosted
141 | version: "0.12.16+1"
142 | material_color_utilities:
143 | dependency: transitive
144 | description:
145 | name: material_color_utilities
146 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
147 | url: "https://pub.dev"
148 | source: hosted
149 | version: "0.11.1"
150 | meta:
151 | dependency: transitive
152 | description:
153 | name: meta
154 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
155 | url: "https://pub.dev"
156 | source: hosted
157 | version: "1.15.0"
158 | path:
159 | dependency: transitive
160 | description:
161 | name: path
162 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
163 | url: "https://pub.dev"
164 | source: hosted
165 | version: "1.9.0"
166 | platform:
167 | dependency: transitive
168 | description:
169 | name: platform
170 | sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
171 | url: "https://pub.dev"
172 | source: hosted
173 | version: "3.1.6"
174 | riverpod:
175 | dependency: transitive
176 | description:
177 | name: riverpod
178 | sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959"
179 | url: "https://pub.dev"
180 | source: hosted
181 | version: "2.6.1"
182 | sky_engine:
183 | dependency: transitive
184 | description: flutter
185 | source: sdk
186 | version: "0.0.99"
187 | source_span:
188 | dependency: transitive
189 | description:
190 | name: source_span
191 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
192 | url: "https://pub.dev"
193 | source: hosted
194 | version: "1.10.0"
195 | stack_trace:
196 | dependency: transitive
197 | description:
198 | name: stack_trace
199 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
200 | url: "https://pub.dev"
201 | source: hosted
202 | version: "1.11.1"
203 | state_notifier:
204 | dependency: transitive
205 | description:
206 | name: state_notifier
207 | sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb
208 | url: "https://pub.dev"
209 | source: hosted
210 | version: "1.0.0"
211 | stream_channel:
212 | dependency: transitive
213 | description:
214 | name: stream_channel
215 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
216 | url: "https://pub.dev"
217 | source: hosted
218 | version: "2.1.2"
219 | string_scanner:
220 | dependency: transitive
221 | description:
222 | name: string_scanner
223 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
224 | url: "https://pub.dev"
225 | source: hosted
226 | version: "1.2.0"
227 | term_glyph:
228 | dependency: transitive
229 | description:
230 | name: term_glyph
231 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
232 | url: "https://pub.dev"
233 | source: hosted
234 | version: "1.2.1"
235 | test_api:
236 | dependency: transitive
237 | description:
238 | name: test_api
239 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
240 | url: "https://pub.dev"
241 | source: hosted
242 | version: "0.7.2"
243 | typed_data:
244 | dependency: transitive
245 | description:
246 | name: typed_data
247 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
248 | url: "https://pub.dev"
249 | source: hosted
250 | version: "1.3.2"
251 | vector_math:
252 | dependency: transitive
253 | description:
254 | name: vector_math
255 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
256 | url: "https://pub.dev"
257 | source: hosted
258 | version: "2.1.4"
259 | very_good_analysis:
260 | dependency: "direct dev"
261 | description:
262 | name: very_good_analysis
263 | sha256: "1fb637c0022034b1f19ea2acb42a3603cbd8314a470646a59a2fb01f5f3a8629"
264 | url: "https://pub.dev"
265 | source: hosted
266 | version: "6.0.0"
267 | vm_service:
268 | dependency: transitive
269 | description:
270 | name: vm_service
271 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
272 | url: "https://pub.dev"
273 | source: hosted
274 | version: "14.2.5"
275 | sdks:
276 | dart: ">=3.4.1 <4.0.0"
277 | flutter: ">=3.22.0"
278 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: free_malware_detection
2 | description: "Flutter malware detection library for Android. Protect your app against potential threats with Talsec."
3 | publish_to: 'none'
4 | version: 1.0.0
5 |
6 | environment:
7 | sdk: '>=3.4.1 <4.0.0'
8 |
9 | dependencies:
10 | android_intent_plus: 4.0.3
11 | flutter:
12 | sdk: flutter
13 | flutter_riverpod: ^2.6.1
14 | freerasp: 6.8.0
15 |
16 | dev_dependencies:
17 | flutter_test:
18 | sdk: flutter
19 | very_good_analysis: ^6.0.0
20 |
21 | flutter:
22 | uses-material-design: true
23 |
--------------------------------------------------------------------------------