mirror of
https://github.com/QM4RS/FridaBox.git
synced 2026-09-16 14:12:11 +02:00
195 lines
7.2 KiB
Groovy
195 lines
7.2 KiB
Groovy
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.jetbrains.kotlin.android)
|
|
}
|
|
|
|
def releaseStoreFile = System.getenv("FRIDABOX_RELEASE_STORE_FILE")
|
|
def releaseStorePassword = System.getenv("FRIDABOX_RELEASE_STORE_PASSWORD")
|
|
def releaseKeyAlias = System.getenv("FRIDABOX_RELEASE_KEY_ALIAS")
|
|
def releaseKeyPassword = System.getenv("FRIDABOX_RELEASE_KEY_PASSWORD")
|
|
def releaseSigningValues = [releaseStoreFile, releaseStorePassword, releaseKeyAlias, releaseKeyPassword]
|
|
def releaseSigningConfigured = releaseSigningValues.every { it != null && !it.trim().isEmpty() }
|
|
if (releaseSigningValues.any { it != null && !it.trim().isEmpty() } && !releaseSigningConfigured) {
|
|
throw new GradleException("Release signing is incomplete. Set all four FRIDABOX_RELEASE_* environment variables.")
|
|
}
|
|
|
|
android {
|
|
|
|
namespace 'com.qm4rs.fridabox'
|
|
compileSdk rootProject.ext.compileSdkVersion
|
|
ndkVersion = "29.0.14206865"
|
|
defaultConfig {
|
|
applicationId "com.qm4rs.fridabox"
|
|
minSdk rootProject.ext.minSdk
|
|
targetSdk rootProject.ext.targetSdkVersion
|
|
versionCode rootProject.ext.versionCode
|
|
versionName rootProject.ext.versionName
|
|
|
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
|
|
splits {
|
|
abi {
|
|
enable true
|
|
reset()
|
|
|
|
include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
|
universalApk false
|
|
}
|
|
}
|
|
}
|
|
|
|
signingConfigs {
|
|
if (releaseSigningConfigured) {
|
|
release {
|
|
storeFile file(releaseStoreFile)
|
|
storePassword releaseStorePassword
|
|
keyAlias releaseKeyAlias
|
|
keyPassword releaseKeyPassword
|
|
}
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
release {
|
|
if (releaseSigningConfigured) {
|
|
signingConfig signingConfigs.release
|
|
}
|
|
minifyEnabled true
|
|
shrinkResources true
|
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
}
|
|
}
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_21
|
|
targetCompatibility JavaVersion.VERSION_21
|
|
}
|
|
buildFeatures {
|
|
viewBinding true
|
|
buildConfig true
|
|
}
|
|
sourceSets {
|
|
debug.assets.srcDir("$buildDir/generated/demoGuestAssets")
|
|
}
|
|
kotlinOptions {
|
|
jvmTarget = '21'
|
|
}
|
|
packaging {
|
|
jniLibs {
|
|
excludes.add("**/libandroidx.graphics.path.so")
|
|
useLegacyPackaging true
|
|
}
|
|
resources {
|
|
excludes.add("**/libandroidx.graphics.path.so")
|
|
}
|
|
}
|
|
applicationVariants.configureEach { variant ->
|
|
variant.outputs.configureEach { output ->
|
|
output.outputFileName = "FridaBox_${variant.versionName}_${output.baseName}.apk"
|
|
}
|
|
}
|
|
lint {
|
|
abortOnError false
|
|
checkReleaseBuilds false
|
|
}
|
|
}
|
|
|
|
tasks.register("copyDemoGuestDebug", Copy) {
|
|
dependsOn(":sample-guest:assembleDebug")
|
|
from(project(":sample-guest").layout.buildDirectory.file("outputs/apk/debug/sample-guest-debug.apk"))
|
|
into(layout.buildDirectory.dir("generated/demoGuestAssets/demo"))
|
|
rename { "sample-guest.apk" }
|
|
}
|
|
tasks.matching { it.name == "mergeDebugAssets" }.configureEach { dependsOn("copyDemoGuestDebug") }
|
|
tasks.matching { it.name.toLowerCase().contains("debug") && it.name.toLowerCase().contains("lint") }
|
|
.configureEach { dependsOn("copyDemoGuestDebug") }
|
|
|
|
tasks.register("verifyDebugApkHasNoGadget") {
|
|
dependsOn("assembleDebug")
|
|
doLast {
|
|
def apks = fileTree("$buildDir/outputs/apk/debug").matching { include("*.apk") }.files
|
|
if (apks.isEmpty()) {
|
|
throw new GradleException("No debug APKs were produced")
|
|
}
|
|
apks.each { apk ->
|
|
def entries = zipTree(apk).files.findAll {
|
|
it.name.toLowerCase().contains("gadget") && it.name.toLowerCase().endsWith(".so")
|
|
}
|
|
if (!entries.isEmpty()) {
|
|
throw new GradleException("${apk.name} must not bundle Frida Gadget: ${entries*.name}")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.register("verifyInstrumentationOrdering") {
|
|
doLast {
|
|
def source = project(":Bcore").file("src/main/java/top/niunaijun/blackbox/app/BActivityThread.java").text
|
|
def loader = source.indexOf("FridaGadgetLoader.loadAtProcessBind()")
|
|
def makeApplication = source.indexOf("makeApplication(", loader)
|
|
if (loader < 0 || makeApplication < 0 || loader >= makeApplication) {
|
|
throw new GradleException("Frida Gadget loader must execute before guest makeApplication")
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.register("verifyRuntimeBridgeAssets") {
|
|
doLast {
|
|
def bridgeAssets = [
|
|
"java-7.0.11.js", "java-7.0.12.js", "java-7.0.13.js",
|
|
"il2cpp-0.12.2.js", "il2cpp-0.13.0.js", "il2cpp-0.13.1.js"
|
|
]
|
|
def bridgeRoot = file("src/main/assets/fridabox/bridges")
|
|
bridgeAssets.each { name ->
|
|
def asset = new File(bridgeRoot, name)
|
|
if (!asset.isFile() || asset.length() == 0 || asset.length() > 2 * 1024 * 1024) {
|
|
throw new GradleException("Missing or invalid runtime bridge asset: ${name}")
|
|
}
|
|
def source = new String(asset.bytes, java.nio.charset.StandardCharsets.UTF_8)
|
|
if (!source.startsWith("📦\n") || !source.contains("\n✄\n")) {
|
|
throw new GradleException("Runtime bridge is not a valid frida-compile bundle: ${name}")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.register("verifyTablerAndroidIcons", Exec) {
|
|
workingDir(rootProject.projectDir)
|
|
def nodeExecutable = System.getProperty("os.name").toLowerCase().contains("windows") ? "node.exe" : "node"
|
|
commandLine(nodeExecutable, "tools/generate_tabler_android_icons.mjs", "--check")
|
|
doFirst {
|
|
if (!rootProject.file("node_modules/@tabler/icons/package.json").isFile()) {
|
|
throw new GradleException("Missing @tabler/icons. Run npm ci before building FridaBox.")
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.register("verifyDemoGuestUnmodified") {
|
|
dependsOn("copyDemoGuestDebug")
|
|
doLast {
|
|
def source = project(":sample-guest").layout.buildDirectory.file("outputs/apk/debug/sample-guest-debug.apk").get().asFile
|
|
def embedded = layout.buildDirectory.file("generated/demoGuestAssets/demo/sample-guest.apk").get().asFile
|
|
if (!java.util.Arrays.equals(java.security.MessageDigest.getInstance("SHA-256").digest(source.bytes),
|
|
java.security.MessageDigest.getInstance("SHA-256").digest(embedded.bytes))) {
|
|
throw new GradleException("Embedded sample APK differs from generated sample APK")
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.named("check").configure {
|
|
dependsOn("verifyDebugApkHasNoGadget", "verifyInstrumentationOrdering",
|
|
"verifyDemoGuestUnmodified", "verifyTablerAndroidIcons", "verifyRuntimeBridgeAssets")
|
|
}
|
|
|
|
dependencies {
|
|
implementation project(':Bcore')
|
|
|
|
implementation libs.appcompat
|
|
implementation libs.material
|
|
implementation libs.constraintlayout
|
|
implementation libs.core.ktx
|
|
implementation "org.tukaani:xz:1.12"
|
|
testImplementation libs.junit
|
|
androidTestImplementation libs.ext.junit
|
|
androidTestImplementation libs.espresso.core
|
|
}
|