2018-9-27
IPackageDeleteObserver.Stub继承于Binder类,在应用中进行getPackageManager().deletePackage调用的时候,会传递一个Binder的回调对象给PMS(system_server)
PackageDeleteObserver observer = new PackageDeleteObserver();
getPackageManager().deletePackage("com.tencent.mm", observer, 0);
这个试验中,我们的每次点击按钮都会创建一个PackageDeleteObserver对象传给PMS,我们尝试多次点击按钮,new很多对象,看看是否会对系统构成攻击。
为了避免PackageDeleteObserver对象的释放,我们甚至采用ArrayList将其引用起来。
public class MainActivity extends Activity
implements OnClickListener {
private static final String TAG = "MyService";
private List
public class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
public void packageDeleted(boolean succeeded) {
Log.i(TAG, "======= UNINSTALL_COMPLETE ==========");
}
public void packageDeleted(String s, int i)
{
Log.i(TAG, "=======1 UNINSTALL_COMPLETE ==========");
}
}
public void onClick(View src)
{
Log.i(TAG, "onClick: starting service");
PackageDeleteObserver observer = new PackageDeleteObserver();
mList.add(observer);
getPackageManager().deletePackage("com.tencent.mm", observer, 0);
Log.i(TAG, "List.size = " + mList.size());
Log.i(TAG, "onClick: starting service, end of onClick");
}
不断的点击按钮,同时,观察Local Binders的数量
Unknown:/ $ dumpsys meminfo 7365 | grep Binders
Local Binders: 26 Proxy Binders: 15
Unknown:/ $ dumpsys meminfo 7365 | grep Binders
Local Binders: 48 Proxy Binders: 15
Unknown:/ $ dumpsys meminfo 7365 | grep Binders
Local Binders: 55 Proxy Binders: 15
Unknown:/ $ dumpsys meminfo 7365 | grep Binders
Local Binders: 13 Proxy Binders: 15
结果发现,还是被释放了。
why?
打开JavaBBinder中的log来观察期创建和析构,
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGD("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
virtual ~JavaBBinder()
{
ALOGD("Destroying JavaBBinder %p\n", this);
android_atomic_dec(&gNumLocalRefs);
JNIEnv* env = javavm_to_jnienv(mVM);
env->DeleteGlobalRef(mObject);
}
结果发现,JavaBBinder对象确实是可以被释放的,
01-01 17:09:01.784 7365 7365 D JavaBinder: Creating JavaBBinder 0x74a3213080
01-01 17:09:13.376 7365 7378 D JavaBinder: Destroying JavaBBinder 0x74a3213080
查看Binder.java中的init方法
private native final void init();
其实现在android_util_Binder.cpp中的
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
可以看出,Binder对象关联的是JavaBBinderHolder,而不是JavaBBinder对象。
当调用端的BinderProxy对象释放的时候,server端的binder对象在没有被引用的情况下也会被释放。