feat:配置文件格式修改以及activity自定义化

This commit is contained in:
lateautumn4lin 2020-09-14 17:02:38 +08:00
parent 17304cf0f0
commit c5cd0450b3
8 changed files with 247 additions and 48 deletions

View File

@ -0,0 +1,116 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -1,4 +1,6 @@
remote_server=192.144.152.23
package_name=com.lateautumn4lin.headwolf
package_kuaishou=com.smile.gifmaker
package_pdd=com.xunmeng.pinduoduo
group_pdd.name=com.xunmeng.pinduoduo
group_pdd.home=com.xunmeng.pinduoduo.ui.activity.HomeActivity
group_kuaishou.name=com.smile.gifmaker
group_kuaishou.home=com.yxcorp.gifshow.HomeActivity

View File

@ -7,6 +7,8 @@ package com.lateautumn4lin.headwolf;
* @date 2020/9/10 13:40
*/
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.lateautumn4lin.headwolf.commons.Logger;
import com.lateautumn4lin.headwolf.handlers.KuaishouHandler;
import com.lateautumn4lin.headwolf.utils.PropertiesAssistant;
@ -15,7 +17,6 @@ import com.virjar.sekiro.api.SekiroRequestHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
import static java.util.Arrays.asList;
@ -25,7 +26,8 @@ import static java.util.Arrays.asList;
* The type Config.
*/
public class Config {
private static Properties propertiesAssistant = PropertiesAssistant.getProperties();
private static HashMap propertiesAssistant = PropertiesAssistant.getJsonProperties();
// 预先把handlers文件夹下面的类实现
private static List<SekiroRequestHandler> handlers = asList(
(SekiroRequestHandler) new KuaishouHandler()
);
@ -44,7 +46,7 @@ public class Config {
/**
* The Groups.
*/
static private HashMap<String, String> groups = GetAllPackageGroups();
static private HashMap<String, HashMap<String, String>> groups = GetAllPackageGroups();
/**
* Get package name string.
@ -52,8 +54,7 @@ public class Config {
* @return the string
*/
public static String GetPackageName() {
Properties propertiesAssistant = PropertiesAssistant.getProperties();
return propertiesAssistant.getProperty("package_name");
return propertiesAssistant.get("package_name").toString();
}
@ -63,7 +64,7 @@ public class Config {
* @return the remote server
*/
public static String getRemoteServer() {
return propertiesAssistant.getProperty("remote_server");
return propertiesAssistant.get("remote_server").toString();
}
/**
@ -84,13 +85,18 @@ public class Config {
*
* @return the hash map
*/
public static HashMap<String, String> GetAllPackageGroups() {
Properties propertiesAssistant = PropertiesAssistant.getProperties();
HashMap<String, String> all_package_groups = new HashMap<String, String>();
public static HashMap<String, HashMap<String, String>> GetAllPackageGroups() {
HashMap<String, HashMap<String, String>> all_package_groups = new HashMap<String, HashMap<String, String>>();
try {
for (String name : propertiesAssistant.stringPropertyNames()) {
if (name.contains("package_") ^ name.contains("name")) {
all_package_groups.put(propertiesAssistant.getProperty(name), name);
for (Object group : propertiesAssistant.keySet()) {
if (((String) group).contains("group")) {
HashMap<String, String> same_group = new HashMap<String, String>();
JsonObject GroupInfo = (new Gson()).toJsonTree(propertiesAssistant.get(group)).getAsJsonObject();
String name = GroupInfo.get("name").toString().replace("\"", "");
String home = GroupInfo.get("home").toString().replace("\"", "");
same_group.put("home", home);
same_group.put("group", group.toString());
all_package_groups.put(name, same_group);
}
}
} catch (Exception e) {
@ -107,7 +113,17 @@ public class Config {
* @return the group
*/
public static String GetGroup(String type_name) {
return groups.get(type_name);
return groups.get(type_name).get("group");
}
/**
* Get home string.
*
* @param type_name the type name
* @return the string
*/
public static String GetHome(String type_name) {
return groups.get(type_name).get("home");
}
/**
@ -116,13 +132,10 @@ public class Config {
* @return the string
*/
public static List<String> GetHookPackages() {
Properties propertiesAssistant = PropertiesAssistant.getProperties();
List<String> inner_hook_packages = new ArrayList<String>();
try {
for (String name : propertiesAssistant.stringPropertyNames()) {
if (name.contains("package_") ^ name.contains("name")) {
inner_hook_packages.add(propertiesAssistant.getProperty(name));
}
for (String name : groups.keySet()) {
inner_hook_packages.add(name);
}
} catch (Exception e) {
Logger.loge(e.toString());

View File

@ -5,7 +5,6 @@ import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.lateautumn4lin.headwolf.commons.Logger;
import com.tencent.mmkv.MMKV;
/**
@ -18,15 +17,5 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.logi("StartUp MainActivity");
// try {
// String rootDir = MMKV.initialize("/data/user/0/com.lateautumn4lin.headwolf/files/mmkv");
// MMKV kv = MMKV.mmkvWithID("test", MMKV.MULTI_PROCESS_MODE);
// Logger.logi("mmkv root: " + rootDir);
// kv.encode("string", "Hello from mmkv");
// String str = kv.decodeString("string");
// Logger.logi("Get MMKV:" + str);
// } catch (Exception e) {
// Logger.loge(e.toString());
// }
}
}

View File

@ -16,6 +16,7 @@ import com.lateautumn4lin.headwolf.commons.Logger;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import dalvik.system.PathClassLoader;
@ -29,21 +30,18 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage;
* The type Base entry. 第一层Hook入口
*/
public class BaseEntry implements IXposedHookLoadPackage {
private String modulePackage = null;
private static List<String> hookPackages = null;
private String modulePackage = "com.lateautumn4lin.headwolf";
private static List<String> hookPackages = new ArrayList<String>();
private final String handleHookClass = RealEntry.class.getName();
private final String handleHookMethod = "handleLoadPackage";
static {
hookPackages.add("com.smile.gifmaker");
}
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
try {
// 延迟初始化静态变量
if (modulePackage == null) {
modulePackage = Config.GetPackageName();
}
if (hookPackages == null) {
hookPackages = Config.GetHookPackages();
}
// 包含配置文件中配置的包名则进入真正Hook逻辑
if (hookPackages.contains(loadPackageParam.packageName)) {
try {

View File

@ -20,6 +20,7 @@ import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
* The type Real entry.
*/
@ -27,6 +28,8 @@ public class RealEntry implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
try {
// 测试
Logger.logi("5555");
Logger.logi(String.format("Begin Real Hook Logic About:%s", loadPackageParam.packageName));
// step1:获取context
Context context = (Context) XposedHelpers.callMethod(
@ -39,11 +42,13 @@ public class RealEntry implements IXposedHookLoadPackage {
),
"getSystemContext"
);
// step2:获取包名对应的需要注册的handler以及home_class
Class HomeClass = loadPackageParam.classLoader.loadClass("com.yxcorp.gifshow.HomeActivity");
HashMap<String, SekiroRequestHandler> associate_handlers = ClassesReaderAssistant.reader(context, loadPackageParam.packageName);
// step3:由注册类进行handler注册
Register.GroupRegister(loadPackageParam, HomeClass, associate_handlers);
// step2:由注册类进行handler注册
if (Register.GroupRegister(loadPackageParam, associate_handlers)) {
Logger.logi(String.format("Real Hook Logic About:%s Success", loadPackageParam.packageName));
} else {
Logger.logi(String.format("Real Hook Logic About:%s Error", loadPackageParam.packageName));
}
} catch (Exception e) {
Logger.loge(e.toString());
}

View File

@ -29,14 +29,14 @@ public class Register {
* Base register boolean.
*
* @param loadPackageParam the load package param
* @param home_class the home class
* @param associate_handlers the associate handlers
* @return the boolean
*/
public static Boolean GroupRegister(final XC_LoadPackage.LoadPackageParam loadPackageParam, Class home_class, final HashMap<String, SekiroRequestHandler> associate_handlers) {
final String group_name = Config.GetGroup(loadPackageParam.packageName);
public static Boolean GroupRegister(final XC_LoadPackage.LoadPackageParam loadPackageParam, final HashMap<String, SekiroRequestHandler> associate_handlers) {
try {
XposedHelpers.findAndHookMethod(home_class, "onCreate", Bundle.class, new XC_MethodHook() {
Class HomeClass = loadPackageParam.classLoader.loadClass(Config.GetHome(loadPackageParam.packageName));
final String group_name = Config.GetGroup(loadPackageParam.packageName);
XposedHelpers.findAndHookMethod(HomeClass, "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Logger.logi(String.format("Group Register:%s Begin ClientId:%s", group_name, Config.getClientId()));

View File

@ -1,14 +1,23 @@
package com.lateautumn4lin.headwolf.utils;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.lateautumn4lin.headwolf.commons.Logger;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
import java.util.regex.Pattern;
/**
* The type Properties assistant.
*/
public class PropertiesAssistant {
private static final Pattern floatPattern = Pattern.compile("^-?[0-9]+(\\.[0-9]+)?$");
private static final Pattern intPattern = Pattern.compile("^-?[0-9]+$");
/**
* Gets properties.
*
@ -24,4 +33,71 @@ public class PropertiesAssistant {
}
return props;
}
/**
* Gets json properties.
*
* @return the json properties
*/
public static HashMap getJsonProperties() {
Properties properties = new Properties();
try {
InputStream in = PropertiesAssistant.class.getResourceAsStream("/assets/config");
properties.load(in);
} catch (Exception e) {
Logger.loge(e.toString());
}
JsonObject json = new JsonObject();
for (Object key : properties.keySet()) {
String baseKey = key.toString();
String[] splittedKey = baseKey.split("\\.");
JsonObject nestedObject = json;
for (int i = 0; i < splittedKey.length - 1; ++i) {
if (!json.has(splittedKey[i])) {
json.add(splittedKey[i], new JsonObject());
}
nestedObject = json.getAsJsonObject(splittedKey[i]);
}
String finalKeyElement = splittedKey[splittedKey.length - 1];
String value = properties.getProperty(baseKey);
String[] splitedValue = value.split("\\,");
if (splitedValue.length == 1) {
if (value.toLowerCase().equals("true") || value.toLowerCase().equals("false")) {
nestedObject.addProperty(finalKeyElement, Boolean.parseBoolean(value));
} else if (intPattern.matcher(value).matches()) {
nestedObject.addProperty(finalKeyElement, Integer.parseInt(value));
} else if (floatPattern.matcher(value).matches()) {
nestedObject.addProperty(finalKeyElement, Float.parseFloat(value));
} else {
nestedObject.addProperty(finalKeyElement, value);
}
} else {
JsonArray elementArray = new JsonArray();
for (String val : splitedValue) {
if (val.toLowerCase().equals("true") || val.toLowerCase().equals("false")) {
elementArray.add(new JsonPrimitive(Boolean.parseBoolean(val)));
} else if (intPattern.matcher(val).matches()) {
elementArray.add(new JsonPrimitive(Integer.parseInt(val)));
} else if (floatPattern.matcher(val).matches()) {
elementArray.add(new JsonPrimitive(Float.parseFloat(val)));
} else {
elementArray.add(new JsonPrimitive(val));
}
}
nestedObject.add(finalKeyElement, elementArray);
}
}
return new Gson().fromJson(json, HashMap.class);
}
}