1.IActivityManager
1启动Activity执行到Instrumentation的execStartActivity方法时,Android 26以下版本的代码为:
public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
try {
intent. migrateExtraStreamToClipData ( ) ;
intent. prepareToLeaveProcess ( who) ;
int result = ActivityManagerNative. getDefault ( )
. startActivity ( whoThread, who. getBasePackageName ( ) , intent, intent. resolveTypeIfNeeded ( who. getContentResolver ( ) ) , token, target != null ? target. mEmbeddedID : null, requestCode, 0 , null, options) ;
checkStartActivityResult ( result, intent) ;
} catch ( RemoteException e) {
throw new RuntimeException ( "Failure from system" , e) ;
}
return null;
}
Android 26以上版本的代码为:
public ActivityResult execStartActivity ( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
try {
intent. migrateExtraStreamToClipData ( ) ;
intent. prepareToLeaveProcess ( who) ;
int result = ActivityManager. getService ( )
. startActivity ( whoThread, who. getBasePackageName ( ) , intent, intent. resolveTypeIfNeeded ( who. getContentResolver ( ) ) ,
token, target != null ? target. mEmbeddedID : null, requestCode, 0 , null, options) ;
checkStartActivityResult ( result, intent) ;
} catch ( RemoteException e) {
throw new RuntimeException ( "Failure from system" , e) ;
}
return null;
}
在Hook进行Intent替换时,获取IActivityManager的方式不同,Android 26以下版本如下:
Class mActivityManagerClass = Class. forName ( "android.app.ActivityManagerNative" ) ;
Method getDefaultMethod = mActivityManagerClass. getDeclaredMethod ( "getDefault" ) ;
getDefaultMethod. setAccessible ( true ) ;
mIActivityManager = getDefaultMethod. invoke ( null) ;
Android 26以上版本如下:
Class mActivityManagerClass = Class. forName ( "android.app.ActivityManager" ) ;
mIActivityManager = mActivityManagerClass. getMethod ( "getService" ) . invoke ( null) ;
Field mIActivityManagerSingletonField = mActivityManagerClass. getDeclaredField ( "IActivityManagerSingleton" ) ;
mIActivityManagerSingletonField. setAccessible ( true ) ;
mIActivityManagerSingleton = mIActivityManagerSingletonField. get ( null) ;
2. Handler H
在Android 28版本中,ActivityThread的内部类Handler H去掉了以下消息类型:
public static final int LAUNCH_ACTIVITY = 100 ;
public static final int PAUSE_ACTIVITY = 101 ;
public static final int PAUSE_ACTIVITY_FINISHING= 102 ;
public static final int STOP_ACTIVITY_SHOW = 103 ;
public static final int STOP_ACTIVITY_HIDE = 104 ;
public static final int SHOW_WINDOW = 105 ;
public static final int HIDE_WINDOW = 106 ;
public static final int RESUME_ACTIVITY = 107 ;
public static final int SEND_RESULT = 108 ;
public static final int DESTROY_ACTIVITY = 109 ;
当启动Activity时,会跳转到handleMessage方法的以下代码:
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = ( ClientTransaction) msg. obj;
mTransactionExecutor. execute ( transaction) ;
if ( isSystem ( ) ) {
transaction. recycle ( ) ;
}
break ;
在以上代码执行前,需要把真实的Intent注入其中,替换掉绕过AMS检查的代理Intent。以上代码首先获得了ClientTransaction对象,ClientTransaction中有一个成员变量List mActivityCallbacks,ClientTransactionItem的其中一个子类是LaunchActivityItem,LaunchActivityItem中的成员变量Intent就是需要替换的Intent。
新建一个MyHandler继承android.os.Handler,使用MyHandler替换ActivityThread中的H,在handlerMessage中,首先获取mActivityCallbacks。
Object mClientTransaction = msg. obj;
Field mactivityCallbacks = mClientTransaction. getClass ( ) . getDeclaredField ( "mActivityCallbacks" ) ;
mactivityCallbacks. setAccessible ( true ) ;
List mActivityCallbacks = ( List) mactivityCallbacks. get ( mClientTransaction) ;
if ( mActivityCallbacks. size ( ) == 0 ) {
return false ;
}
获取LaunchActivityItem:
Class mLaunchActivityItemClass = Class. forName ( "android.app.servertransaction.LaunchActivityItem" ) ;
Object mLaunchActivityItem = mActivityCallbacks. get ( 0 ) ;
if ( mLaunchActivityItemClass. isInstance ( mLaunchActivityItem) == false ) {
return false ;
}
Field mIntentField = mLaunchActivityItemClass. getDeclaredField ( "mIntent" ) ;
mIntentField. setAccessible ( true ) ;
Intent proxyIntent = ( Intent) mIntentField. get ( mLaunchActivityItem) ;
替换Intent:
Intent targetIntent = proxyIntent. getParcelableExtra ( "targetIntent" ) ;
if ( targetIntent != null) {
mIntentField. setAccessible ( true ) ;
mIntentField. set ( mLaunchActivityItem, targetIntent) ;
}