- 一、ActivityThread 后续分析
- 二、ActivityThread 相关源码
- 三、Application 替换位置
dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Application 首先要理解系统如何注册应用的 Application 的 ;
一、ActivityThread 后续分析在 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 源码分析 ) 基础上 , 继续分析 ActivityThread 的 handleBindApplication 方法 ;
在 Application app = data.info.makeApplication(data.restrictedBackupMode, null) 代码中 , 创建了 Application , 并且调用了 Application 的 attachBaseContext 方法 ;
创建完毕之后 , 将创建的 Application 赋值给了 ActivityThread 的 mInitialApplication 成员 , mInitialApplication = app ;
④ ActivityThread 的 mInitialApplication 成员是 Application
在后面调用了 mInstrumentation.callApplicationOnCreate(app) 方法 , 执行了 Application 中的 onCreate 方法 , 此时
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
二、ActivityThread 相关源码
public final class ActivityThread {
Application mInitialApplication;
final ArrayList mAllApplications
= new ArrayList();
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
final H mH = new H();
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
private void handleBindApplication(AppBindData data) {
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
if (!data.restrictedBackupMode) {
List providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
// 此处调用了 Application 的 onCreate 函数
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
public final void bindApplication(String processName, ApplicationInfo appInfo,
List providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map services,
Bundle coreSettings) {
sendMessage(H.BIND_APPLICATION, data);
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
}
}
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
}
}
完整源码参考 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/ActivityThread.java
三、Application 替换位置当应用启动后 , 在 AndroidManifest.xml 中配置的 代理 Application 为 kim.hsl.multipledex.ProxyApplication ;
因此在应用程序开始运行时 , 以下几个位置运行的 Application 是 kim.hsl.multipledex.ProxyApplication , 需要将其替换为实际开发的 Application ;
① ContextImpl 的 private Context mOuterContext 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
② ActivityThread 中的 ArrayList mAllApplications 集合中添加了 kim.hsl.multipledex.ProxyApplication 对象 ;
③ LoadedApk 中的 mApplication 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
④ ActivityThread 中的 Application mInitialApplication 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
替换 Application 就是需要替换上述对象的对应 Application 成员 ;