Pid for the process that sent an intent

2019-02-11 06:14发布

I am trying to discover the process id or package name of the process that sent me an intent. I don't want to put the process id or package name in an extra (as some other questions have asked) since I don't want to allow spoofing. The code I used is:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_secure_file_share);
    ...   

    Intent intent = getIntent();

    if (intent != null)
    {
        // get the caller
        String callingPackage = getAppNameByPID(getApplicationContext(),
               Binder.getCallingPid());
    ....
    }
 }

Where getAppNameByPID translates the PID to the package name. The problem is that Binder.getCallingPid() always returns the recipient's PID (not the caller's).

How do you get the caller's PID?

2条回答
Ridiculous、
3楼-- · 2019-02-11 06:39

I tried this as well and I could only get a result using bound services.

@Override
public IBinder onBind(Intent intent) {
    @SuppressWarnings("static-access")
    int uid = mBinder.getCallingUid();

    final PackageManager pm = getPackageManager();
    String name = pm.getNameForUid(uid);

    Log.d("ITestService", String.format("onBind: calling name: %s"), name);

    //name is your own package, not the caller

    return mBinder;
}

But if you implement the Stub of your AIDL:

private final ITestService.Stub mBinder = new ITestService.Stub() {
    public void test() {
        //Get caller information
        //UID
        int uid = Binder.getCallingUid();

        final PackageManager pm = getPackageManager();
        String name = pm.getNameForUid(uid);        
        //name will be sharedUserId of caller, OR if not set the package name of the caller

        String[] packageNames = pm.getPackagesForUid(uid);
        //packageNames is a array of packages using that UID, could be more than 1 if using sharedUserIds

        Log.d("ITestService", String.format("Calling uid: %d (getNameForUid: %s)", uid, name));
        for (String packageName : packageNames) {
            Log.d("ITestService", String.format("getPackagesForUid: %s", packageName));
        } 

        //PID
        int pid = Binder.getCallingPid();
        Log.d("ITestService", String.format("Calling pid: %d", pid));
        String processName = "";

        ActivityManager am = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
        List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo proc : processes) {
            if (proc.pid == pid) {
                processName = proc.processName;
                Log.d("ITestService", String.format("Found ProcessName of pid(%d): %s", pid, processName));

                //processName will be the package name of the caller, YEAH!
            }
        }
    }
}

PID will be the most reliable one if you want to know which package called it.

查看更多
登录 后发表回答