Skip to content

Commit

Permalink
新增了classloader选择能力,可以选择APP里的其他ClassLoader
Browse files Browse the repository at this point in the history
Add Classloader Selector, now XServer can switch to other classloader.
  • Loading branch information
Monkeylord committed Dec 16, 2021
1 parent 8a79301 commit aaaf591
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
8 changes: 8 additions & 0 deletions app/src/main/assets/pages/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ <h2>Request Infomations:</h2>
</#list>
</details>
</#if>
<#if objs?exists>
<details>
<summary>Known ClassLoaders(click to switch to):</summary>
<#list classloaders?keys as key>
<p><a href="classview?op=setclassloader&classloader=${key}">${key}:${classloaders[key]}</a></p>
</#list>
</details>
</#if>
<!--
<h1>Dynamic Xposed Module Load</h1>
<form action=/file method="get" target="_blank">
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/monkeylord/XServer/XServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import monkeylord.XServer.api.WsScript;
import monkeylord.XServer.api.wsMethodViewNew;
import monkeylord.XServer.api.wsTracerNew;
import monkeylord.XServer.handler.ClassHandler;
import monkeylord.XServer.handler.ObjectHandler;
import monkeylord.XServer.objectparser.BooleanParser;
import monkeylord.XServer.objectparser.ByteArrayParser;
Expand Down Expand Up @@ -112,6 +113,9 @@ public XServer(int port, Hashtable<String, Operation> route) {
} catch (IOException e) {
e.printStackTrace();
}
ClassHandler.classLoaders.put("default-"+classLoader.hashCode(),classLoader);
ClassHandler.monitorClassloaders(classLoader);
ClassHandler.classLoaders.put("application-"+getCurrentApplication().getClassLoader().hashCode(),getCurrentApplication().getClassLoader());
}

@Override
Expand Down Expand Up @@ -205,6 +209,7 @@ public Response handle(IHTTPSession session) {
map.put("params", session.getParms());
map.put("headers", session.getHeaders());
map.put("clzs", DexHelper.getClassesInDex(XServer.classLoader));
map.put("classloaders", ClassHandler.getClassLoaderDescriptions());
map.put("parsers", parsers);
map.put("objs", ObjectHandler.objects);
map.put("pid", String.valueOf(Process.myPid()));
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/monkeylord/XServer/XposedEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam)
if (!targetApp.equals("MadMode")&&!loadPackageParam.packageName.equals(targetApp)) return;
gatherInfo(loadPackageParam);
//启动XServer
setXposedHookProvider();
if(!targetApp.equals("MadMode"))new XServer(8000);
new XServer(Process.myPid());
XposedBridge.log("XServer Listening... on"+loadPackageParam.packageName + "@" + Process.myPid());
setXposedHookProvider();
XposedBridge.log("Using XposedHook...@" + Process.myPid());
}

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/monkeylord/XServer/api/ClassView.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public String handle(String url, Map<String, String> parms, Map<String, String>
res.put("classes",
DexHelper.getClassesInDex(XServer.classLoader));
return res.toJSONString();
case "setclassloader":
res.put("success",ClassHandler.setXServerClassloader(parms.get("classloader")));
return "<meta http-equiv=\"refresh\" content=\"1;url=/\"> ";
default:
return "";
}
Expand Down
48 changes: 48 additions & 0 deletions app/src/main/java/monkeylord/XServer/handler/ClassHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,63 @@
import com.alibaba.fastjson.JSON;

import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import monkeylord.XServer.XServer;
import monkeylord.XServer.handler.Hook.XServer_MethodHook;
import monkeylord.XServer.handler.Hook.XServer_Param;
import monkeylord.XServer.utils.DexHelper;
import monkeylord.XServer.utils.Utils;

//处理类相关的内容
public class ClassHandler {
public static HashMap<String, ClassLoader> classLoaders = new HashMap<>();

public static boolean monitorClassloaders(ClassLoader classLoader){
try {
Class classLoaderClz = ClassLoader.class;
Member m = classLoaderClz.getDeclaredConstructor(ClassLoader.class);
HookHandler.getProvider().hookMethod(m, new XServer_MethodHook() {
@Override
public void beforeHookedMethod(XServer_Param param) throws Throwable {
super.beforeHookedMethod(param);
classLoaders.put("classloader"+ param.thisObject.hashCode(), (ClassLoader) param.thisObject);
classLoaders.put("classloader"+ ((ClassLoader) param.thisObject).getParent().hashCode(), (ClassLoader) ((ClassLoader) param.thisObject).getParent());
}
});
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}

public static boolean setXServerClassloader(String name){
if(classLoaders.get(name)!=null){
XServer.classLoader = classLoaders.get(name);
return true;
}
return false;
}

public static HashMap<String, String> getClassLoaderDescriptions(){
HashMap<String,String> map = new HashMap<>();
for (Map.Entry<String,ClassLoader> entry:classLoaders.entrySet()) {
try {
map.put(entry.getKey(), entry.getValue().toString());
}catch (Exception e){
e.printStackTrace();
map.put(entry.getKey(),entry.getValue().getClass().getName());
}
}
return map;
}

public static String[] getAllClasses(ClassLoader classLoader) {
return DexHelper.getClassesInDex(classLoader);
}
Expand Down

0 comments on commit aaaf591

Please sign in to comment.