Skip to content

Commit

Permalink
Listen vpn
Browse files Browse the repository at this point in the history
  • Loading branch information
Nep-Timeline committed Nov 23, 2024
1 parent 463514c commit bbf84a5
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
8 changes: 8 additions & 0 deletions app/src/main/java/nep/timeline/cirno/entity/AppState.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class AppState {
private boolean location = false;
private boolean audio = false;
private boolean recording = false;
private boolean vpn = false;
private final Set<IBinder> activities = new HashSet<>();
private final Set<IBinder> locationListeners = new HashSet<>();
private final Set<Integer> interfaceIds = new HashSet<>();
Expand Down Expand Up @@ -50,4 +51,11 @@ public synchronized boolean setRecording(boolean value) {
recording = value;
return true;
}

public synchronized boolean setVpn(boolean value) {
if (vpn == value)
return false;
vpn = value;
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package nep.timeline.cirno.hooks.android.vpn;

import android.net.NetworkInfo;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import nep.timeline.cirno.entity.AppRecord;
import nep.timeline.cirno.framework.AbstractMethodHook;
import nep.timeline.cirno.framework.MethodHook;
import nep.timeline.cirno.log.Log;
import nep.timeline.cirno.services.AppService;
import nep.timeline.cirno.services.FreezerService;
import nep.timeline.cirno.threads.FreezerHandler;
import nep.timeline.cirno.utils.PKGUtils;

public class VpnStateHook extends MethodHook {
public VpnStateHook(ClassLoader classLoader) {
super(classLoader);
}

@Override
public String getTargetClass() {
return "com.android.server.connectivity.Vpn";
}

@Override
public String getTargetMethod() {
return "updateState";
}

@Override
public Object[] getTargetParam() {
return new Object[] { NetworkInfo.DetailedState.class, String.class };
}

@Override
public XC_MethodHook getTargetHook() {
return new AbstractMethodHook() {
@Override
protected void beforeMethod(XC_MethodHook.MethodHookParam param) {
String state = param.args[0].toString();
int uid = XposedHelpers.getIntField(param.thisObject, "mOwnerUID");
String packageName = (String) XposedHelpers.getObjectField(param.thisObject, "mPackage");

AppRecord appRecord = AppService.get(packageName, PKGUtils.getUserId(uid));
if (appRecord != null) {
if (appRecord.isSystem())
return;

if ("CONNECTED".equals(state) && appRecord.getAppState().setVpn(true)) {
Log.d(appRecord.getPackageNameWithUser() + " 连接至VPN");
FreezerService.thaw(appRecord);
}

if (("DISCONNECTED".equals(state) || "FAILED".equals(state)) && appRecord.getAppState().setVpn(false)) {
Log.d(appRecord.getPackageNameWithUser() + " 从VPN断开连接");
FreezerHandler.sendFreezeMessageIgnoreMessages(appRecord, 3000);
}
}
}
};
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/nep/timeline/cirno/master/AndroidHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import nep.timeline.cirno.hooks.android.recorder.ReleaseRecorderHook;
import nep.timeline.cirno.hooks.android.signal.SendSignalHook;
import nep.timeline.cirno.hooks.android.signal.SendSignalQuietHook;
import nep.timeline.cirno.hooks.android.vpn.VpnStateHook;
import nep.timeline.cirno.hooks.android.wakelock.WakeLockHook;
import nep.timeline.cirno.services.BinderService;

Expand Down Expand Up @@ -76,6 +77,8 @@ public static void start(ClassLoader classLoader) {
// Recorder
new RecorderEventHook(classLoader);
new ReleaseRecorderHook(classLoader);
// Vpn
new VpnStateHook(classLoader);
// ReKernel
BinderService.start(classLoader);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class FreezerService {
public static void freezer(AppRecord appRecord) {
if (appRecord.isFrozen() || appRecord.isSystem() || appRecord.getAppState().isVisible() || appRecord.getAppState().isLocation() || appRecord.getAppState().isAudio() || appRecord.getAppState().isRecording())
if (appRecord.isFrozen() || appRecord.isSystem() || appRecord.getAppState().isVisible() || appRecord.getAppState().isLocation() || appRecord.getAppState().isAudio() || appRecord.getAppState().isRecording() || appRecord.getAppState().isVpn())
return;

for (ProcessRecord processRecord : appRecord.getProcessRecords()) {
Expand Down

0 comments on commit bbf84a5

Please sign in to comment.