jeudi 2 août 2018

Implement hidden Android interface through reflection and proxy

I am trying to use the hidden Android package manager's method installPackage and its callback class IPackageInstallObserver. I managed to retrieve the method in question via Java's reflection but am struggling to implement the hidden observer interface via reflection proxies.

I tried the following approach but it still didn't work. I tried it like this:

// I declared the same interface signature locally
interface IPackageInstallObserver {
    fun packageInstalled(packageName: String?, returnCode: Int)
}

// get the classes and method via reflection
val cPackageManager = Class.forName("android.content.pm.PackageManager")
val cPackageInstallObserver = Class.forName("android.content.pm.IPackageInstallObserver")
installPackage = cPackageManager.getMethod("installPackage", Uri::class.java, cPackageInstallObserver, Integer.TYPE, String::class.java)
INSTALL_REPLACE_EXISTING = cPackageManager.getField("INSTALL_REPLACE_EXISTING").getInt(null)

// create the observer
val installObserver = Proxy.newProxyInstance(
    CustomPackageManager::class.java.classLoader,
    arrayOf<Class<*>>(IPackageInstallObserver::class.java),  // local definition
    InstallObserverInvocationHandler(listener)
) as IPackageInstallObserver // local definition

// the invocation handler
class InstallObserverInvocationHandler(private val listener: PackageListener): InvocationHandler {

    override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
        if (method?.name == "packageInstalled" && method.parameterTypes.size == 2 &&
                         method.parameterTypes[0] == String::class.java &&
                method.parameterTypes[1] == Integer.TYPE) {

            /* custom implementation */
        }
        return null
    }
}

// how I use the installPackage method
installPackage.invoke(context.packageManager, apkUri, installObserver, INSTALL_REPLACE_EXISTING, INSTALLER_NAME)

However, my installObserver instance is unfortunately null - can somebody tell me what I'm doing wrong? I do have system privileges and required permissions declared.





Aucun commentaire:

Enregistrer un commentaire