Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Commit

Permalink
v37: Detect version and pass it to the installer app
Browse files Browse the repository at this point in the history
  • Loading branch information
rovo89 committed Nov 1, 2013
1 parent 46e70e0 commit a18f4b9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
2 changes: 1 addition & 1 deletion assets/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
36
37
65 changes: 60 additions & 5 deletions src/de/robv/android/xposed/XposedBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
Expand All @@ -29,6 +30,8 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import android.annotation.SuppressLint;
import android.app.ActivityThread;
Expand Down Expand Up @@ -56,6 +59,9 @@
import de.robv.android.xposed.callbacks.XCallback;

public final class XposedBridge {
public static final String INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer";
public static int XPOSED_BRIDGE_VERSION;

private static PrintWriter logWriter = null;
// log for initialization of a few mods is about 500 bytes, so 2*20 kB (2*~350 lines) should be enough
private static final int MAX_LOGFILE_SIZE = 20*1024;
Expand All @@ -64,7 +70,7 @@ public final class XposedBridge {
private static final Object[] EMPTY_ARRAY = new Object[0];
public static final ClassLoader BOOTCLASSLOADER = ClassLoader.getSystemClassLoader();
@SuppressLint("SdCardPath")
public static final String BASE_DIR = "/data/data/de.robv.android.xposed.installer/";
public static final String BASE_DIR = "/data/data/" + INSTALLER_PACKAGE_NAME + "/";

// built-in handlers
private static final Map<Member, TreeSet<XC_MethodHook>> hookedMethodCallbacks
Expand Down Expand Up @@ -92,8 +98,10 @@ private static void main(String[] args) {
} catch (IOException ignored) {}

String date = DateFormat.getDateTimeInstance().format(new Date());
determineXposedVersion();
log("-----------------\n" + date + " UTC\n"
+ "Loading Xposed (for " + (startClassName == null ? "Zygote" : startClassName) + ")...");
+ "Loading Xposed v" + XPOSED_BRIDGE_VERSION
+ " (for " + (startClassName == null ? "Zygote" : startClassName) + ")...");

if (initNative()) {
if (startClassName == null) {
Expand All @@ -118,6 +126,43 @@ private static void main(String[] args) {
}

private static native String getStartClassName();

private static void determineXposedVersion() throws IOException {
ZipInputStream is = new ZipInputStream(new FileInputStream(BASE_DIR + "bin/XposedBridge.jar"));
ZipEntry entry;
try {
while ((entry = is.getNextEntry()) != null) {
if (!entry.getName().equals("assets/VERSION"))
continue;

BufferedReader br = new BufferedReader(new InputStreamReader(is));
String version = br.readLine();
br.close();

XPOSED_BRIDGE_VERSION = extractIntPart(version);
if (XPOSED_BRIDGE_VERSION == 0)
throw new RuntimeException("could not parse XposedBridge version from \"" + version + "\"");
return;
}
throw new RuntimeException("could not find assets/VERSION in " + BASE_DIR + "bin/XposedBridge.jar");
} finally {
try {
is.close();
} catch (Exception e) { }
}
}

private static int extractIntPart(String str) {
int result = 0, length = str.length();
for (int offset = 0; offset < length; offset++) {
char c = str.charAt(offset);
if ('0' <= c && c <= '9')
result = result * 10 + (c - '0');
else
break;
}
return result;
}

/**
* Hook some methods which we want to create an easier interface for developers.
Expand All @@ -139,19 +184,22 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
CompatibilityInfo compatInfo = (CompatibilityInfo) getObjectField(param.args[0], "compatInfo");
if (appInfo.sourceDir == null)
return;

setObjectField(activityThread, "mBoundApplication", param.args[0]);
loadedPackagesInProcess.add(appInfo.packageName);
LoadedApk loadedApk = activityThread.getPackageInfoNoCheck(appInfo, compatInfo);
XResources.setPackageNameForResDir(appInfo.packageName, loadedApk.getResDir());

LoadPackageParam lpparam = new LoadPackageParam(loadedPackageCallbacks);
lpparam.packageName = appInfo.packageName;
lpparam.processName = (String) getObjectField(param.args[0], "processName");
lpparam.classLoader = loadedApk.getClassLoader();
lpparam.appInfo = appInfo;
lpparam.isFirstApplication = true;
XC_LoadPackage.callAll(lpparam);

if (appInfo.packageName.equals(INSTALLER_PACKAGE_NAME))
hookXposedInstaller(lpparam.classLoader);
}
});

Expand Down Expand Up @@ -243,7 +291,14 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

XResources.init();
}


private static void hookXposedInstaller(ClassLoader classLoader) {
try {
findAndHookMethod(INSTALLER_PACKAGE_NAME + ".XposedApp", classLoader, "getActiveXposedVersion",
XC_MethodReplacement.returnConstant(XPOSED_BRIDGE_VERSION));
} catch (Throwable t) { XposedBridge.log(t); }
}

/**
* Try to load all modules defined in <code>BASE_DIR/conf/modules.list</code>
*/
Expand Down

0 comments on commit a18f4b9

Please sign in to comment.