add loader's loader
This commit is contained in:
parent
2da58b2ab9
commit
ab1a213161
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk 30
|
||||||
|
buildToolsVersion "30.0.3"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk rootProject.ext.androidMinSdkVersion
|
||||||
|
targetSdk rootProject.ext.androidTargetSdkVersion
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
def buildType = variant.name.capitalize()
|
||||||
|
def variantLowered = variant.name.toLowerCase()
|
||||||
|
|
||||||
|
variant.outputs.all {
|
||||||
|
outputFileName = "${variant.getFlavorName()}-${variant.versionName}.apk"
|
||||||
|
}
|
||||||
|
|
||||||
|
task "copyDex$buildType"(type: Copy) {
|
||||||
|
dependsOn("assemble$buildType")
|
||||||
|
def dexFilePath = "$buildDir/intermediates/dex/${variantLowered}/mergeDex${buildType}/classes.dex"
|
||||||
|
from dexFilePath
|
||||||
|
rename "(.*).dex", "classes-${version_name}.dex"
|
||||||
|
into "$rootProject.projectDir/out/list-dex"
|
||||||
|
}
|
||||||
|
|
||||||
|
task "copySo$buildType"(type: Copy) {
|
||||||
|
dependsOn("assemble$buildType")
|
||||||
|
from "$buildDir/intermediates/merged_native_libs/${variantLowered}/out/lib"
|
||||||
|
into "$rootProject.projectDir/out/list-so"
|
||||||
|
}
|
||||||
|
|
||||||
|
task "copy$buildType"() {
|
||||||
|
dependsOn("copySo$buildType")
|
||||||
|
dependsOn("copyDex$buildType")
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
System.out.println("Dex and so files has been copy to ${rootProject.projectDir}${File.separator}out")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':share')
|
||||||
|
compileOnly project(":hiddenapi-stubs")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.lsposed.lspatch.appstub">
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
package org.lsposed.lspatch.appstub;
|
||||||
|
|
||||||
|
import android.app.ActivityThread;
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import dalvik.system.InMemoryDexClassLoader;
|
||||||
|
|
||||||
|
public class LSPApplicationSub extends Application {
|
||||||
|
final static String TAG = LSPApplicationSub.class.getSimpleName();
|
||||||
|
|
||||||
|
static Object realLSPApplication = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
// load real lsp loader from asset
|
||||||
|
Context context = createAppContext();
|
||||||
|
if (context == null) {
|
||||||
|
Log.e(TAG, "create context err");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
InputStream inputStream = context.getAssets().open("lsploader.dex");
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
int nRead;
|
||||||
|
byte[] data = new byte[16384];
|
||||||
|
|
||||||
|
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
InMemoryDexClassLoader inMemoryDexClassLoader = new InMemoryDexClassLoader(ByteBuffer.wrap(buffer.toByteArray()), LSPApplicationSub.class.getClassLoader());
|
||||||
|
Class<?> lspa = inMemoryDexClassLoader.loadClass("org.lsposed.lspatch.appstub.LSPApplication");
|
||||||
|
realLSPApplication = lspa.newInstance();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new IllegalStateException("wtf", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void attachBaseContext(Context base) {
|
||||||
|
super.attachBaseContext(base);
|
||||||
|
|
||||||
|
if (realLSPApplication != null) {
|
||||||
|
try {
|
||||||
|
realLSPApplication.getClass().getMethod("attachBaseContext", Context.class).invoke(realLSPApplication, base);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new IllegalStateException("wtf", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy from app project
|
||||||
|
public static Context createAppContext() {
|
||||||
|
try {
|
||||||
|
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
|
||||||
|
Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
|
||||||
|
currentActivityThreadMethod.setAccessible(true);
|
||||||
|
|
||||||
|
Object activityThreadObj = currentActivityThreadMethod.invoke(null);
|
||||||
|
|
||||||
|
Field boundApplicationField = activityThreadClass.getDeclaredField("mBoundApplication");
|
||||||
|
boundApplicationField.setAccessible(true);
|
||||||
|
Object mBoundApplication = boundApplicationField.get(activityThreadObj); // AppBindData
|
||||||
|
if (mBoundApplication == null) {
|
||||||
|
Log.e(TAG, "mBoundApplication null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Field infoField = mBoundApplication.getClass().getDeclaredField("info"); // info
|
||||||
|
infoField.setAccessible(true);
|
||||||
|
Object loadedApkObj = infoField.get(mBoundApplication); // LoadedApk
|
||||||
|
if (loadedApkObj == null) {
|
||||||
|
Log.e(TAG, "loadedApkObj null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Class<?> contextImplClass = Class.forName("android.app.ContextImpl");
|
||||||
|
Method createAppContextMethod = contextImplClass.getDeclaredMethod("createAppContext", activityThreadClass, loadedApkObj.getClass());
|
||||||
|
createAppContextMethod.setAccessible(true);
|
||||||
|
|
||||||
|
Object context = createAppContextMethod.invoke(null, (ActivityThread) activityThreadObj, loadedApkObj);
|
||||||
|
|
||||||
|
if (context instanceof Context) {
|
||||||
|
return (Context) context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,3 +13,4 @@ project(':manager-service').projectDir = new File('mmp/manager-service')
|
||||||
include ':patch'
|
include ':patch'
|
||||||
include ':axmlprinter'
|
include ':axmlprinter'
|
||||||
include ':share'
|
include ':share'
|
||||||
|
include ':appstub'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue