capacitor-dex-editor 0.0.15 → 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,94 +1621,84 @@ public class DexManager {
|
|
|
1621
1621
|
|
|
1622
1622
|
smali.append("\n");
|
|
1623
1623
|
|
|
1624
|
-
//
|
|
1625
|
-
|
|
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
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
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
|
-
|
|
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
|
+
}
|
|
1642
1673
|
|
|
1643
|
-
//
|
|
1644
|
-
|
|
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
|
-
|
|
1649
|
-
if ((mFlags & 0x0002) != 0
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
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
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
smali
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
if (instruction instanceof com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) {
|
|
1684
|
-
com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction offInstr =
|
|
1685
|
-
(com.android.tools.smali.dexlib2.iface.instruction.OffsetInstruction) instruction;
|
|
1686
|
-
int targetOffset = codeOffset + offInstr.getCodeOffset();
|
|
1687
|
-
labelMap.put(targetOffset, ":cond_" + Integer.toHexString(targetOffset));
|
|
1688
|
-
}
|
|
1689
|
-
codeOffset += instruction.getCodeUnits();
|
|
1690
|
-
}
|
|
1691
|
-
|
|
1692
|
-
// 第二遍:输出指令
|
|
1693
|
-
codeOffset = 0;
|
|
1694
|
-
for (Instruction instruction : impl.getInstructions()) {
|
|
1695
|
-
// 输出标签(如果有)
|
|
1696
|
-
if (labelMap.containsKey(codeOffset)) {
|
|
1697
|
-
smali.append("\n ").append(labelMap.get(codeOffset)).append("\n");
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
|
-
smali.append(" ").append(instruction.getOpcode().name.toLowerCase().replace('_', '-'));
|
|
1701
|
-
String params = formatInstruction(instruction);
|
|
1702
|
-
if (!params.isEmpty()) {
|
|
1703
|
-
smali.append(" ").append(params);
|
|
1704
|
-
}
|
|
1705
|
-
smali.append("\n");
|
|
1706
|
-
|
|
1707
|
-
codeOffset += instruction.getCodeUnits();
|
|
1708
|
-
}
|
|
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);
|
|
1709
1701
|
}
|
|
1710
|
-
|
|
1711
|
-
smali.append(".end method\n");
|
|
1712
1702
|
}
|
|
1713
1703
|
|
|
1714
1704
|
result.put("smali", smali.toString());
|
|
@@ -1725,6 +1715,77 @@ public class DexManager {
|
|
|
1725
1715
|
return result;
|
|
1726
1716
|
}
|
|
1727
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
|
+
|
|
1728
1789
|
/**
|
|
1729
1790
|
* 格式化指令参数 - 使用正确的 Smali 语法格式
|
|
1730
1791
|
* invoke 指令格式: invoke-xxx {v0, v1}, Lclass;->method()V
|