capacitor-dex-editor 0.0.56 → 0.0.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -537,6 +537,40 @@ public class DexEditorPluginPlugin extends Plugin {
537
537
  dexManager.closeMultiDexSession(params.getString("sessionId"));
538
538
  break;
539
539
 
540
+ case "addClassToSession":
541
+ dexManager.addClassToSession(
542
+ params.getString("sessionId"),
543
+ params.getString("className"),
544
+ params.getString("smaliContent")
545
+ );
546
+ break;
547
+
548
+ case "deleteClassFromSession":
549
+ dexManager.deleteClassFromSession(
550
+ params.getString("sessionId"),
551
+ params.getString("className")
552
+ );
553
+ break;
554
+
555
+ case "getMethodFromSession":
556
+ result.put("data", dexManager.getMethodFromSession(
557
+ params.getString("sessionId"),
558
+ params.getString("className"),
559
+ params.getString("methodName"),
560
+ params.optString("methodSignature", "")
561
+ ));
562
+ break;
563
+
564
+ case "modifyMethodInSession":
565
+ dexManager.modifyMethodInSession(
566
+ params.getString("sessionId"),
567
+ params.getString("className"),
568
+ params.getString("methodName"),
569
+ params.optString("methodSignature", ""),
570
+ params.getString("newMethodCode")
571
+ );
572
+ break;
573
+
540
574
  case "listSessions":
541
575
  result.put("data", dexManager.listAllSessions());
542
576
  break;
@@ -1158,30 +1158,6 @@ public class DexManager {
1158
1158
  return "";
1159
1159
  }
1160
1160
 
1161
- private String replaceMethodInSmali(String classSmali, String methodName,
1162
- String signature, String newMethodCode) {
1163
- String methodStart = ".method";
1164
- String methodEnd = ".end method";
1165
-
1166
- int searchStart = 0;
1167
- while (true) {
1168
- int start = classSmali.indexOf(methodStart, searchStart);
1169
- if (start == -1) break;
1170
-
1171
- int end = classSmali.indexOf(methodEnd, start);
1172
- if (end == -1) break;
1173
-
1174
- String methodBlock = classSmali.substring(start, end + methodEnd.length());
1175
- if (methodBlock.contains(methodName)) {
1176
- return classSmali.substring(0, start) + newMethodCode +
1177
- classSmali.substring(end + methodEnd.length());
1178
- }
1179
-
1180
- searchStart = end + methodEnd.length();
1181
- }
1182
-
1183
- return classSmali;
1184
- }
1185
1161
 
1186
1162
  private String insertMethodToSmali(String classSmali, String methodCode) {
1187
1163
  // 在类结束前插入方法
@@ -1983,6 +1959,194 @@ public class DexManager {
1983
1959
  Log.d(TAG, "Modified class in session: " + className);
1984
1960
  }
1985
1961
 
1962
+ /**
1963
+ * 添加新类到会话
1964
+ */
1965
+ public void addClassToSession(String sessionId, String className, String smaliContent) throws Exception {
1966
+ MultiDexSession session = multiDexSessions.get(sessionId);
1967
+ if (session == null) {
1968
+ throw new IllegalArgumentException("Session not found: " + sessionId);
1969
+ }
1970
+
1971
+ // 编译 Smali
1972
+ ClassDef newClassDef = compileSmaliToClass(smaliContent, Opcodes.getDefault());
1973
+
1974
+ // 添加到第一个 DEX(默认 classes.dex)
1975
+ String targetDex = "classes.dex";
1976
+ if (!session.dexFiles.containsKey(targetDex) && !session.dexFiles.isEmpty()) {
1977
+ targetDex = session.dexFiles.keySet().iterator().next();
1978
+ }
1979
+
1980
+ session.modifiedClasses.put(targetDex + "|" + className, newClassDef);
1981
+ session.modified = true;
1982
+
1983
+ Log.d(TAG, "Added class to session: " + className);
1984
+ }
1985
+
1986
+ /**
1987
+ * 从会话中删除类
1988
+ */
1989
+ public void deleteClassFromSession(String sessionId, String className) throws Exception {
1990
+ MultiDexSession session = multiDexSessions.get(sessionId);
1991
+ if (session == null) {
1992
+ throw new IllegalArgumentException("Session not found: " + sessionId);
1993
+ }
1994
+
1995
+ String targetType = convertClassNameToType(className);
1996
+
1997
+ // 找到类所在的 DEX 并标记为删除
1998
+ String targetDex = null;
1999
+ for (Map.Entry<String, DexBackedDexFile> entry : session.dexFiles.entrySet()) {
2000
+ for (ClassDef classDef : entry.getValue().getClasses()) {
2001
+ if (classDef.getType().equals(targetType)) {
2002
+ targetDex = entry.getKey();
2003
+ break;
2004
+ }
2005
+ }
2006
+ if (targetDex != null) break;
2007
+ }
2008
+
2009
+ if (targetDex == null) {
2010
+ throw new IllegalArgumentException("Class not found: " + className);
2011
+ }
2012
+
2013
+ // 用 null 标记删除
2014
+ session.modifiedClasses.put(targetDex + "|" + className, null);
2015
+ session.modified = true;
2016
+
2017
+ Log.d(TAG, "Deleted class from session: " + className);
2018
+ }
2019
+
2020
+ /**
2021
+ * 从会话中获取单个方法的 Smali 代码
2022
+ */
2023
+ public JSObject getMethodFromSession(String sessionId, String className, String methodName, String methodSignature) throws Exception {
2024
+ JSObject result = new JSObject();
2025
+
2026
+ MultiDexSession session = multiDexSessions.get(sessionId);
2027
+ if (session == null) {
2028
+ throw new IllegalArgumentException("Session not found: " + sessionId);
2029
+ }
2030
+
2031
+ // 先获取整个类的 Smali
2032
+ JSObject classResult = getClassSmaliFromSession(sessionId, className);
2033
+ String smaliContent = classResult.optString("smaliContent", "");
2034
+
2035
+ if (smaliContent.isEmpty()) {
2036
+ result.put("methodCode", "# 类未找到: " + className);
2037
+ return result;
2038
+ }
2039
+
2040
+ // 解析并提取方法
2041
+ String methodCode = extractMethodFromSmali(smaliContent, methodName, methodSignature);
2042
+ result.put("methodCode", methodCode);
2043
+ result.put("className", className);
2044
+ result.put("methodName", methodName);
2045
+
2046
+ return result;
2047
+ }
2048
+
2049
+ /**
2050
+ * 修改会话中的单个方法
2051
+ */
2052
+ public void modifyMethodInSession(String sessionId, String className, String methodName, String methodSignature, String newMethodCode) throws Exception {
2053
+ MultiDexSession session = multiDexSessions.get(sessionId);
2054
+ if (session == null) {
2055
+ throw new IllegalArgumentException("Session not found: " + sessionId);
2056
+ }
2057
+
2058
+ // 获取整个类的 Smali
2059
+ JSObject classResult = getClassSmaliFromSession(sessionId, className);
2060
+ String smaliContent = classResult.optString("smaliContent", "");
2061
+
2062
+ if (smaliContent.isEmpty()) {
2063
+ throw new IllegalArgumentException("Class not found: " + className);
2064
+ }
2065
+
2066
+ // 替换方法
2067
+ String newSmaliContent = replaceMethodInSmali(smaliContent, methodName, methodSignature, newMethodCode);
2068
+
2069
+ // 保存修改后的类
2070
+ modifyClassInSession(sessionId, className, newSmaliContent);
2071
+
2072
+ Log.d(TAG, "Modified method in session: " + className + "." + methodName);
2073
+ }
2074
+
2075
+ /**
2076
+ * 从 Smali 代码中提取指定方法
2077
+ */
2078
+ private String extractMethodFromSmali(String smaliContent, String methodName, String methodSignature) {
2079
+ String[] lines = smaliContent.split("\n");
2080
+ StringBuilder methodCode = new StringBuilder();
2081
+ boolean inMethod = false;
2082
+ boolean found = false;
2083
+
2084
+ for (String line : lines) {
2085
+ if (line.startsWith(".method ")) {
2086
+ // 检查是否是目标方法
2087
+ if (line.contains(" " + methodName + "(") || line.contains(" " + methodName + ";")) {
2088
+ // 如果指定了签名,进一步匹配
2089
+ if (methodSignature == null || methodSignature.isEmpty() || line.contains(methodSignature)) {
2090
+ inMethod = true;
2091
+ found = true;
2092
+ }
2093
+ }
2094
+ }
2095
+
2096
+ if (inMethod) {
2097
+ methodCode.append(line).append("\n");
2098
+ if (line.equals(".end method")) {
2099
+ break;
2100
+ }
2101
+ }
2102
+ }
2103
+
2104
+ if (!found) {
2105
+ return "# 方法未找到: " + methodName + (methodSignature != null ? methodSignature : "");
2106
+ }
2107
+
2108
+ return methodCode.toString();
2109
+ }
2110
+
2111
+ /**
2112
+ * 替换 Smali 代码中的指定方法
2113
+ */
2114
+ private String replaceMethodInSmali(String smaliContent, String methodName, String methodSignature, String newMethodCode) {
2115
+ String[] lines = smaliContent.split("\n");
2116
+ StringBuilder result = new StringBuilder();
2117
+ boolean inMethod = false;
2118
+ boolean replaced = false;
2119
+
2120
+ for (String line : lines) {
2121
+ if (line.startsWith(".method ")) {
2122
+ if (line.contains(" " + methodName + "(") || line.contains(" " + methodName + ";")) {
2123
+ if (methodSignature == null || methodSignature.isEmpty() || line.contains(methodSignature)) {
2124
+ // 插入新方法代码
2125
+ result.append(newMethodCode.trim()).append("\n");
2126
+ inMethod = true;
2127
+ replaced = true;
2128
+ continue;
2129
+ }
2130
+ }
2131
+ }
2132
+
2133
+ if (inMethod) {
2134
+ if (line.equals(".end method")) {
2135
+ inMethod = false;
2136
+ }
2137
+ continue;
2138
+ }
2139
+
2140
+ result.append(line).append("\n");
2141
+ }
2142
+
2143
+ if (!replaced) {
2144
+ throw new IllegalArgumentException("Method not found: " + methodName);
2145
+ }
2146
+
2147
+ return result.toString();
2148
+ }
2149
+
1986
2150
  /**
1987
2151
  * 保存多 DEX 会话的修改到 APK
1988
2152
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.56",
3
+ "version": "0.0.58",
4
4
  "description": "Capacitor-plugin-for-editing-DEX-files-in-APK",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",