diff --git a/build.gradle b/build.gradle index 6a06ade..13e0db0 100644 --- a/build.gradle +++ b/build.gradle @@ -33,17 +33,17 @@ android { task downloadAarch(type: Download) { src 'https://jenkins.awain.net/job/Frida-android-binaries/lastSuccessfulBuild/artifact/jniLibs/arm64-v8a/frida.so' - dest layout.projectDirectory.file('src/main/jniLibs/arm64-v8a/frida.so') + dest layout.projectDirectory.file('src/main/jniLibs/arm64-v8a/libfrida.so') } task downloadArmeabi(type: Download) { src 'https://jenkins.awain.net/job/Frida-android-binaries/lastSuccessfulBuild/artifact/jniLibs/armeabi-v7a/frida.so' - dest layout.projectDirectory.file('src/main/jniLibs/armeabi-v7a/frida.so') + dest layout.projectDirectory.file('src/main/jniLibs/armeabi-v7a/libfrida.so') } task downloadx86(type: Download, ) { src 'https://jenkins.awain.net/job/Frida-android-binaries/lastSuccessfulBuild/artifact/jniLibs/x86/frida.so' - dest layout.projectDirectory.file('src/main/jniLibs/x86/frida.so') + dest layout.projectDirectory.file('src/main/jniLibs/x86/libfrida.so') } task deleteLibs(type: Delete) { @@ -52,19 +52,21 @@ task deleteLibs(type: Delete) { } } -preBuild.dependsOn deleteLibs -preBuild.dependsOn downloadAarch +//preBuild.dependsOn deleteLibs +//preBuild.dependsOn downloadAarch /*preBuild.dependsOn downloadArmeabi preBuild.dependsOn downloadx86*/ dependencies { implementation libs.okhttp - implementation libs.ground.crockford32 + implementation libs.commons.codec implementation libs.ktsh implementation libs.appcompat implementation libs.material implementation libs.activity implementation libs.constraintlayout + implementation libs.room.runtime + annotationProcessor libs.room.compiler testImplementation libs.junit androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 3a5505e..02855a4 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:installLocation="internalOnly"> @@ -9,19 +9,21 @@ diff --git a/src/main/java/com/alterdekim/frida/FridaLib.java b/src/main/java/com/alterdekim/frida/FridaLib.java index 6cc6005..f07916f 100644 --- a/src/main/java/com/alterdekim/frida/FridaLib.java +++ b/src/main/java/com/alterdekim/frida/FridaLib.java @@ -1,4 +1,18 @@ package com.alterdekim.frida; +import android.util.Log; + public class FridaLib { + + static { + System.loadLibrary("frida"); + } + + public native int start(String config_b32, int tun_fd, boolean close_fd_on_drop); + + public native int stop(); + + private static void traceFromNative(String text) { + Log.i("FridaLib", text); + } } diff --git a/src/main/java/com/alterdekim/fridaapp/MainActivity.java b/src/main/java/com/alterdekim/fridaapp/MainActivity.java index a4c11f6..a322eef 100644 --- a/src/main/java/com/alterdekim/fridaapp/MainActivity.java +++ b/src/main/java/com/alterdekim/fridaapp/MainActivity.java @@ -1,10 +1,16 @@ package com.alterdekim.fridaapp; +import android.app.Activity; import android.content.Intent; +import android.net.Uri; import android.net.VpnService; import android.os.Bundle; import android.util.Log; +import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; +import android.widget.PopupMenu; +import android.widget.Toast; import androidx.activity.EdgeToEdge; import androidx.activity.result.ActivityResultLauncher; @@ -13,18 +19,41 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; +import androidx.room.Room; +import com.alterdekim.fridaapp.room.AppDatabase; +import com.alterdekim.fridaapp.room.Config; import com.alterdekim.fridaapp.service.FridaService; -public class MainActivity extends AppCompatActivity { +import org.apache.commons.codec.binary.Base32; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener { private static final String TAG = MainActivity.class.getSimpleName(); + private AppDatabase db; + + ActivityResultLauncher someActivityResultLauncher = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() != Activity.RESULT_OK) return; + Intent data = result.getData(); + try { + String raw_data = Util.readTextFromUri(this, data.getData()); + String name = Util.getFilenameFromUri(this, data.getData()); + String b32 = Base32.builder().get().encodeToString(raw_data.getBytes(StandardCharsets.UTF_8)); + db.userDao().insertAll(new Config(name, b32)); + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + }); private final ActivityResultLauncher launcher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { - if (result.getResultCode() == RESULT_OK) { - startService(new Intent(this, FridaService.class)); - } + if (result.getResultCode() != RESULT_OK) return; + startService(new Intent(this, FridaService.class)); } ); @@ -33,23 +62,54 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.activity_main); + this.db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "def-db").build(); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); + findViewById(R.id.addConfig).setOnClickListener(v -> { + PopupMenu popup = new PopupMenu(this, v); + popup.setOnMenuItemClickListener(MainActivity.this); + popup.getMenuInflater().inflate(R.menu.mm, popup.getMenu()); + popup.show(); + }); - findViewById(R.id.start_btn).setOnClickListener(view -> startVpn()); + LayoutInflater inflater = getLayoutInflater(); + for( Config config : db.userDao().getAll() ) { + + View myLayout = inflater.inflate(R.layout.single_config, mainLayout, false); + } + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + if( item.getItemId() == R.id.new_config ) { + newConfig(); + return true; + } else if( item.getItemId() == R.id.import_from_file ) { + importConfigFromFile(); + return true; + } + return false; + } + + private void newConfig() { + Toast.makeText(this, "newConfig", Toast.LENGTH_LONG).show(); + } + + private void importConfigFromFile() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("application/*"); + someActivityResultLauncher.launch(intent); } private void startVpn() { Intent intent = VpnService.prepare(MainActivity.this); if (intent != null) { - Log.i("ASD", "!= null"); launcher.launch(intent); - } else { - Log.i("ASD", "== null"); - startService(new Intent(this, FridaService.class)); + return; } + startService(new Intent(this, FridaService.class)); } } \ No newline at end of file diff --git a/src/main/java/com/alterdekim/fridaapp/Util.java b/src/main/java/com/alterdekim/fridaapp/Util.java new file mode 100644 index 0000000..cc0807e --- /dev/null +++ b/src/main/java/com/alterdekim/fridaapp/Util.java @@ -0,0 +1,37 @@ +package com.alterdekim.fridaapp; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.OpenableColumns; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Objects; + +public class Util { + public static String readTextFromUri(Context context, Uri uri) throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + try (InputStream inputStream = + context.getContentResolver().openInputStream(uri); + BufferedReader reader = new BufferedReader( + new InputStreamReader(Objects.requireNonNull(inputStream)))) { + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + } + } + return stringBuilder.toString(); + } + + public static String getFilenameFromUri(Context context, Uri uri) { + try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) { + if (cursor != null && cursor.moveToFirst() && cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) >= 0) { + return cursor.getString(Math.abs(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))); + } + } + return "default"; + } +} diff --git a/src/main/java/com/alterdekim/fridaapp/room/AppDatabase.java b/src/main/java/com/alterdekim/fridaapp/room/AppDatabase.java new file mode 100644 index 0000000..08ce198 --- /dev/null +++ b/src/main/java/com/alterdekim/fridaapp/room/AppDatabase.java @@ -0,0 +1,9 @@ +package com.alterdekim.fridaapp.room; + +import androidx.room.Database; +import androidx.room.RoomDatabase; + +@Database(entities = {Config.class}, version = 1) +public abstract class AppDatabase extends RoomDatabase { + public abstract ConfigDAO userDao(); +} diff --git a/src/main/java/com/alterdekim/fridaapp/room/Config.java b/src/main/java/com/alterdekim/fridaapp/room/Config.java new file mode 100644 index 0000000..39b1c67 --- /dev/null +++ b/src/main/java/com/alterdekim/fridaapp/room/Config.java @@ -0,0 +1,22 @@ +package com.alterdekim.fridaapp.room; + +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity +public class Config { + @PrimaryKey + public int uid; + + @ColumnInfo(name = "title") + public String title; + + @ColumnInfo(name = "data_b32") + public String data_b32; + + public Config(String title, String data_b32) { + this.title = title; + this.data_b32 = data_b32; + } +} diff --git a/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java b/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java new file mode 100644 index 0000000..9ac607e --- /dev/null +++ b/src/main/java/com/alterdekim/fridaapp/room/ConfigDAO.java @@ -0,0 +1,27 @@ +package com.alterdekim.fridaapp.room; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; + +import java.util.List; +import java.util.Optional; + +@Dao +public interface ConfigDAO { + @Query("SELECT * FROM config") + List getAll(); + + @Query("SELECT * FROM config WHERE uid IN (:cfgIds)") + List loadAllByIds(int[] cfgIds); + + @Query("SELECT * FROM config WHERE uid = :cfgId") + Optional loadById(int cfgId); + + @Insert + void insertAll(Config... users); + + @Delete + void delete(Config user); +} diff --git a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java index e3fc218..d3e2178 100644 --- a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java +++ b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java @@ -6,6 +6,7 @@ import android.net.VpnService; import android.os.ParcelFileDescriptor; import android.util.Log; +import com.alterdekim.frida.FridaLib; import com.alterdekim.fridaapp.R; import java.io.IOException; @@ -23,14 +24,13 @@ public class FridaService extends VpnService { private ParcelFileDescriptor vpnInterface = null; private PendingIntent pendingIntent; - @Override public void onCreate() { setupVPN(); Log.i(TAG, "Started"); // .detachFd() try { - Thread t = new Thread(new NativeBinaryConnection(vpnInterface.dup().getFd(), getApplicationContext().getApplicationInfo().nativeLibraryDir)); + Thread t = new Thread(new NativeBinaryConnection(vpnInterface.dup().detachFd(), getApplicationContext().getApplicationInfo().nativeLibraryDir)); t.start(); } catch (Exception e) { Log.e(TAG, e.getMessage()); @@ -47,11 +47,11 @@ public class FridaService extends VpnService { .build(); try { try (Response response = client.newCall(request).execute()) { - Log.i(TAG, "Response code: " + response.code()); + // Log.i(TAG, "Response code: " + response.code()); if (response.body() != null) { - Log.i(TAG, "Response body: " + response.body().string()); + // Log.i(TAG, "Response body: " + response.body().string()); } else { - Log.i(TAG, "Response body: null"); + // Log.i(TAG, "Response body: null"); } } } catch (IOException e) { @@ -65,14 +65,15 @@ public class FridaService extends VpnService { try { //if (vpnInterface == null) { Builder builder = new Builder(); - builder.addAddress(VPN_ADDRESS, 32); + builder.setMtu(1400); + builder.addAddress(VPN_ADDRESS, 24); builder.addRoute(VPN_ROUTE, 0); - //builder.addDnsServer("1.1.1.1"); - //builder.setMtu(1400); + builder.addDnsServer("8.8.8.8"); //builder.addAllowedApplication(); - //builder.addDisallowedApplication(); - - vpnInterface = builder.setSession(getString(R.string.app_name)).setConfigureIntent(pendingIntent).establish(); + builder.addDisallowedApplication("com.alterdekim.fridaapp"); + // .setSession(getString(R.string.app_name)) + // .setConfigureIntent(pendingIntent) + vpnInterface = builder.establish(); // } } catch (Exception e) { Log.e(TAG, "error", e); diff --git a/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java b/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java index 347dcd5..99748bb 100644 --- a/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java +++ b/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java @@ -2,6 +2,7 @@ package com.alterdekim.fridaapp.service; import android.util.Log; +import com.alterdekim.frida.FridaLib; import com.jaredrummler.ktsh.Shell; import java.io.BufferedReader; @@ -23,23 +24,10 @@ public class NativeBinaryConnection implements Runnable { public void run() { try { Log.i(TAG, "FD: " + this.fd); - /* Shell shell = new Shell("sh"); - Shell.Command.Result result = shell.run(command); - Log.i(TAG, result.stdout()); - Log.i(TAG, result.stderr());*/ - ProcessBuilder p = new ProcessBuilder("./frida.so", "--fd", fd+"", "--config", "MNWGSZLOOQ5A2CRAEBYHE2LWMF2GKX3LMV4TUIDPMIYTKOBRNFVTMNZSGNTU6ZTKJ4XXS3DIO44WIVZLNRLTE2LCI5ZXISDVIJKVG42MK5MT2DIKEAQHA5LCNRUWGX3LMV4TUIDEMRBWGSSYIFIVS4SRHFWVIRTJOB2HOK3OK5WXOUJXG5IESSSQOAYEU3SLJ5GU6NCLIMYD2DIKEAQGCZDEOJSXG4Z2EAYTALRWGYXDMNROGYGQU43FOJ3GK4R2BUFCAIDQOVRGY2LDL5VWK6J2EBCUUTSROIZVUNKKJBWC65CDLFNC6UDDJZGGWTLTKMYGCS3OMZVGINCKMJ3DMVDVHE3EKTJ5BUFCAIDFNZSHA33JNZ2DUIBRGU4S4MJQGAXDCOBOHA4DUOBXHEZQ2CRAEBVWKZLQMFWGS5TFHIQDEMANBI======").directory(new File(baseDir)); - p.redirectErrorStream(true); - - Process pr = p.start(); - - BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream())); - String line; - while ((line = in.readLine()) != null) { - Log.i(TAG, line); - } - pr.waitFor(); - Log.i(TAG, "ok!"); - in.close(); + FridaLib lib = new FridaLib(); + Log.i(TAG, "Starting Frida client"); + int r = lib.start("", this.fd, false); + Log.i(TAG, "Exit code: " + r); } catch (Exception e) { Log.e(TAG, e.getMessage()); } diff --git a/src/main/res/drawable-v24/ic_launcher_foreground.xml b/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1..0000000 --- a/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/res/drawable/baseline_add_24.xml b/src/main/res/drawable/baseline_add_24.xml new file mode 100644 index 0000000..9f83b8f --- /dev/null +++ b/src/main/res/drawable/baseline_add_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/res/drawable/baseline_create_24.xml b/src/main/res/drawable/baseline_create_24.xml new file mode 100644 index 0000000..3c53db7 --- /dev/null +++ b/src/main/res/drawable/baseline_create_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/res/drawable/baseline_file_open_24.xml b/src/main/res/drawable/baseline_file_open_24.xml new file mode 100644 index 0000000..b4425d0 --- /dev/null +++ b/src/main/res/drawable/baseline_file_open_24.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/res/drawable/ic_launcher_background.xml b/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9..0000000 --- a/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/res/layout/activity_main.xml b/src/main/res/layout/activity_main.xml index fab63b4..c879e1a 100644 --- a/src/main/res/layout/activity_main.xml +++ b/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - -