12

I am trying to figure out which application on my device has made any internet usage request (called any api etc).. For this I have created a class extended from "VpnService" class just to make sure my device traffic routes through me, although i have not actually connected to a VPN instead i am just faking it and letting the traffic go through me to 0.0.0.0. The code is below, It works fine, but i want to figure out which application has initiated the request for using internet or whose packet is coming in/out in the main while loop below. Also, is there a way I can stop requests from any app - either ways [incoming and outgoing]?

    *private Thread mThread;
private ParcelFileDescriptor mInterface;
//a. Configure a builder for the interface.
Builder builder = new Builder();
// Services interface
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.getApplicationInfo();
    // Start a new session by creating a new thread.
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                //a. Configure the TUN and get the interface.
                mInterface = builder.setSession("MyVPNService")
                        .setMtu(1500)
                        .addAddress("192.168.1.66", 32)
                        .addRoute("0.0.0.0", 0).establish();
                //b. Packets to be sent are queued in this input stream.
                FileInputStream in = new FileInputStream(
                        mInterface.getFileDescriptor());
                //b. Packets received need to be written to this output stream.
                FileOutputStream out = new FileOutputStream(
                        mInterface.getFileDescriptor());
                //c. The UDP channel can be used to pass/get ip package to/from server
                DatagramChannel tunnel = DatagramChannel.open();

                // Connect to the server, localhost is used for demonstration only.
                tunnel.connect(new InetSocketAddress("127.0.0.1", 8087));
                //d. Protect this socket, so package send by it will not be feedback to the vpn service.
                protect(tunnel.socket());               
//                  ByteBuffer packet = ByteBuffer.allocate(32767);



//e. Use a loop to pass packets.
                    while (true) {
//---> Here in this loop the packets are coming in and out..
                        }
                    }
                } catch (Exception e) {
                    // Catch any exception
                    e.printStackTrace();
                } finally {
                    try {
                        if (mInterface != null) {
                            mInterface.close();
                            mInterface = null;
                        }
                    } catch (Exception e) {
                    }
                }
            }
        }, "MyVpnRunnable");
        //start the service
        mThread.start();
        return START_STICKY;
    }*

Reno Jones

Reno Jones
  • 1,979
  • 1
  • 18
  • 30
  • refer to https://stackoverflow.com/questions/28930342/how-to-get-uid-from-packet-android and from uid you can get the app name with PackageManager.getNameForUid() – some1 Jul 10 '20 at 14:10

2 Answers2

1

I'm afraid this can't be done only with help of VpnService. You can't get necessary information with normal VpnService APIs.

However this is trivial with iptables (and of course a rooted phone...) like this:

iptables -t mangle -A PREROUTING -m owner --uid-owner bad_app_uid -j DROP

You'll need to

  1. root the phone
  2. compile your own iptables binary with all necessary extensions
  3. build iptables command line in Java
  4. run iptables

I have no idea about blocking incoming traffic per app - but doesn't seem very necessary.

If you do want to give it a try, https://github.com/shadowsocks/shadowsocks-android compiles iptables which I guess might just run for you too. BTW I have nothing to do with the mentioned app.

EDIT: Android 5.0 VpnService has several new APIs such as addAllowedApplication and addDisallowedApplication, but "disallow" here only means the specified application will just bypass the VPN.

mindex
  • 1,606
  • 13
  • 18
0

TrafficStats can tell you over a period of time which app have accessed internet. Then use iptables to block internet access for a specific app.

mesh
  • 849
  • 9
  • 16
  • TrafficStats doesn't seem to fair well when a VPN is active. It thinks all traffic originates from the VPN application. – Nathan F. Feb 11 '20 at 04:40