Solution: Use dynamic proxy to replace the signature information in the PackageManager

Replace the sPackageManager field in ActivityThread

Replace ApplicationPackageManager mPM object inside

Obtain PackageManager related code:

public static void hookPMS(Context context, String packageName, String sign) { try { SignatureFake.setSign(sign); / / to get global ActivityThread Object Object currentActivityThread = Reflect. OnClass (" android. App. ActivityThread ") .call("currentActivityThread").get(); Object sPackageManager = Reflect.onClass("android.app.ActivityThread").field("sPackageManager").get(); Class<? > iPackageManagerInterface = Reflect.onClass("android.content.pm.IPackageManager").type(); Object proxy = Proxy.newProxyInstance( iPackageManagerInterface.getClassLoader(), new Class<? >[]{iPackageManagerInterface}, new PmsHookBinderInvocationHandler(sPackageManager, packageName, 0)); On (currentActivityThread). Set ("sPackageManager",proxy); // replace the sPackageManager field in ActivityThread. / / 2. Replace ApplicationPackageManager objects inside the mPM PackageManager PM = context. GetPackageManager (); Reflect.on(pm).set("mPM", proxy); } catch (Exception e) { Log.d(TAG, "hook pms error:" + Log.getStackTraceString(e)); }}Copy the code

InvocationHandler callback

@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// Check whether the getPackageInfo method is true if("getPackageInfo".equals(method.getName())){if(DEBUG) { Log.d(TAG,"hook method:" + method.getName()); } String pkgName = (String)args[0]; Integer flag = (Integer)args[1]; if(DEBUG) { Log.d(TAG, "hook pkgName:" + pkgName + " appPkgName:" + appPkgName + ",flaf:" + flag); } if((flag & Packagemanager.get_signatures) == Packagemanager.get_signatures && AppPkgName.com pareToIgnoreCase (pkgName) = = 0) {/ / the constructor of the incoming new signature overwrite the original signature PackageInfo info = (PackageInfo) method.invoke(base, args); info.signatures = SignatureFake.getSignature(info.signatures); return info; } } return method.invoke(base, args); }Copy the code

Code: github.com/bineanzhou/…