capacitor-dex-editor 0.0.72 → 0.0.74

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.
@@ -213,15 +213,29 @@ public class DexManager {
213
213
  }
214
214
 
215
215
  /**
216
- * 保存 DEX 文件
216
+ * 保存 DEX 文件(优先使用 C++ 修改的字节数据)
217
217
  */
218
218
  public void saveDex(String sessionId, String outputPath) throws Exception {
219
219
  DexSession session = getSession(sessionId);
220
+
221
+ File outputFile = new File(outputPath);
222
+ if (outputFile.getParentFile() != null) {
223
+ outputFile.getParentFile().mkdirs();
224
+ }
220
225
 
221
- // 创建新的 DEX 文件
226
+ // 如果使用 C++ 修改了 dexBytes,直接保存
227
+ if (session.dexBytes != null && session.modified &&
228
+ session.modifiedClasses.isEmpty() && session.removedClasses.isEmpty()) {
229
+ try (java.io.FileOutputStream fos = new java.io.FileOutputStream(outputFile)) {
230
+ fos.write(session.dexBytes);
231
+ }
232
+ Log.d(TAG, "Saved DEX (C++ modified) to: " + outputPath);
233
+ return;
234
+ }
235
+
236
+ // Java 回退实现
222
237
  DexPool dexPool = new DexPool(session.originalDexFile.getOpcodes());
223
238
 
224
- // 添加所有类(排除已删除的,使用修改后的版本)
225
239
  Set<String> modifiedClassTypes = new HashSet<>();
226
240
  for (ClassDef modifiedClass : session.modifiedClasses) {
227
241
  modifiedClassTypes.add(modifiedClass.getType());
@@ -235,13 +249,6 @@ public class DexManager {
235
249
  }
236
250
  }
237
251
 
238
- // 写入文件 (使用官方推荐方式)
239
- File outputFile = new File(outputPath);
240
- if (outputFile.getParentFile() != null) {
241
- outputFile.getParentFile().mkdirs();
242
- }
243
-
244
- // 创建临时 DexFile 用于写入
245
252
  List<ClassDef> allClasses = new ArrayList<>();
246
253
  for (ClassDef c : session.modifiedClasses) {
247
254
  allClasses.add(c);
@@ -404,12 +411,27 @@ public class DexManager {
404
411
  }
405
412
 
406
413
  /**
407
- * 添加类
414
+ * 添加类(优先使用 C++ 实现)
408
415
  */
409
416
  public void addClass(String sessionId, String smaliCode) throws Exception {
410
417
  DexSession session = getSession(sessionId);
411
418
 
412
- // Smali 代码编译为 ClassDef
419
+ // 优先使用 C++ 实现
420
+ if (CppDex.isAvailable() && session.dexBytes != null) {
421
+ try {
422
+ byte[] newDexBytes = CppDex.addClass(session.dexBytes, smaliCode);
423
+ if (newDexBytes != null) {
424
+ session.dexBytes = newDexBytes;
425
+ session.modified = true;
426
+ Log.d(TAG, "Added class via C++");
427
+ return;
428
+ }
429
+ } catch (Exception e) {
430
+ Log.w(TAG, "C++ addClass failed, fallback to Java", e);
431
+ }
432
+ }
433
+
434
+ // Java 回退实现
413
435
  ClassDef newClass = compileSmaliToClass(smaliCode, session.originalDexFile.getOpcodes());
414
436
  session.modifiedClasses.add(newClass);
415
437
  session.modified = true;
@@ -418,10 +440,27 @@ public class DexManager {
418
440
  }
419
441
 
420
442
  /**
421
- * 删除类
443
+ * 删除类(优先使用 C++ 实现)
422
444
  */
423
445
  public void removeClass(String sessionId, String className) throws Exception {
424
446
  DexSession session = getSession(sessionId);
447
+
448
+ // 优先使用 C++ 实现
449
+ if (CppDex.isAvailable() && session.dexBytes != null) {
450
+ try {
451
+ byte[] newDexBytes = CppDex.deleteClass(session.dexBytes, className);
452
+ if (newDexBytes != null) {
453
+ session.dexBytes = newDexBytes;
454
+ session.modified = true;
455
+ Log.d(TAG, "Removed class via C++: " + className);
456
+ return;
457
+ }
458
+ } catch (Exception e) {
459
+ Log.w(TAG, "C++ removeClass failed, fallback to Java", e);
460
+ }
461
+ }
462
+
463
+ // Java 回退实现
425
464
  session.removedClasses.add(className);
426
465
  session.modified = true;
427
466
 
@@ -602,28 +641,39 @@ public class DexManager {
602
641
  }
603
642
 
604
643
  /**
605
- * 设置方法的 Smali 代码
644
+ * 设置方法的 Smali 代码(优先使用 C++ 实现)
606
645
  */
607
646
  public void setMethodSmali(String sessionId, String className,
608
647
  String methodName, String methodSignature,
609
648
  String smaliCode) throws Exception {
610
649
  DexSession session = getSession(sessionId);
650
+
651
+ // 获取原类的 Smali 并替换方法
652
+ String classSmali = classToSmali(sessionId, className).getString("smali");
653
+ String modifiedSmali = replaceMethodInSmali(classSmali, methodName, methodSignature, smaliCode);
654
+
655
+ // 优先使用 C++ 实现
656
+ if (CppDex.isAvailable() && session.dexBytes != null) {
657
+ try {
658
+ byte[] newDexBytes = CppDex.modifyClass(session.dexBytes, className, modifiedSmali);
659
+ if (newDexBytes != null) {
660
+ session.dexBytes = newDexBytes;
661
+ session.modified = true;
662
+ Log.d(TAG, "Modified method via C++: " + className + "->" + methodName);
663
+ return;
664
+ }
665
+ } catch (Exception e) {
666
+ Log.w(TAG, "C++ modifyClass failed, fallback to Java", e);
667
+ }
668
+ }
669
+
670
+ // Java 回退实现
611
671
  ClassDef classDef = findClass(session, className);
612
-
613
672
  if (classDef == null) {
614
673
  throw new IllegalArgumentException("Class not found: " + className);
615
674
  }
616
-
617
- // 获取原类的 Smali
618
- String classSmali = classToSmali(sessionId, className).getString("smali");
619
675
 
620
- // 替换方法
621
- String modifiedSmali = replaceMethodInSmali(classSmali, methodName, methodSignature, smaliCode);
622
-
623
- // 重新编译
624
676
  ClassDef modifiedClass = compileSmaliToClass(modifiedSmali, session.originalDexFile.getOpcodes());
625
-
626
- // 更新会话
627
677
  session.removedClasses.add(className);
628
678
  session.modifiedClasses.add(modifiedClass);
629
679
  session.modified = true;
@@ -894,7 +944,7 @@ public class DexManager {
894
944
  }
895
945
 
896
946
  /**
897
- * 汇编 Smali 目录为 DEX
947
+ * 汇编 Smali 目录为 DEX(优先使用 C++ 实现)
898
948
  */
899
949
  public JSObject assemble(String smaliDir, String outputPath) throws Exception {
900
950
  File inputDir = new File(smaliDir);
@@ -905,7 +955,35 @@ public class DexManager {
905
955
  }
906
956
 
907
957
  outputFile.getParentFile().mkdirs();
958
+
959
+ // 优先使用 C++ 实现
960
+ if (CppDex.isAvailable()) {
961
+ try {
962
+ // 读取所有 smali 文件并合并
963
+ List<File> smaliFiles = collectSmaliFiles(inputDir);
964
+ StringBuilder allSmali = new StringBuilder();
965
+ for (File f : smaliFiles) {
966
+ allSmali.append(readFileContent(f));
967
+ allSmali.append("\n\n");
968
+ }
969
+
970
+ byte[] dexBytes = CppDex.smaliToDex(allSmali.toString());
971
+ if (dexBytes != null && dexBytes.length > 0) {
972
+ try (java.io.FileOutputStream fos = new java.io.FileOutputStream(outputFile)) {
973
+ fos.write(dexBytes);
974
+ }
975
+ JSObject result = new JSObject();
976
+ result.put("success", true);
977
+ result.put("outputPath", outputPath);
978
+ result.put("engine", "cpp");
979
+ return result;
980
+ }
981
+ } catch (Exception e) {
982
+ Log.w(TAG, "C++ smaliToDex failed, fallback to Java", e);
983
+ }
984
+ }
908
985
 
986
+ // Java 回退实现
909
987
  SmaliOptions options = new SmaliOptions();
910
988
  options.outputDexFile = outputPath;
911
989
 
@@ -920,6 +998,7 @@ public class DexManager {
920
998
  JSObject result = new JSObject();
921
999
  result.put("success", success);
922
1000
  result.put("outputPath", outputPath);
1001
+ result.put("engine", "java");
923
1002
  return result;
924
1003
  }
925
1004
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.72",
3
+ "version": "0.0.74",
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",