capacitor-dex-editor 0.0.11 → 0.0.13

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.
@@ -432,6 +432,15 @@ public class DexEditorPluginPlugin extends Plugin {
432
432
  ));
433
433
  break;
434
434
 
435
+ case "saveClassSmali":
436
+ result.put("data", dexManager.saveClassSmaliToApk(
437
+ params.getString("apkPath"),
438
+ params.getString("dexPath"),
439
+ params.getString("className"),
440
+ params.getString("smaliContent")
441
+ ));
442
+ break;
443
+
435
444
  default:
436
445
  result.put("success", false);
437
446
  result.put("error", "Unknown action: " + action);
@@ -1756,4 +1756,113 @@ public class DexManager {
1756
1756
 
1757
1757
  return sb.toString();
1758
1758
  }
1759
+
1760
+ /**
1761
+ * 保存修改后的 Smali 代码到 APK 中的 DEX 文件
1762
+ * 注意:这是一个复杂操作,需要重新编译 Smali 并修改 DEX 文件
1763
+ */
1764
+ public JSObject saveClassSmaliToApk(String apkPath, String dexPath, String className, String smaliContent) throws Exception {
1765
+ JSObject result = new JSObject();
1766
+
1767
+ Log.d(TAG, "saveClassSmaliToApk: apkPath=" + apkPath + ", dexPath=" + dexPath + ", className=" + className);
1768
+ Log.d(TAG, "smaliContent length: " + (smaliContent != null ? smaliContent.length() : 0));
1769
+
1770
+ if (className == null || className.isEmpty()) {
1771
+ result.put("success", false);
1772
+ result.put("error", "未指定类名");
1773
+ return result;
1774
+ }
1775
+
1776
+ if (smaliContent == null || smaliContent.isEmpty()) {
1777
+ result.put("success", false);
1778
+ result.put("error", "Smali 内容为空");
1779
+ return result;
1780
+ }
1781
+
1782
+ try {
1783
+ // 创建临时目录存储 smali 文件(使用系统临时目录)
1784
+ java.io.File tempDir = new java.io.File(System.getProperty("java.io.tmpdir"), "smali_temp_" + System.currentTimeMillis());
1785
+ if (!tempDir.mkdirs()) {
1786
+ result.put("success", false);
1787
+ result.put("error", "无法创建临时目录");
1788
+ return result;
1789
+ }
1790
+
1791
+ // 将类名转换为文件路径
1792
+ String classPath = className.replace(".", "/") + ".smali";
1793
+ java.io.File smaliFile = new java.io.File(tempDir, classPath);
1794
+ smaliFile.getParentFile().mkdirs();
1795
+
1796
+ // 写入 smali 文件
1797
+ try (java.io.FileWriter writer = new java.io.FileWriter(smaliFile)) {
1798
+ writer.write(smaliContent);
1799
+ }
1800
+
1801
+ Log.d(TAG, "Smali file written to: " + smaliFile.getAbsolutePath());
1802
+
1803
+ // 使用 smali 库编译 smali 文件为 dex
1804
+ // 注意:这需要 smali 库的支持
1805
+ java.io.File outputDex = new java.io.File(tempDir, "classes_modified.dex");
1806
+
1807
+ // 使用 SmaliOptions 编译
1808
+ com.android.tools.smali.smali.SmaliOptions options = new com.android.tools.smali.smali.SmaliOptions();
1809
+ options.outputDexFile = outputDex.getAbsolutePath();
1810
+ options.apiLevel = 30;
1811
+
1812
+ java.util.List<String> inputFiles = new java.util.ArrayList<>();
1813
+ inputFiles.add(smaliFile.getAbsolutePath());
1814
+
1815
+ boolean success = com.android.tools.smali.smali.Smali.assemble(options, inputFiles);
1816
+
1817
+ if (!success) {
1818
+ result.put("success", false);
1819
+ result.put("error", "Smali 编译失败");
1820
+ cleanupTempDir(tempDir);
1821
+ return result;
1822
+ }
1823
+
1824
+ Log.d(TAG, "Smali compiled successfully to: " + outputDex.getAbsolutePath());
1825
+
1826
+ // TODO: 将编译后的 dex 合并回原 APK
1827
+ // 这是一个复杂的操作,需要:
1828
+ // 1. 解压 APK
1829
+ // 2. 替换/合并 DEX 文件中的类
1830
+ // 3. 重新打包 APK
1831
+ // 4. 重新签名 APK
1832
+
1833
+ // 目前先返回成功,实际保存功能需要更多实现
1834
+ result.put("success", true);
1835
+ result.put("message", "Smali 编译成功,但完整保存功能需要进一步实现");
1836
+ result.put("compiledDexPath", outputDex.getAbsolutePath());
1837
+
1838
+ // 清理临时文件(暂时保留以便调试)
1839
+ // cleanupTempDir(tempDir);
1840
+
1841
+ } catch (Exception e) {
1842
+ Log.e(TAG, "Error saving smali: " + e.getMessage(), e);
1843
+ result.put("success", false);
1844
+ result.put("error", "保存失败: " + e.getMessage());
1845
+ }
1846
+
1847
+ return result;
1848
+ }
1849
+
1850
+ /**
1851
+ * 清理临时目录
1852
+ */
1853
+ private void cleanupTempDir(java.io.File dir) {
1854
+ if (dir != null && dir.exists()) {
1855
+ java.io.File[] files = dir.listFiles();
1856
+ if (files != null) {
1857
+ for (java.io.File file : files) {
1858
+ if (file.isDirectory()) {
1859
+ cleanupTempDir(file);
1860
+ } else {
1861
+ file.delete();
1862
+ }
1863
+ }
1864
+ }
1865
+ dir.delete();
1866
+ }
1867
+ }
1759
1868
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
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",