diff --git a/build.gradle b/build.gradle index 0d0b16a..425e808 100644 --- a/build.gradle +++ b/build.gradle @@ -67,6 +67,9 @@ dependencies { implementation "androidx.room:room-rxjava3:2.6.1" implementation 'io.reactivex.rxjava3:rxandroid:3.0.2' implementation 'io.reactivex.rxjava3:rxjava:3.1.5' + implementation 'com.fasterxml.jackson.jr:jackson-jr-objects:2.18.2' + implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.2' + runtimeOnly 'com.fasterxml.jackson.jr:jackson-jr-annotation-support:2.18.2' compileOnly 'org.projectlombok:lombok:1.18.34' annotationProcessor 'org.projectlombok:lombok:1.18.34' implementation libs.androidx.coordinatorlayout diff --git a/src/main/java/com/alterdekim/frida/config/ClientConfig.java b/src/main/java/com/alterdekim/frida/config/ClientConfig.java new file mode 100644 index 0000000..adf3278 --- /dev/null +++ b/src/main/java/com/alterdekim/frida/config/ClientConfig.java @@ -0,0 +1,31 @@ +package com.alterdekim.frida.config; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.jetbrains.annotations.NotNull; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@ToString +@Getter +public class ClientConfig { + @NotNull + private String private_key; + @NotNull + private String public_key; + @NotNull + private String address; + + @JsonCreator + public ClientConfig(@JsonProperty(required = true, value = "private_key") @NotNull String private_key, + @JsonProperty(required = true, value = "public_key") @NotNull String public_key, + @JsonProperty(required = true, value = "address") @NotNull String address) { + this.private_key = private_key; + this.public_key = public_key; + this.address = address; + } +} diff --git a/src/main/java/com/alterdekim/frida/config/Config.java b/src/main/java/com/alterdekim/frida/config/Config.java new file mode 100644 index 0000000..8ae17b9 --- /dev/null +++ b/src/main/java/com/alterdekim/frida/config/Config.java @@ -0,0 +1,27 @@ +package com.alterdekim.frida.config; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.jetbrains.annotations.NotNull; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@ToString +@Getter +@NoArgsConstructor +public class Config { + @NotNull + @JsonProperty(required = true) + private ClientConfig client; + @NotNull + @JsonProperty(required = true) + private ServerConfig server; + + public Config(@JsonProperty(required = true, value = "client") @NotNull ClientConfig client, @JsonProperty(required = true, value = "server") @NotNull ServerConfig server) { + this.client = client; + this.server = server; + } +} diff --git a/src/main/java/com/alterdekim/frida/config/ServerConfig.java b/src/main/java/com/alterdekim/frida/config/ServerConfig.java new file mode 100644 index 0000000..3d8affe --- /dev/null +++ b/src/main/java/com/alterdekim/frida/config/ServerConfig.java @@ -0,0 +1,32 @@ +package com.alterdekim.frida.config; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.jetbrains.annotations.NotNull; + +import lombok.Getter; +import lombok.ToString; + +@ToString +@Getter +public class ServerConfig { + @NotNull + private String public_key; + @NotNull + private String endpoint; + @NotNull + private String internal_gateway; + private byte keepalive; + + @JsonCreator + public ServerConfig(@JsonProperty(required = true, value = "public_key") @NotNull String public_key, + @JsonProperty(required = true, value = "endpoint") @NotNull String endpoint, + @JsonProperty(required = true, value = "internal_gateway") @NotNull String internal_gateway, + @JsonProperty(required = true, value = "keepalive") byte keepalive) { + this.public_key = public_key; + this.endpoint = endpoint; + this.internal_gateway = internal_gateway; + this.keepalive = keepalive; + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java b/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java index 5b4619d..23d3813 100644 --- a/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java +++ b/src/main/java/com/alterdekim/fridaapp/activity/MainActivity.java @@ -55,8 +55,8 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI try { String raw_data = Util.readTextFromUri(this, data.getData()); String name = Util.getFilenameFromUri(this, data.getData()); - String hex = Util.bytesToHex(raw_data.getBytes()); - this.controller.insertNewConfig(name, hex); + byte[] config = raw_data.getBytes(); + this.controller.insertNewConfig(name, config); } catch (IOException e) { Log.e(TAG, e.getMessage()); } diff --git a/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java b/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java index 2dd1623..108ebea 100644 --- a/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java +++ b/src/main/java/com/alterdekim/fridaapp/controller/MainActivityController.java @@ -16,8 +16,12 @@ import com.alterdekim.fridaapp.activity.SingleConfigActivity; import com.alterdekim.fridaapp.room.AppDatabase; import com.alterdekim.fridaapp.room.Config; import com.alterdekim.fridaapp.service.FridaService; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.android.material.switchmaterial.SwitchMaterial; +import java.io.IOException; import java.util.Iterator; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -59,8 +63,8 @@ public class MainActivityController implements IController { Config config = iter.next(); View cfg_instance = inflater.inflate(R.layout.single_config, this.mainActivity.getCfg_list(), false); this.mainActivity.getCfg_list().addView(cfg_instance); - TextView view_name = (TextView) cfg_instance.findViewById(R.id.config_name); - SwitchMaterial view_switch = (SwitchMaterial) cfg_instance.findViewById(R.id.config_switch); + TextView view_name = cfg_instance.findViewById(R.id.config_name); + SwitchMaterial view_switch = cfg_instance.findViewById(R.id.config_switch); view_switch.setUseMaterialThemeColors(true); view_switch.setOnCheckedChangeListener((compoundButton, b) -> toggleVpn(view_switch, config, b)); view_name.setText(config.getTitle()); @@ -75,8 +79,17 @@ public class MainActivityController implements IController { .subscribe(); } - public void insertNewConfig(String name, String hex) { - db.userDao().insertAll(new Config(name, hex)) + public void insertNewConfig(String name, byte[] config) { + try { + com.alterdekim.frida.config.Config cfg = new ObjectMapper(new YAMLFactory()).setAnnotationIntrospector(new JacksonAnnotationIntrospector()).readValue(config, com.alterdekim.frida.config.Config.class); + Log.i(TAG, cfg.toString()); + } catch (IOException e) { + Log.e(TAG, "Can't parse config"); + e.printStackTrace(); + Toast.makeText(this.mainActivity, R.string.config_adding_error, Toast.LENGTH_LONG).show(); + return; + } + db.userDao().insertAll(new Config(name, config)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(throwable -> Toast.makeText(MainActivityController.this.mainActivity, R.string.config_adding_error, Toast.LENGTH_LONG).show()) @@ -86,7 +99,7 @@ public class MainActivityController implements IController { private void toggleVpn(SwitchMaterial view, Config config, boolean val) { Intent intent = new Intent(this.mainActivity, FridaService.class); - intent.putExtra("vpn_hex", config.getData_hex()); + intent.putExtra("vpn_data", config.getData_raw()); intent.putExtra("vpn_uid", config.getUid()); intent.putExtra("vpn_state", val); this.mainActivity.startService(intent); diff --git a/src/main/java/com/alterdekim/fridaapp/room/Config.java b/src/main/java/com/alterdekim/fridaapp/room/Config.java index 83f0027..c5c7ffa 100644 --- a/src/main/java/com/alterdekim/fridaapp/room/Config.java +++ b/src/main/java/com/alterdekim/fridaapp/room/Config.java @@ -21,6 +21,6 @@ public class Config { @ColumnInfo(name = "title") private final String title; - @ColumnInfo(name = "data_hex") - private final String data_hex; + @ColumnInfo(name = "data_raw") + private final byte[] data_raw; } diff --git a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java index a4a8bc1..398eadb 100644 --- a/src/main/java/com/alterdekim/fridaapp/service/FridaService.java +++ b/src/main/java/com/alterdekim/fridaapp/service/FridaService.java @@ -6,6 +6,10 @@ import android.os.ParcelFileDescriptor; import android.util.Log; import com.alterdekim.frida.FridaLib; +import com.alterdekim.frida.config.Config; +import com.alterdekim.fridaapp.util.Util; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import java.io.BufferedReader; import java.io.File; @@ -20,7 +24,6 @@ import io.reactivex.rxjava3.schedulers.Schedulers; public class FridaService extends VpnService { private static final String TAG = FridaService.class.getSimpleName(); - private static final String VPN_ADDRESS = "10.66.66.6"; // Only IPv4 support for now private static final String VPN_ROUTE = "0.0.0.0"; // Intercept everything private ParcelFileDescriptor vpnInterface = null; @@ -36,8 +39,9 @@ public class FridaService extends VpnService { Log.i(TAG, "Created"); } - private void setupVPN() { + private void setupVPN(byte[] cfg_raw) { try { + Config config = new ObjectMapper(new YAMLFactory()).readValue(cfg_raw, Config.class); File outputDir = this.getCacheDir(); // context being the Activity pointer File outputFile = new File(outputDir, "fridalib.log"); if( outputFile.exists() ) { outputFile.delete(); } @@ -61,9 +65,9 @@ public class FridaService extends VpnService { Builder builder = new Builder(); builder.setMtu(1400); - builder.addAddress(VPN_ADDRESS, 24); + builder.addAddress(config.getClient().getAddress(), 24); builder.addRoute(VPN_ROUTE, 0); - builder.addDnsServer("8.8.8.8"); + //builder.addDnsServer("8.8.8.8"); //builder.addAllowedApplication(); builder.addDisallowedApplication("com.alterdekim.fridaapp"); vpnInterface = builder.establish(); @@ -95,16 +99,16 @@ public class FridaService extends VpnService { @Override public int onStartCommand(Intent intent, int flags, int startId) { if( intent.getExtras() == null ) return START_STICKY; - String hex = intent.getExtras().getString("vpn_hex"); + byte[] config = intent.getExtras().getByteArray("vpn_data"); int uid = intent.getExtras().getInt("vpn_uid"); boolean state = intent.getExtras().getBoolean("vpn_state"); if(!state) { this.lib.stop(); return START_STICKY; } - setupVPN(); + setupVPN(config); // TODO: different configs - this.vpnProcess = Flowable.fromRunnable(new NativeBinaryConnection(vpnInterface.detachFd(), hex, lib, logPath)) + this.vpnProcess = Flowable.fromRunnable(new NativeBinaryConnection(vpnInterface.detachFd(), Util.bytesToHex(config), lib, logPath)) .subscribeOn(Schedulers.newThread()) .observeOn(Schedulers.newThread()) .subscribe(); diff --git a/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java b/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java index 5ba9ec2..a256b5f 100644 --- a/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java +++ b/src/main/java/com/alterdekim/fridaapp/service/NativeBinaryConnection.java @@ -4,6 +4,8 @@ import android.util.Log; import com.alterdekim.frida.FridaLib; +import java.util.Objects; + import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -20,10 +22,10 @@ public class NativeBinaryConnection implements Runnable { try { Log.i(TAG, "FD: " + this.fd); Log.i(TAG, "Starting Frida client"); - int r = lib.start(this.hex.toLowerCase(), this.fd, false, this.tempFile); + int r = lib.start(this.hex, this.fd, false, this.tempFile); Log.i(TAG, "Exit code: " + r); } catch (Exception e) { - Log.e(TAG, e.getMessage()); + Log.e(TAG, Objects.requireNonNull(e.getMessage())); } } } diff --git a/src/main/java/com/alterdekim/fridaapp/util/Util.java b/src/main/java/com/alterdekim/fridaapp/util/Util.java index 2a2f22e..458fc95 100644 --- a/src/main/java/com/alterdekim/fridaapp/util/Util.java +++ b/src/main/java/com/alterdekim/fridaapp/util/Util.java @@ -34,7 +34,7 @@ public class Util { return "default"; } - private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) {