capacitor-dex-editor 0.0.16 → 0.0.18

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.
@@ -29,6 +29,8 @@ import com.android.tools.smali.dexlib2.writer.io.FileDataStore;
29
29
  import com.android.tools.smali.dexlib2.writer.pool.DexPool;
30
30
  import com.android.tools.smali.baksmali.Baksmali;
31
31
  import com.android.tools.smali.baksmali.BaksmaliOptions;
32
+ import com.android.tools.smali.baksmali.Adaptors.ClassDefinition;
33
+ import com.android.tools.smali.baksmali.formatter.BaksmaliWriter;
32
34
  import com.android.tools.smali.smali.Smali;
33
35
  import com.android.tools.smali.smali.SmaliOptions;
34
36
 
@@ -1588,120 +1590,16 @@ public class DexManager {
1588
1590
  return result;
1589
1591
  }
1590
1592
 
1591
- // 生成 Smali 代码
1592
- smali.append(".class ");
1593
- // 访问标志
1594
- int accessFlags = targetClass.getAccessFlags();
1595
- if ((accessFlags & 0x0001) != 0) smali.append("public ");
1596
- if ((accessFlags & 0x0010) != 0) smali.append("final ");
1597
- if ((accessFlags & 0x0020) != 0) smali.append("super ");
1598
- if ((accessFlags & 0x0200) != 0) smali.append("interface ");
1599
- if ((accessFlags & 0x0400) != 0) smali.append("abstract ");
1600
- if ((accessFlags & 0x1000) != 0) smali.append("synthetic ");
1601
- if ((accessFlags & 0x2000) != 0) smali.append("annotation ");
1602
- if ((accessFlags & 0x4000) != 0) smali.append("enum ");
1603
- smali.append(targetClass.getType()).append("\n");
1593
+ // 使用 baksmali 库生成正确的 Smali 代码
1594
+ BaksmaliOptions options = new BaksmaliOptions();
1595
+ ClassDefinition classDefinition = new ClassDefinition(options, targetClass);
1604
1596
 
1605
- // 父类
1606
- String superClass = targetClass.getSuperclass();
1607
- if (superClass != null) {
1608
- smali.append(".super ").append(superClass).append("\n");
1609
- }
1610
-
1611
- // 源文件
1612
- String sourceFile = targetClass.getSourceFile();
1613
- if (sourceFile != null) {
1614
- smali.append(".source \"").append(sourceFile).append("\"\n");
1615
- }
1616
-
1617
- // 实现的接口
1618
- for (String iface : targetClass.getInterfaces()) {
1619
- smali.append(".implements ").append(iface).append("\n");
1620
- }
1621
-
1622
- smali.append("\n");
1623
-
1624
- // 分离静态字段和实例字段
1625
- java.util.List<Field> staticFields = new java.util.ArrayList<>();
1626
- java.util.List<Field> instanceFields = new java.util.ArrayList<>();
1627
- for (Field field : targetClass.getFields()) {
1628
- if ((field.getAccessFlags() & 0x0008) != 0) {
1629
- staticFields.add(field);
1630
- } else {
1631
- instanceFields.add(field);
1632
- }
1633
- }
1634
-
1635
- // 静态字段
1636
- if (!staticFields.isEmpty()) {
1637
- smali.append("# static fields\n");
1638
- for (Field field : staticFields) {
1639
- smali.append(".field ");
1640
- int fFlags = field.getAccessFlags();
1641
- if ((fFlags & 0x0001) != 0) smali.append("public ");
1642
- if ((fFlags & 0x0002) != 0) smali.append("private ");
1643
- if ((fFlags & 0x0004) != 0) smali.append("protected ");
1644
- smali.append("static ");
1645
- if ((fFlags & 0x0010) != 0) smali.append("final ");
1646
- if ((fFlags & 0x0040) != 0) smali.append("volatile ");
1647
- if ((fFlags & 0x0080) != 0) smali.append("transient ");
1648
- if ((fFlags & 0x1000) != 0) smali.append("synthetic ");
1649
- if ((fFlags & 0x4000) != 0) smali.append("enum ");
1650
- smali.append(field.getName()).append(":").append(field.getType()).append("\n");
1651
- }
1652
- smali.append("\n");
1653
- }
1654
-
1655
- // 实例字段
1656
- if (!instanceFields.isEmpty()) {
1657
- smali.append("# instance fields\n");
1658
- for (Field field : instanceFields) {
1659
- smali.append(".field ");
1660
- int fFlags = field.getAccessFlags();
1661
- if ((fFlags & 0x0001) != 0) smali.append("public ");
1662
- if ((fFlags & 0x0002) != 0) smali.append("private ");
1663
- if ((fFlags & 0x0004) != 0) smali.append("protected ");
1664
- if ((fFlags & 0x0010) != 0) smali.append("final ");
1665
- if ((fFlags & 0x0040) != 0) smali.append("volatile ");
1666
- if ((fFlags & 0x0080) != 0) smali.append("transient ");
1667
- if ((fFlags & 0x1000) != 0) smali.append("synthetic ");
1668
- if ((fFlags & 0x4000) != 0) smali.append("enum ");
1669
- smali.append(field.getName()).append(":").append(field.getType()).append("\n");
1670
- }
1671
- smali.append("\n");
1672
- }
1673
-
1674
- // 分离直接方法和虚拟方法
1675
- java.util.List<Method> directMethods = new java.util.ArrayList<>();
1676
- java.util.List<Method> virtualMethods = new java.util.ArrayList<>();
1677
- for (Method method : targetClass.getMethods()) {
1678
- int mFlags = method.getAccessFlags();
1679
- // direct methods: private, static, constructor
1680
- if ((mFlags & 0x0002) != 0 || (mFlags & 0x0008) != 0 ||
1681
- method.getName().equals("<init>") || method.getName().equals("<clinit>")) {
1682
- directMethods.add(method);
1683
- } else {
1684
- virtualMethods.add(method);
1685
- }
1686
- }
1687
-
1688
- // 直接方法
1689
- if (!directMethods.isEmpty()) {
1690
- smali.append("\n# direct methods\n");
1691
- for (Method method : directMethods) {
1692
- outputMethod(smali, method);
1693
- }
1694
- }
1695
-
1696
- // 虚拟方法
1697
- if (!virtualMethods.isEmpty()) {
1698
- smali.append("\n# virtual methods\n");
1699
- for (Method method : virtualMethods) {
1700
- outputMethod(smali, method);
1701
- }
1702
- }
1597
+ java.io.StringWriter stringWriter = new java.io.StringWriter();
1598
+ BaksmaliWriter writer = new BaksmaliWriter(stringWriter, null);
1599
+ classDefinition.writeTo(writer);
1600
+ writer.close();
1703
1601
 
1704
- result.put("smali", smali.toString());
1602
+ result.put("smali", stringWriter.toString());
1705
1603
 
1706
1604
  } finally {
1707
1605
  if (dexInputStream != null) {
@@ -1715,179 +1613,6 @@ public class DexManager {
1715
1613
  return result;
1716
1614
  }
1717
1615
 
1718
- /**
1719
- * 输出单个方法的 Smali 代码 (MT 风格)
1720
- */
1721
- private void outputMethod(StringBuilder smali, Method method) {
1722
- smali.append(".method ");
1723
- int mFlags = method.getAccessFlags();
1724
- if ((mFlags & 0x0001) != 0) smali.append("public ");
1725
- if ((mFlags & 0x0002) != 0) smali.append("private ");
1726
- if ((mFlags & 0x0004) != 0) smali.append("protected ");
1727
- if ((mFlags & 0x0008) != 0) smali.append("static ");
1728
- if ((mFlags & 0x0010) != 0) smali.append("final ");
1729
- if ((mFlags & 0x0020) != 0) smali.append("synchronized ");
1730
- if ((mFlags & 0x0040) != 0) smali.append("bridge ");
1731
- if ((mFlags & 0x0080) != 0) smali.append("varargs ");
1732
- if ((mFlags & 0x0100) != 0) smali.append("native ");
1733
- if ((mFlags & 0x0400) != 0) smali.append("abstract ");
1734
- if ((mFlags & 0x0800) != 0) smali.append("strictfp ");
1735
- if ((mFlags & 0x1000) != 0) smali.append("synthetic ");
1736
- if ((mFlags & 0x10000) != 0) smali.append("constructor ");
1737
- if ((mFlags & 0x20000) != 0) smali.append("declared-synchronized ");
1738
-
1739
- smali.append(method.getName());
1740
- smali.append("(");
1741
- for (CharSequence param : method.getParameterTypes()) {
1742
- smali.append(param);
1743
- }
1744
- smali.append(")");
1745
- smali.append(method.getReturnType());
1746
- smali.append("\n");
1747
-
1748
- MethodImplementation impl = method.getImplementation();
1749
- if (impl != null) {
1750
- smali.append(" .registers ").append(impl.getRegisterCount()).append("\n\n");
1751
-
1752
- // 输出指令,跟踪标签位置
1753
- java.util.Map<Integer, String> labelMap = new java.util.HashMap<>();
1754
- int codeOffset = 0;
1755
-
1756
- // 第一遍:收集所有标签位置
1757
- for (Instruction instruction : impl.getInstructions()) {
1758
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) {
1759
- com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction offInstr =
1760
- (com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) instruction;
1761
- int targetOffset = codeOffset + offInstr.getCodeOffset();
1762
- labelMap.put(targetOffset, ":cond_" + Integer.toHexString(targetOffset));
1763
- }
1764
- codeOffset += instruction.getCodeUnits();
1765
- }
1766
-
1767
- // 第二遍:输出指令 (MT 风格:每条指令后有空行)
1768
- codeOffset = 0;
1769
- for (Instruction instruction : impl.getInstructions()) {
1770
- // 输出标签(如果有)
1771
- if (labelMap.containsKey(codeOffset)) {
1772
- smali.append("\n ").append(labelMap.get(codeOffset)).append("\n");
1773
- }
1774
-
1775
- smali.append(" ").append(instruction.getOpcode().name.toLowerCase().replace('_', '-'));
1776
- String params = formatInstruction(instruction);
1777
- if (!params.isEmpty()) {
1778
- smali.append(" ").append(params);
1779
- }
1780
- smali.append("\n\n"); // MT 风格:每条指令后有空行
1781
-
1782
- codeOffset += instruction.getCodeUnits();
1783
- }
1784
- }
1785
-
1786
- smali.append(".end method\n");
1787
- }
1788
-
1789
- /**
1790
- * 格式化指令参数 - 使用正确的 Smali 语法格式
1791
- * invoke 指令格式: invoke-xxx {v0, v1}, Lclass;->method()V
1792
- */
1793
- private String formatInstruction(Instruction instruction) {
1794
- StringBuilder sb = new StringBuilder();
1795
- String opName = instruction.getOpcode().name.toLowerCase();
1796
- boolean isInvokeOrFilled = opName.startsWith("invoke") || opName.startsWith("filled-new-array");
1797
-
1798
- // 收集寄存器
1799
- java.util.List<Integer> registers = new java.util.ArrayList<>();
1800
-
1801
- // 处理多寄存器指令 (invoke 指令使用 FiveRegisterInstruction)
1802
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction) {
1803
- com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction regInstr =
1804
- (com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction) instruction;
1805
- int regCount = regInstr.getRegisterCount();
1806
- if (regCount >= 1) registers.add(regInstr.getRegisterC());
1807
- if (regCount >= 2) registers.add(regInstr.getRegisterD());
1808
- if (regCount >= 3) registers.add(regInstr.getRegisterE());
1809
- if (regCount >= 4) registers.add(regInstr.getRegisterF());
1810
- if (regCount >= 5) registers.add(regInstr.getRegisterG());
1811
- } else if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstruction) {
1812
- com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstruction regInstr =
1813
- (com.android.tools.smali.dexlib2.iface.instruction.RegisterRangeInstruction) instruction;
1814
- int start = regInstr.getStartRegister();
1815
- int count = regInstr.getRegisterCount();
1816
- for (int i = 0; i < count; i++) {
1817
- registers.add(start + i);
1818
- }
1819
- } else {
1820
- // 处理普通寄存器指令
1821
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction) {
1822
- com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction regInstr =
1823
- (com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction) instruction;
1824
- registers.add(regInstr.getRegisterA());
1825
- }
1826
-
1827
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction) {
1828
- com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction regInstr =
1829
- (com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction) instruction;
1830
- registers.add(regInstr.getRegisterB());
1831
- }
1832
-
1833
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction) {
1834
- com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction regInstr =
1835
- (com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction) instruction;
1836
- registers.add(regInstr.getRegisterC());
1837
- }
1838
- }
1839
-
1840
- // 格式化寄存器部分
1841
- if (!registers.isEmpty()) {
1842
- if (isInvokeOrFilled) {
1843
- // invoke 指令使用 {} 包裹寄存器
1844
- sb.append("{");
1845
- for (int i = 0; i < registers.size(); i++) {
1846
- if (i > 0) sb.append(", ");
1847
- sb.append("v").append(registers.get(i));
1848
- }
1849
- sb.append("}");
1850
- } else {
1851
- // 普通指令直接列出寄存器
1852
- for (int i = 0; i < registers.size(); i++) {
1853
- if (i > 0) sb.append(", ");
1854
- sb.append("v").append(registers.get(i));
1855
- }
1856
- }
1857
- }
1858
-
1859
- // 处理引用指令
1860
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction) {
1861
- com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction refInstr =
1862
- (com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction) instruction;
1863
- if (sb.length() > 0) sb.append(", ");
1864
- sb.append(refInstr.getReference().toString());
1865
- }
1866
-
1867
- // 处理字面量指令
1868
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction) {
1869
- com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction litInstr =
1870
- (com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction) instruction;
1871
- if (sb.length() > 0) sb.append(", ");
1872
- sb.append("0x").append(Long.toHexString(litInstr.getWideLiteral()));
1873
- } else if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction) {
1874
- com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction litInstr =
1875
- (com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction) instruction;
1876
- if (sb.length() > 0) sb.append(", ");
1877
- sb.append("0x").append(Integer.toHexString(litInstr.getNarrowLiteral()));
1878
- }
1879
-
1880
- // 处理偏移指令
1881
- if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) {
1882
- com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction offInstr =
1883
- (com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) instruction;
1884
- if (sb.length() > 0) sb.append(", ");
1885
- sb.append(":label_").append(offInstr.getCodeOffset());
1886
- }
1887
-
1888
- return sb.toString();
1889
- }
1890
-
1891
1616
  /**
1892
1617
  * 保存修改后的 Smali 代码到 APK 中的 DEX 文件
1893
1618
  * 注意:这是一个复杂操作,需要重新编译 Smali 并修改 DEX 文件
@@ -1954,20 +1679,127 @@ public class DexManager {
1954
1679
 
1955
1680
  Log.d(TAG, "Smali compiled successfully to: " + outputDex.getAbsolutePath());
1956
1681
 
1957
- // TODO: 将编译后的 dex 合并回原 APK
1958
- // 这是一个复杂的操作,需要:
1959
- // 1. 解压 APK
1960
- // 2. 替换/合并 DEX 文件中的类
1961
- // 3. 重新打包 APK
1962
- // 4. 重新签名 APK
1682
+ // 将编译后的类合并到原 DEX 文件中
1683
+ // 1. 读取原 APK 中的 DEX 文件
1684
+ java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(apkPath);
1685
+ java.util.zip.ZipEntry dexEntry = zipFile.getEntry(dexPath);
1686
+
1687
+ if (dexEntry == null) {
1688
+ result.put("success", false);
1689
+ result.put("error", "DEX 文件未找到: " + dexPath);
1690
+ zipFile.close();
1691
+ cleanupTempDir(tempDir);
1692
+ return result;
1693
+ }
1694
+
1695
+ // 读取原 DEX
1696
+ java.io.InputStream dexInputStream = zipFile.getInputStream(dexEntry);
1697
+ java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
1698
+ byte[] buffer = new byte[8192];
1699
+ int len;
1700
+ while ((len = dexInputStream.read(buffer)) != -1) {
1701
+ baos.write(buffer, 0, len);
1702
+ }
1703
+ byte[] originalDexBytes = baos.toByteArray();
1704
+ dexInputStream.close();
1705
+
1706
+ // 解析原 DEX 和新编译的 DEX
1707
+ DexBackedDexFile originalDex = new DexBackedDexFile(Opcodes.getDefault(), originalDexBytes);
1708
+ DexBackedDexFile newDex = DexBackedDexFile.fromInputStream(Opcodes.getDefault(),
1709
+ new java.io.BufferedInputStream(new java.io.FileInputStream(outputDex)));
1710
+
1711
+ // 合并 DEX:用新类替换原类
1712
+ String targetType = "L" + className.replace(".", "/") + ";";
1713
+ java.util.List<ClassDef> mergedClasses = new java.util.ArrayList<>();
1714
+
1715
+ // 添加原 DEX 中除目标类外的所有类
1716
+ for (ClassDef classDef : originalDex.getClasses()) {
1717
+ if (!classDef.getType().equals(targetType)) {
1718
+ mergedClasses.add(classDef);
1719
+ }
1720
+ }
1721
+
1722
+ // 添加新编译的类
1723
+ for (ClassDef classDef : newDex.getClasses()) {
1724
+ mergedClasses.add(classDef);
1725
+ }
1726
+
1727
+ Log.d(TAG, "Merged " + mergedClasses.size() + " classes");
1728
+
1729
+ // 创建新的 DEX 文件
1730
+ java.io.File mergedDexFile = new java.io.File(tempDir, "classes_merged.dex");
1731
+ DexPool dexPool = new DexPool(Opcodes.getDefault());
1732
+ for (ClassDef classDef : mergedClasses) {
1733
+ dexPool.internClass(classDef);
1734
+ }
1735
+ dexPool.writeTo(new FileDataStore(mergedDexFile));
1736
+
1737
+ Log.d(TAG, "Merged DEX written to: " + mergedDexFile.getAbsolutePath());
1738
+
1739
+ // 2. 创建新的 APK(复制原 APK 并替换 DEX)
1740
+ java.io.File outputApk = new java.io.File(apkPath + ".modified.apk");
1741
+ java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(
1742
+ new java.io.FileOutputStream(outputApk));
1743
+
1744
+ // 复制原 APK 中的所有条目(除了要替换的 DEX)
1745
+ java.util.Enumeration<? extends java.util.zip.ZipEntry> entries = zipFile.entries();
1746
+ while (entries.hasMoreElements()) {
1747
+ java.util.zip.ZipEntry entry = entries.nextElement();
1748
+ if (entry.getName().equals(dexPath)) {
1749
+ // 跳过原 DEX,稍后添加新的
1750
+ continue;
1751
+ }
1752
+
1753
+ // 复制其他条目
1754
+ java.util.zip.ZipEntry newEntry = new java.util.zip.ZipEntry(entry.getName());
1755
+ zos.putNextEntry(newEntry);
1756
+
1757
+ if (!entry.isDirectory()) {
1758
+ java.io.InputStream is = zipFile.getInputStream(entry);
1759
+ while ((len = is.read(buffer)) != -1) {
1760
+ zos.write(buffer, 0, len);
1761
+ }
1762
+ is.close();
1763
+ }
1764
+ zos.closeEntry();
1765
+ }
1766
+
1767
+ // 添加修改后的 DEX
1768
+ java.util.zip.ZipEntry newDexEntry = new java.util.zip.ZipEntry(dexPath);
1769
+ zos.putNextEntry(newDexEntry);
1770
+ java.io.FileInputStream fis = new java.io.FileInputStream(mergedDexFile);
1771
+ while ((len = fis.read(buffer)) != -1) {
1772
+ zos.write(buffer, 0, len);
1773
+ }
1774
+ fis.close();
1775
+ zos.closeEntry();
1776
+
1777
+ zos.close();
1778
+ zipFile.close();
1779
+
1780
+ Log.d(TAG, "Modified APK written to: " + outputApk.getAbsolutePath());
1781
+
1782
+ // 3. 替换原 APK(先备份)
1783
+ java.io.File backupApk = new java.io.File(apkPath + ".backup");
1784
+ java.io.File originalApkFile = new java.io.File(apkPath);
1785
+
1786
+ // 复制原 APK 作为备份
1787
+ copyFile(originalApkFile, backupApk);
1788
+
1789
+ // 用修改后的 APK 替换原 APK
1790
+ copyFile(outputApk, originalApkFile);
1791
+
1792
+ // 删除临时修改的 APK
1793
+ outputApk.delete();
1794
+
1795
+ Log.d(TAG, "APK updated successfully. Backup at: " + backupApk.getAbsolutePath());
1963
1796
 
1964
- // 目前先返回成功,实际保存功能需要更多实现
1965
1797
  result.put("success", true);
1966
- result.put("message", "Smali 编译成功,但完整保存功能需要进一步实现");
1967
- result.put("compiledDexPath", outputDex.getAbsolutePath());
1798
+ result.put("message", "Smali 保存成功!已更新 APK");
1799
+ result.put("backupPath", backupApk.getAbsolutePath());
1968
1800
 
1969
- // 清理临时文件(暂时保留以便调试)
1970
- // cleanupTempDir(tempDir);
1801
+ // 清理临时文件
1802
+ cleanupTempDir(tempDir);
1971
1803
 
1972
1804
  } catch (Exception e) {
1973
1805
  Log.e(TAG, "Error saving smali: " + e.getMessage(), e);
@@ -1978,6 +1810,21 @@ public class DexManager {
1978
1810
  return result;
1979
1811
  }
1980
1812
 
1813
+ /**
1814
+ * 复制文件
1815
+ */
1816
+ private void copyFile(java.io.File src, java.io.File dst) throws java.io.IOException {
1817
+ java.io.FileInputStream fis = new java.io.FileInputStream(src);
1818
+ java.io.FileOutputStream fos = new java.io.FileOutputStream(dst);
1819
+ byte[] buffer = new byte[8192];
1820
+ int len;
1821
+ while ((len = fis.read(buffer)) != -1) {
1822
+ fos.write(buffer, 0, len);
1823
+ }
1824
+ fis.close();
1825
+ fos.close();
1826
+ }
1827
+
1981
1828
  /**
1982
1829
  * 清理临时目录
1983
1830
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
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",