Activity启动流程:Hook实现启动未注册Activity

}

}

Intent intent = (Intent) args[index];

Intent proxyIntent = new Intent(intent);

//占位的Activity

proxyIntent.setClassName(“com.wangyz.plugindemo”, “com.wangyz.plugindemo.ProxyActivity”);

proxyIntent.putExtra(“target_intent”, intent);

args[index] = proxyIntent;

}

return method.invoke(mInstance, args);

}

});

mInstanceField.set(singleton, proxyInstance);

} catch (Exception e) {

e.printStackTrace();

}

}

获取还原Intent的Hook点

Android8.0及以下

启动Activity的消息,会回调到ActivityThread中的mH的dispatchMessage方法,可以通过给mH设置一个callBack,在callBack的handleMessage中,然后替换回真正要启动的Intent,然后返回false,让handleMessage再继续处理。

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

Android8.0及以下,在ActivityThread的mH中的handleMessage方法中,会处理LAUNCH_ACTIVITY类型的消息,在这里调用了handleLaunchActivity方法来启动Activity。

case LAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);

final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(

r.activityInfo.applicationInfo, r.compatInfo);

handleLaunchActivity(r, null);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

Android9.0

和8.0一样,设置callBack,然后修改Intent。

在ActivityThread的mH中的handleMessage方法中,会处理EXECUTE_TRANSACTION类型的消息,在这里调用了TransactionExecutor.execute方法

case EXECUTE_TRANSACTION:

final ClientTransaction transaction = (ClientTransaction) msg.obj;

mTransactionExecutor.execute(transaction);

if (isSystem()) {

// Client transactions inside system process are recycled on the client side

// instead of ClientLifecycleManager to avoid being cleared before this

// message is handled.

transaction.recycle();

}

// TODO(lifecycler): Recycle locally scheduled transactions.

break;

execute方法中会调用executeCallbacks

public void execute(ClientTransaction transaction) {

final IBinder token = transaction.getActivityToken();

log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

executeCallbacks(transaction);

executeLifecycleState(transaction);

mPendingActions.clear();

log(“End resolving transaction”);

}

public void executeCallbacks(ClientTransaction transaction) {

final List callbacks = transaction.getCallbacks();

if (callbacks == null) {

// No callbacks to execute, return early.

return;

}

log(“Resolving callbacks”);

final IBinder token = transaction.getActivityToken();

ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

// In case when post-execution state of the last callback matches the final state requested

// for the activity in this transaction, we won’t do the last transition here and do it when

// moving to final state instead (because it may contain additional parameters from server).

final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();

final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
UNDEFINED;

// Index of the last callback that requests some post-execution state.

final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

final int size = callbacks.size();

for (int i = 0; i < size; ++i) {

final ClientTransactionItem item = callbacks.get(i);

log("Resolving callback: " + item);

final int postExecutionState = item.getPostExecutionState();

final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,

item.getPostExecutionState());

if (closestPreExecutionState != UNDEFINED) {

cycleToPath(r, closestPreExecutionState);

}

item.execute(mTransactionHandler, token, mPendingActions);

item.postExecute(mTransactionHandler, token, mPendingActions);

if (r == null) {

// Launch activity request will create an activity record.

r = mTransactionHandler.getActivityClient(token);

}

if (postExecutionState != UNDEFINED && r != null) {

// Skip the very last transition and perform it by explicit state request instead.

final boolean shouldExcludeLastTransition =

i == lastCallbackRequestingState && finalState == postExecutionState;

cycleToPath(r, postExecutionState, shouldExcludeLastTransition);

}

}

}

这个方法里会调用ClientTransactionItem的execute方法。ClientTransactionItem是在ActivityStackSupervisor中的realStartActivityLocked中添加的

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,

boolean andResume, boolean checkConfig) throws RemoteException {

// Create activity launch transaction.

final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,

r.appToken);

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),

System.identityHashCode®, r.info,

// TODO: Have this take the merged configuration instead of separate global

// and override configs.

mergedConfiguration.getGlobalConfiguration(),

mergedConfiguration.getOverrideConfiguration(), r.compat,

r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,

r.persistentState, results, newIntents, mService.isNextTransitionForward(),

profilerInfo));

}

因此,ClientTransactionItem对应的具体类为LaunchActivityItem,它对应的execute方法

@Override

public void execute(ClientTransactionHandler client, IBinder token,

PendingTransactionActions pendingActions) {

Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);

ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,

mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,

mPendingResults, mPendingNewIntents, mIsForward,

mProfilerInfo, client);

client.handleLaunchActivity(r, pendingActions, null /* customIntent */);

Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);

}

在它的方法里又调用了ClientTransactionHandler的handleLaunchActivity,而ClientTransactionHandler就是在ActivityThread中定义的

private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

ActivityThread继承了ClientTransactionHandler,那么它就会实现handleLaunchActivity。最终在这个方法里启动Activity

public final class ActivityThread extends ClientTransactionHandler {

@Override

public Activity handleLaunchActivity(ActivityClientRecord r,

PendingTransactionActions pendingActions, Intent customIntent) {

}

}

还原Intent

public static void hookHandler() {

try {

Field sCurrentActivityThreadThread = getField(Class.forName(“android.app.ActivityThread”), “sCurrentActivityThread”);

Object activityThread = sCurrentActivityThreadThread.get(null);

Field mHField = getField(Class.forName(“android.app.ActivityThread”), “mH”);

Object mH = mHField.get(activityThread);

Field mCallbackField = getField(Class.forName(“android.os.Handler”), “mCallback”);

mCallbackField.set(mH, new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

switch (msg.what) {

case 100: {

try {

Field intentField = getField(msg.obj.getClass(), “intent”);

Intent proxyIntent = (Intent) intentField.get(msg.obj);

Intent targetIntent = proxyIntent.getParcelableExtra(“target_intent”);

if (targetIntent != null) {

// proxyIntent.setComponent(targetIntent.getComponent());

intentField.set(msg.obj, targetIntent);

}

} catch (Exception e) {

e.printStackTrace();

}

}

break;

case 159: {

try {

Field mActivityCallbacksField = getField(msg.obj.getClass(), “mActivityCallbacks”);

List mActivityCallbacks = (List) mActivityCallbacksField.get(msg.obj);

for (int i = 0; i < mActivityCallbacks.size(); i++) {

if (mActivityCallbacks.get(i).getClass().getName()

.equals(“android.app.servertransaction.LaunchActivityItem”)) {

Object launchActivityItem = mActivityCallbacks.get(i);

Field mIntentField = getField(launchActivityItem.getClass(), “mIntent”);

Intent intent = (Intent) mIntentField.get(launchActivityItem);

// 获取插件的

Intent proxyIntent = intent.getParcelableExtra(“target_intent”);

//替换

if (proxyIntent != null) {

mIntentField.set(launchActivityItem, proxyIntent);

}

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

break;

default:

break;

}

return false;

}

});

} catch (Exception e) {

e.printStackTrace();

}

}

在Application创建时Hook

@Override

public void onCreate() {

super.onCreate();

//一般是从服务器下载回来,然后复制到应用的私有目录下,这里演示从sdcard复制到data目录下,6.0及以上需要申请动态权限。复制应该放在非UI线程上做,这里简化操作,放在UI线程上操作。

String pluginPath = getDir(“plugin”, Context.MODE_PRIVATE).getAbsolutePath();

pluginPath = pluginPath + “/plugin.apk”;

if (!new File(pluginPath).exists()) {

FileUtil.copyFile(PLUGIN_PATH, pluginPath);

}

HookUtil.loadPlugin(this, pluginPath);

HookUtil.hookAMS();

HookUtil.hookHandler();

}

到这里,就可以启用同一应用内未注册的Activity。

启动插件应用内的Activity


启动非同一应用内的Activity,相比启动同一应用内的Activity,需要多几个步骤。由于不在一个应用内,所以需要把插件的APK先加载进来,然后同样也需要在AMS检测前替换Intent为占位的Intent,在检测后,启动Activity前替换回为需要启动Activity的Intent。另外,由于插件是动态加载进去的,也需要解决资源加载的问题。

加载插件

加载插件主要是用到类加载器

public static void loadPlugin(Context context, String dexPath) {

//判断dex是否存在

File dex = new File(dexPath);

if (!dex.exists()) {

return;

}

try {

//获取自己的dexElements

PathClassLoader pathClassLoader = (PathClassLoader) context.getClassLoader();

Field pathListField = getField(pathClassLoader.getClass(), “pathList”);

Object pathListObject = pathListField.get(pathClassLoader);

Field dexElementsField = getField(pathListObject.getClass(), “dexElements”);

Object[] dexElementsObject = (Object[]) dexElementsField.get(pathListObject);

//获取dex中的dexElements

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值