capacitor-dex-editor 0.0.14 → 0.0.16

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.
@@ -1621,67 +1621,84 @@ public class DexManager {
1621
1621
 
1622
1622
  smali.append("\n");
1623
1623
 
1624
- // 字段
1625
- smali.append("# ========== 字段 ==========\n");
1624
+ // 分离静态字段和实例字段
1625
+ java.util.List<Field> staticFields = new java.util.ArrayList<>();
1626
+ java.util.List<Field> instanceFields = new java.util.ArrayList<>();
1626
1627
  for (Field field : targetClass.getFields()) {
1627
- smali.append(".field ");
1628
- int fFlags = field.getAccessFlags();
1629
- if ((fFlags & 0x0001) != 0) smali.append("public ");
1630
- if ((fFlags & 0x0002) != 0) smali.append("private ");
1631
- if ((fFlags & 0x0004) != 0) smali.append("protected ");
1632
- if ((fFlags & 0x0008) != 0) smali.append("static ");
1633
- if ((fFlags & 0x0010) != 0) smali.append("final ");
1634
- if ((fFlags & 0x0040) != 0) smali.append("volatile ");
1635
- if ((fFlags & 0x0080) != 0) smali.append("transient ");
1636
- if ((fFlags & 0x1000) != 0) smali.append("synthetic ");
1637
- if ((fFlags & 0x4000) != 0) smali.append("enum ");
1638
- smali.append(field.getName()).append(":").append(field.getType()).append("\n");
1628
+ if ((field.getAccessFlags() & 0x0008) != 0) {
1629
+ staticFields.add(field);
1630
+ } else {
1631
+ instanceFields.add(field);
1632
+ }
1639
1633
  }
1640
1634
 
1641
- smali.append("\n");
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
+ }
1642
1654
 
1643
- // 方法
1644
- smali.append("# ========== 方法 ==========\n");
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<>();
1645
1677
  for (Method method : targetClass.getMethods()) {
1646
- smali.append("\n.method ");
1647
1678
  int mFlags = method.getAccessFlags();
1648
- if ((mFlags & 0x0001) != 0) smali.append("public ");
1649
- if ((mFlags & 0x0002) != 0) smali.append("private ");
1650
- if ((mFlags & 0x0004) != 0) smali.append("protected ");
1651
- if ((mFlags & 0x0008) != 0) smali.append("static ");
1652
- if ((mFlags & 0x0010) != 0) smali.append("final ");
1653
- if ((mFlags & 0x0020) != 0) smali.append("synchronized ");
1654
- if ((mFlags & 0x0040) != 0) smali.append("bridge ");
1655
- if ((mFlags & 0x0080) != 0) smali.append("varargs ");
1656
- if ((mFlags & 0x0100) != 0) smali.append("native ");
1657
- if ((mFlags & 0x0400) != 0) smali.append("abstract ");
1658
- if ((mFlags & 0x0800) != 0) smali.append("strictfp ");
1659
- if ((mFlags & 0x1000) != 0) smali.append("synthetic ");
1660
- if ((mFlags & 0x10000) != 0) smali.append("constructor ");
1661
- if ((mFlags & 0x20000) != 0) smali.append("declared-synchronized ");
1662
-
1663
- smali.append(method.getName());
1664
- smali.append("(");
1665
- for (CharSequence param : method.getParameterTypes()) {
1666
- smali.append(param);
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);
1667
1685
  }
1668
- smali.append(")");
1669
- smali.append(method.getReturnType());
1670
- smali.append("\n");
1671
-
1672
- MethodImplementation impl = method.getImplementation();
1673
- if (impl != null) {
1674
- smali.append(" .registers ").append(impl.getRegisterCount()).append("\n");
1675
-
1676
- // 输出指令
1677
- for (Instruction instruction : impl.getInstructions()) {
1678
- smali.append(" ").append(instruction.getOpcode().name.toLowerCase());
1679
- smali.append(" ").append(formatInstruction(instruction));
1680
- smali.append("\n");
1681
- }
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);
1682
1701
  }
1683
-
1684
- smali.append(".end method\n");
1685
1702
  }
1686
1703
 
1687
1704
  result.put("smali", smali.toString());
@@ -1698,6 +1715,77 @@ public class DexManager {
1698
1715
  return result;
1699
1716
  }
1700
1717
 
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
+
1701
1789
  /**
1702
1790
  * 格式化指令参数 - 使用正确的 Smali 语法格式
1703
1791
  * invoke 指令格式: invoke-xxx {v0, v1}, Lclass;->method()V
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
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",