capacitor-dex-editor 0.0.66 → 0.0.67
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.
- package/android/src/main/java/com/aetherlink/dexeditor/DexManager.java +90 -59
- package/android/src/main/java/com/aetherlink/dexeditor/RustDex.java +31 -9
- package/android/src/main/jniLibs/arm64-v8a/libdex_rust.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libdex_rust.so +0 -0
- package/android/src/main/jniLibs/x86/libdex_rust.so +0 -0
- package/android/src/main/jniLibs/x86_64/libdex_rust.so +0 -0
- package/package.json +1 -1
|
@@ -1701,7 +1701,7 @@ public class DexManager {
|
|
|
1701
1701
|
}
|
|
1702
1702
|
|
|
1703
1703
|
/**
|
|
1704
|
-
* 获取多 DEX
|
|
1704
|
+
* 获取多 DEX 会话中的类列表(Rust 实现)
|
|
1705
1705
|
*/
|
|
1706
1706
|
public JSObject getClassesFromMultiSession(String sessionId, String packageFilter, int offset, int limit) throws Exception {
|
|
1707
1707
|
MultiDexSession session = multiDexSessions.get(sessionId);
|
|
@@ -1709,26 +1709,29 @@ public class DexManager {
|
|
|
1709
1709
|
throw new IllegalArgumentException("Session not found: " + sessionId);
|
|
1710
1710
|
}
|
|
1711
1711
|
|
|
1712
|
+
if (!RustDex.isAvailable() || session.dexBytes.isEmpty()) {
|
|
1713
|
+
throw new RuntimeException("Rust DEX library not available");
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1712
1716
|
JSObject result = new JSObject();
|
|
1713
1717
|
JSArray classes = new JSArray();
|
|
1714
1718
|
List<String> allClasses = new ArrayList<>();
|
|
1719
|
+
String filter = packageFilter != null ? packageFilter : "";
|
|
1715
1720
|
|
|
1716
|
-
//
|
|
1717
|
-
for (Map.Entry<String,
|
|
1721
|
+
// 使用 Rust 获取每个 DEX 的类列表
|
|
1722
|
+
for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
|
|
1718
1723
|
String dexName = entry.getKey();
|
|
1719
|
-
|
|
1724
|
+
byte[] dexData = entry.getValue();
|
|
1720
1725
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
if (
|
|
1726
|
-
|
|
1727
|
-
|
|
1726
|
+
String jsonResult = RustDex.listClasses(dexData, filter, 0, 100000);
|
|
1727
|
+
if (jsonResult != null && !jsonResult.contains("\"error\"")) {
|
|
1728
|
+
org.json.JSONObject rustResult = new org.json.JSONObject(jsonResult);
|
|
1729
|
+
org.json.JSONArray rustClasses = rustResult.optJSONArray("classes");
|
|
1730
|
+
if (rustClasses != null) {
|
|
1731
|
+
for (int i = 0; i < rustClasses.length(); i++) {
|
|
1732
|
+
allClasses.add(rustClasses.getString(i) + "|" + dexName);
|
|
1728
1733
|
}
|
|
1729
1734
|
}
|
|
1730
|
-
|
|
1731
|
-
allClasses.add(className + "|" + dexName);
|
|
1732
1735
|
}
|
|
1733
1736
|
}
|
|
1734
1737
|
|
|
@@ -1752,6 +1755,7 @@ public class DexManager {
|
|
|
1752
1755
|
result.put("limit", limit);
|
|
1753
1756
|
result.put("classes", classes);
|
|
1754
1757
|
result.put("hasMore", end < total);
|
|
1758
|
+
result.put("engine", "rust");
|
|
1755
1759
|
|
|
1756
1760
|
return result;
|
|
1757
1761
|
}
|
|
@@ -1836,7 +1840,7 @@ public class DexManager {
|
|
|
1836
1840
|
|
|
1837
1841
|
|
|
1838
1842
|
/**
|
|
1839
|
-
* 从多 DEX 会话获取类的 Smali
|
|
1843
|
+
* 从多 DEX 会话获取类的 Smali 代码(Rust 实现)
|
|
1840
1844
|
*/
|
|
1841
1845
|
public JSObject getClassSmaliFromSession(String sessionId, String className) throws Exception {
|
|
1842
1846
|
MultiDexSession session = multiDexSessions.get(sessionId);
|
|
@@ -1844,20 +1848,24 @@ public class DexManager {
|
|
|
1844
1848
|
throw new IllegalArgumentException("Session not found: " + sessionId);
|
|
1845
1849
|
}
|
|
1846
1850
|
|
|
1847
|
-
|
|
1851
|
+
if (!RustDex.isAvailable()) {
|
|
1852
|
+
throw new RuntimeException("Rust DEX library not available");
|
|
1853
|
+
}
|
|
1848
1854
|
|
|
1849
|
-
|
|
1855
|
+
// 使用 Rust 获取 Smali
|
|
1856
|
+
for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
|
|
1850
1857
|
String dexName = entry.getKey();
|
|
1851
|
-
|
|
1858
|
+
byte[] dexData = entry.getValue();
|
|
1852
1859
|
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1860
|
+
String jsonResult = RustDex.getClassSmali(dexData, className);
|
|
1861
|
+
if (jsonResult != null && !jsonResult.contains("\"error\"")) {
|
|
1862
|
+
org.json.JSONObject rustResult = new org.json.JSONObject(jsonResult);
|
|
1863
|
+
JSObject result = new JSObject();
|
|
1864
|
+
result.put("className", className);
|
|
1865
|
+
result.put("dexFile", dexName);
|
|
1866
|
+
result.put("smaliContent", rustResult.optString("smaliContent", ""));
|
|
1867
|
+
result.put("engine", "rust");
|
|
1868
|
+
return result;
|
|
1861
1869
|
}
|
|
1862
1870
|
}
|
|
1863
1871
|
|
|
@@ -1865,7 +1873,7 @@ public class DexManager {
|
|
|
1865
1873
|
}
|
|
1866
1874
|
|
|
1867
1875
|
/**
|
|
1868
|
-
* 修改类并保存到多 DEX
|
|
1876
|
+
* 修改类并保存到多 DEX 会话(Rust 实现)
|
|
1869
1877
|
*/
|
|
1870
1878
|
public void modifyClassInSession(String sessionId, String className, String smaliContent) throws Exception {
|
|
1871
1879
|
MultiDexSession session = multiDexSessions.get(sessionId);
|
|
@@ -1873,36 +1881,41 @@ public class DexManager {
|
|
|
1873
1881
|
throw new IllegalArgumentException("Session not found: " + sessionId);
|
|
1874
1882
|
}
|
|
1875
1883
|
|
|
1876
|
-
|
|
1884
|
+
if (!RustDex.isAvailable()) {
|
|
1885
|
+
throw new RuntimeException("Rust DEX library not available");
|
|
1886
|
+
}
|
|
1877
1887
|
|
|
1878
1888
|
// 找到类所在的 DEX
|
|
1879
1889
|
String targetDex = null;
|
|
1880
|
-
for (Map.Entry<String,
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
}
|
|
1890
|
+
for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
|
|
1891
|
+
String jsonResult = RustDex.getClassSmali(entry.getValue(), className);
|
|
1892
|
+
if (jsonResult != null && !jsonResult.contains("\"error\"")) {
|
|
1893
|
+
targetDex = entry.getKey();
|
|
1894
|
+
break;
|
|
1886
1895
|
}
|
|
1887
|
-
if (targetDex != null) break;
|
|
1888
1896
|
}
|
|
1889
1897
|
|
|
1890
1898
|
if (targetDex == null) {
|
|
1891
1899
|
throw new IllegalArgumentException("Class not found: " + className);
|
|
1892
1900
|
}
|
|
1893
1901
|
|
|
1894
|
-
//
|
|
1895
|
-
|
|
1902
|
+
// 使用 Rust 修改类
|
|
1903
|
+
byte[] originalDex = session.dexBytes.get(targetDex);
|
|
1904
|
+
byte[] modifiedDex = RustDex.modifyClass(originalDex, className, smaliContent);
|
|
1896
1905
|
|
|
1897
|
-
|
|
1898
|
-
|
|
1906
|
+
if (modifiedDex == null) {
|
|
1907
|
+
throw new RuntimeException("Failed to modify class: " + className);
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
// 更新 DEX 字节数据
|
|
1911
|
+
session.dexBytes.put(targetDex, modifiedDex);
|
|
1899
1912
|
session.modified = true;
|
|
1900
1913
|
|
|
1901
|
-
Log.d(TAG, "Modified class in session: " + className);
|
|
1914
|
+
Log.d(TAG, "Modified class in session (Rust): " + className);
|
|
1902
1915
|
}
|
|
1903
1916
|
|
|
1904
1917
|
/**
|
|
1905
|
-
*
|
|
1918
|
+
* 添加新类到会话(Rust 实现)
|
|
1906
1919
|
*/
|
|
1907
1920
|
public void addClassToSession(String sessionId, String className, String smaliContent) throws Exception {
|
|
1908
1921
|
MultiDexSession session = multiDexSessions.get(sessionId);
|
|
@@ -1910,23 +1923,33 @@ public class DexManager {
|
|
|
1910
1923
|
throw new IllegalArgumentException("Session not found: " + sessionId);
|
|
1911
1924
|
}
|
|
1912
1925
|
|
|
1913
|
-
|
|
1914
|
-
|
|
1926
|
+
if (!RustDex.isAvailable()) {
|
|
1927
|
+
throw new RuntimeException("Rust DEX library not available");
|
|
1928
|
+
}
|
|
1915
1929
|
|
|
1916
1930
|
// 添加到第一个 DEX(默认 classes.dex)
|
|
1917
1931
|
String targetDex = "classes.dex";
|
|
1918
|
-
if (!session.
|
|
1919
|
-
targetDex = session.
|
|
1932
|
+
if (!session.dexBytes.containsKey(targetDex) && !session.dexBytes.isEmpty()) {
|
|
1933
|
+
targetDex = session.dexBytes.keySet().iterator().next();
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
// 使用 Rust 添加类
|
|
1937
|
+
byte[] originalDex = session.dexBytes.get(targetDex);
|
|
1938
|
+
byte[] modifiedDex = RustDex.addClass(originalDex, smaliContent);
|
|
1939
|
+
|
|
1940
|
+
if (modifiedDex == null) {
|
|
1941
|
+
throw new RuntimeException("Failed to add class: " + className);
|
|
1920
1942
|
}
|
|
1921
1943
|
|
|
1922
|
-
|
|
1944
|
+
// 更新 DEX 字节数据
|
|
1945
|
+
session.dexBytes.put(targetDex, modifiedDex);
|
|
1923
1946
|
session.modified = true;
|
|
1924
1947
|
|
|
1925
|
-
Log.d(TAG, "Added class to session: " + className);
|
|
1948
|
+
Log.d(TAG, "Added class to session (Rust): " + className);
|
|
1926
1949
|
}
|
|
1927
1950
|
|
|
1928
1951
|
/**
|
|
1929
|
-
*
|
|
1952
|
+
* 从会话中删除类(Rust 实现)
|
|
1930
1953
|
*/
|
|
1931
1954
|
public void deleteClassFromSession(String sessionId, String className) throws Exception {
|
|
1932
1955
|
MultiDexSession session = multiDexSessions.get(sessionId);
|
|
@@ -1934,29 +1957,37 @@ public class DexManager {
|
|
|
1934
1957
|
throw new IllegalArgumentException("Session not found: " + sessionId);
|
|
1935
1958
|
}
|
|
1936
1959
|
|
|
1937
|
-
|
|
1960
|
+
if (!RustDex.isAvailable()) {
|
|
1961
|
+
throw new RuntimeException("Rust DEX library not available");
|
|
1962
|
+
}
|
|
1938
1963
|
|
|
1939
|
-
// 找到类所在的 DEX
|
|
1964
|
+
// 找到类所在的 DEX
|
|
1940
1965
|
String targetDex = null;
|
|
1941
|
-
for (Map.Entry<String,
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
}
|
|
1966
|
+
for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
|
|
1967
|
+
String jsonResult = RustDex.getClassSmali(entry.getValue(), className);
|
|
1968
|
+
if (jsonResult != null && !jsonResult.contains("\"error\"")) {
|
|
1969
|
+
targetDex = entry.getKey();
|
|
1970
|
+
break;
|
|
1947
1971
|
}
|
|
1948
|
-
if (targetDex != null) break;
|
|
1949
1972
|
}
|
|
1950
1973
|
|
|
1951
1974
|
if (targetDex == null) {
|
|
1952
1975
|
throw new IllegalArgumentException("Class not found: " + className);
|
|
1953
1976
|
}
|
|
1954
1977
|
|
|
1955
|
-
//
|
|
1956
|
-
session.
|
|
1978
|
+
// 使用 Rust 删除类
|
|
1979
|
+
byte[] originalDex = session.dexBytes.get(targetDex);
|
|
1980
|
+
byte[] modifiedDex = RustDex.deleteClass(originalDex, className);
|
|
1981
|
+
|
|
1982
|
+
if (modifiedDex == null) {
|
|
1983
|
+
throw new RuntimeException("Failed to delete class: " + className);
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// 更新 DEX 字节数据
|
|
1987
|
+
session.dexBytes.put(targetDex, modifiedDex);
|
|
1957
1988
|
session.modified = true;
|
|
1958
1989
|
|
|
1959
|
-
Log.d(TAG, "Deleted class from session: " + className);
|
|
1990
|
+
Log.d(TAG, "Deleted class from session (Rust): " + className);
|
|
1960
1991
|
}
|
|
1961
1992
|
|
|
1962
1993
|
/**
|
|
@@ -72,15 +72,37 @@ public class RustDex {
|
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* 修改 DEX 中的类
|
|
76
|
+
* @param dexBytes DEX 文件字节数组
|
|
77
|
+
* @param className 类名
|
|
78
|
+
* @param newSmali 新的 Smali 代码
|
|
79
|
+
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
76
80
|
*/
|
|
77
|
-
public static
|
|
81
|
+
public static native byte[] modifyClass(
|
|
78
82
|
byte[] dexBytes,
|
|
79
|
-
String
|
|
80
|
-
String
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
String className,
|
|
84
|
+
String newSmali
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 添加新类到 DEX
|
|
89
|
+
* @param dexBytes DEX 文件字节数组
|
|
90
|
+
* @param newSmali 新类的 Smali 代码
|
|
91
|
+
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
92
|
+
*/
|
|
93
|
+
public static native byte[] addClass(
|
|
94
|
+
byte[] dexBytes,
|
|
95
|
+
String newSmali
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 从 DEX 中删除类
|
|
100
|
+
* @param dexBytes DEX 文件字节数组
|
|
101
|
+
* @param className 要删除的类名
|
|
102
|
+
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
103
|
+
*/
|
|
104
|
+
public static native byte[] deleteClass(
|
|
105
|
+
byte[] dexBytes,
|
|
106
|
+
String className
|
|
107
|
+
);
|
|
86
108
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|