capacitor-dex-editor 0.0.68 → 0.0.70

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.
Files changed (40) hide show
  1. package/android/build.gradle +22 -0
  2. package/android/src/main/cpp/CMakeLists.txt +57 -0
  3. package/android/src/main/cpp/apk/apk_handler.cpp +121 -0
  4. package/android/src/main/cpp/apk/zip_utils.cpp +425 -0
  5. package/android/src/main/cpp/arsc/arsc_parser.cpp +390 -0
  6. package/android/src/main/cpp/dex/dex_builder.cpp +752 -0
  7. package/android/src/main/cpp/dex/dex_parser.cpp +620 -0
  8. package/android/src/main/cpp/dex/smali_disasm.cpp +1223 -0
  9. package/android/src/main/cpp/dex/smali_to_java.cpp +576 -0
  10. package/android/src/main/cpp/include/apk/apk_handler.h +41 -0
  11. package/android/src/main/cpp/include/apk/zip_utils.h +57 -0
  12. package/android/src/main/cpp/include/arsc/arsc_parser.h +98 -0
  13. package/android/src/main/cpp/include/dex/dex_builder.h +189 -0
  14. package/android/src/main/cpp/include/dex/dex_parser.h +137 -0
  15. package/android/src/main/cpp/include/dex/smali_disasm.h +127 -0
  16. package/android/src/main/cpp/include/dex/smali_to_java.h +50 -0
  17. package/android/src/main/cpp/include/xml/android_resources.h +495 -0
  18. package/android/src/main/cpp/include/xml/axml_parser.h +147 -0
  19. package/android/src/main/cpp/jni_bridge.cpp +872 -0
  20. package/android/src/main/cpp/third_party/miniz.c +646 -0
  21. package/android/src/main/cpp/third_party/miniz.h +605 -0
  22. package/android/src/main/cpp/third_party/miniz_common.h +97 -0
  23. package/android/src/main/cpp/third_party/miniz_export.h +6 -0
  24. package/android/src/main/cpp/third_party/miniz_tdef.c +1597 -0
  25. package/android/src/main/cpp/third_party/miniz_tdef.h +199 -0
  26. package/android/src/main/cpp/third_party/miniz_tinfl.c +770 -0
  27. package/android/src/main/cpp/third_party/miniz_tinfl.h +150 -0
  28. package/android/src/main/cpp/third_party/miniz_zip.c +4895 -0
  29. package/android/src/main/cpp/third_party/miniz_zip.h +454 -0
  30. package/android/src/main/cpp/third_party/nlohmann_json/CMakeLists.txt +0 -0
  31. package/android/src/main/cpp/third_party/nlohmann_json/single_include/nlohmann/json.hpp +24765 -0
  32. package/android/src/main/cpp/xml/axml_parser.cpp +1701 -0
  33. package/android/src/main/java/com/aetherlink/dexeditor/CppDex.java +295 -0
  34. package/android/src/main/java/com/aetherlink/dexeditor/DexManager.java +20 -20
  35. package/package.json +1 -1
  36. package/android/src/main/java/com/aetherlink/dexeditor/RustDex.java +0 -108
  37. package/android/src/main/jniLibs/arm64-v8a/libdex_rust.so +0 -0
  38. package/android/src/main/jniLibs/armeabi-v7a/libdex_rust.so +0 -0
  39. package/android/src/main/jniLibs/x86/libdex_rust.so +0 -0
  40. package/android/src/main/jniLibs/x86_64/libdex_rust.so +0 -0
@@ -0,0 +1,295 @@
1
+ package com.aetherlink.dexeditor;
2
+
3
+ import android.util.Log;
4
+
5
+ /**
6
+ * CppDex - C++ 实现的 DEX 解析器 JNI 接口
7
+ * 高性能 DEX 解析、搜索、反汇编
8
+ */
9
+ public class CppDex {
10
+ private static final String TAG = "CppDex";
11
+ private static boolean libraryLoaded = false;
12
+
13
+ static {
14
+ try {
15
+ System.loadLibrary("dex_cpp");
16
+ libraryLoaded = true;
17
+ Log.d(TAG, "C++ library loaded successfully");
18
+ } catch (UnsatisfiedLinkError e) {
19
+ Log.w(TAG, "Failed to load C++ library: " + e.getMessage());
20
+ libraryLoaded = false;
21
+ }
22
+ }
23
+
24
+ /**
25
+ * 检查 C++ 库是否可用
26
+ */
27
+ public static boolean isAvailable() {
28
+ return libraryLoaded;
29
+ }
30
+
31
+ // ==================== DEX 解析操作 ====================
32
+
33
+ /**
34
+ * 获取 DEX 文件信息
35
+ * @param dexBytes DEX 文件字节数组
36
+ * @return JSON 格式的 DEX 信息
37
+ */
38
+ public static native String getDexInfo(byte[] dexBytes);
39
+
40
+ /**
41
+ * 列出 DEX 中的类
42
+ * @param dexBytes DEX 文件字节数组
43
+ * @param packageFilter 包名过滤器
44
+ * @param offset 偏移量
45
+ * @param limit 限制数量
46
+ * @return JSON 格式的类列表
47
+ */
48
+ public static native String listClasses(
49
+ byte[] dexBytes,
50
+ String packageFilter,
51
+ int offset,
52
+ int limit
53
+ );
54
+
55
+ /**
56
+ * 在 DEX 中搜索
57
+ * @param dexBytes DEX 文件字节数组
58
+ * @param query 搜索查询
59
+ * @param searchType 搜索类型: class, method, field, string
60
+ * @param caseSensitive 是否区分大小写
61
+ * @param maxResults 最大结果数
62
+ * @return JSON 格式的搜索结果
63
+ */
64
+ public static native String searchInDex(
65
+ byte[] dexBytes,
66
+ String query,
67
+ String searchType,
68
+ boolean caseSensitive,
69
+ int maxResults
70
+ );
71
+
72
+ /**
73
+ * 获取类的 Smali 代码
74
+ * @param dexBytes DEX 文件字节数组
75
+ * @param className 类名
76
+ * @return JSON 格式的 Smali 代码
77
+ */
78
+ public static native String getClassSmali(
79
+ byte[] dexBytes,
80
+ String className
81
+ );
82
+
83
+ /**
84
+ * 获取单个方法的 Smali 代码
85
+ * @param dexBytes DEX 文件字节数组
86
+ * @param className 类名
87
+ * @param methodName 方法名
88
+ * @param methodSignature 方法签名
89
+ * @return JSON 格式的方法 Smali 代码
90
+ */
91
+ public static native String getMethodSmali(
92
+ byte[] dexBytes,
93
+ String className,
94
+ String methodName,
95
+ String methodSignature
96
+ );
97
+
98
+ // ==================== Smali 转 Java ====================
99
+
100
+ /**
101
+ * 将 Smali 代码转换为 Java 伪代码
102
+ * @param dexBytes DEX 文件字节数组
103
+ * @param className 类名
104
+ * @return JSON 格式的 Java 伪代码
105
+ */
106
+ public static native String smaliToJava(
107
+ byte[] dexBytes,
108
+ String className
109
+ );
110
+
111
+ // ==================== DEX 修改操作 ====================
112
+
113
+ /**
114
+ * 修改 DEX 中的类
115
+ * @param dexBytes DEX 文件字节数组
116
+ * @param className 类名
117
+ * @param newSmali 新的 Smali 代码
118
+ * @return 修改后的 DEX 字节数组,失败返回 null
119
+ */
120
+ public static native byte[] modifyClass(
121
+ byte[] dexBytes,
122
+ String className,
123
+ String newSmali
124
+ );
125
+
126
+ /**
127
+ * 添加新类到 DEX
128
+ * @param dexBytes DEX 文件字节数组
129
+ * @param newSmali 新类的 Smali 代码
130
+ * @return 修改后的 DEX 字节数组,失败返回 null
131
+ */
132
+ public static native byte[] addClass(
133
+ byte[] dexBytes,
134
+ String newSmali
135
+ );
136
+
137
+ /**
138
+ * 从 DEX 中删除类
139
+ * @param dexBytes DEX 文件字节数组
140
+ * @param className 要删除的类名
141
+ * @return 修改后的 DEX 字节数组,失败返回 null
142
+ */
143
+ public static native byte[] deleteClass(
144
+ byte[] dexBytes,
145
+ String className
146
+ );
147
+
148
+ // ==================== 方法级操作 ====================
149
+
150
+ /**
151
+ * 列出类中的所有方法
152
+ * @param dexBytes DEX 文件字节数组
153
+ * @param className 类名
154
+ * @return JSON 格式的方法列表
155
+ */
156
+ public static native String listMethods(
157
+ byte[] dexBytes,
158
+ String className
159
+ );
160
+
161
+ /**
162
+ * 列出类中的所有字段
163
+ * @param dexBytes DEX 文件字节数组
164
+ * @param className 类名
165
+ * @return JSON 格式的字段列表
166
+ */
167
+ public static native String listFields(
168
+ byte[] dexBytes,
169
+ String className
170
+ );
171
+
172
+ // ==================== 字符串操作 ====================
173
+
174
+ /**
175
+ * 列出 DEX 中的字符串
176
+ * @param dexBytes DEX 文件字节数组
177
+ * @param filter 过滤器
178
+ * @param limit 限制数量
179
+ * @return JSON 格式的字符串列表
180
+ */
181
+ public static native String listStrings(
182
+ byte[] dexBytes,
183
+ String filter,
184
+ int limit
185
+ );
186
+
187
+ // ==================== 交叉引用分析 ====================
188
+
189
+ /**
190
+ * 查找方法的交叉引用
191
+ * @param dexBytes DEX 文件字节数组
192
+ * @param className 类名
193
+ * @param methodName 方法名
194
+ * @return JSON 格式的交叉引用列表
195
+ */
196
+ public static native String findMethodXrefs(
197
+ byte[] dexBytes,
198
+ String className,
199
+ String methodName
200
+ );
201
+
202
+ /**
203
+ * 查找字段的交叉引用
204
+ * @param dexBytes DEX 文件字节数组
205
+ * @param className 类名
206
+ * @param fieldName 字段名
207
+ * @return JSON 格式的交叉引用列表
208
+ */
209
+ public static native String findFieldXrefs(
210
+ byte[] dexBytes,
211
+ String className,
212
+ String fieldName
213
+ );
214
+
215
+ // ==================== Smali 编译 ====================
216
+
217
+ /**
218
+ * 将 Smali 代码编译为 DEX
219
+ * @param smaliCode Smali 代码
220
+ * @return 编译后的 DEX 字节数组,失败返回 null
221
+ */
222
+ public static native byte[] smaliToDex(String smaliCode);
223
+
224
+ // ==================== XML/资源解析 ====================
225
+
226
+ /**
227
+ * 解析二进制 XML (AndroidManifest.xml)
228
+ * @param axmlBytes AXML 字节数组
229
+ * @return JSON 格式的解析结果
230
+ */
231
+ public static native String parseAxml(byte[] axmlBytes);
232
+
233
+ /**
234
+ * 编辑 AndroidManifest.xml 属性
235
+ * @param axmlBytes AXML 字节数组
236
+ * @param action 操作: set_package, set_version_name, set_version_code, set_min_sdk, set_target_sdk
237
+ * @param value 新值
238
+ * @return 修改后的 AXML 字节数组,失败返回 null
239
+ */
240
+ public static native byte[] editManifest(
241
+ byte[] axmlBytes,
242
+ String action,
243
+ String value
244
+ );
245
+
246
+ /**
247
+ * 在 AndroidManifest.xml 中搜索
248
+ * @param axmlBytes AXML 字节数组
249
+ * @param attrName 属性名
250
+ * @param value 值
251
+ * @param limit 限制数量
252
+ * @return JSON 格式的搜索结果
253
+ */
254
+ public static native String searchXml(
255
+ byte[] axmlBytes,
256
+ String attrName,
257
+ String value,
258
+ int limit
259
+ );
260
+
261
+ /**
262
+ * 解析 resources.arsc
263
+ * @param arscBytes ARSC 字节数组
264
+ * @return JSON 格式的解析结果
265
+ */
266
+ public static native String parseArsc(byte[] arscBytes);
267
+
268
+ /**
269
+ * 搜索 ARSC 字符串
270
+ * @param arscBytes ARSC 字节数组
271
+ * @param pattern 搜索模式
272
+ * @param limit 限制数量
273
+ * @return JSON 格式的搜索结果
274
+ */
275
+ public static native String searchArscStrings(
276
+ byte[] arscBytes,
277
+ String pattern,
278
+ int limit
279
+ );
280
+
281
+ /**
282
+ * 搜索 ARSC 资源
283
+ * @param arscBytes ARSC 字节数组
284
+ * @param pattern 搜索模式
285
+ * @param type 资源类型 (string, drawable, layout 等)
286
+ * @param limit 限制数量
287
+ * @return JSON 格式的搜索结果
288
+ */
289
+ public static native String searchArscResources(
290
+ byte[] arscBytes,
291
+ String pattern,
292
+ String type,
293
+ int limit
294
+ );
295
+ }
@@ -1709,8 +1709,8 @@ 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");
1712
+ if (!CppDex.isAvailable() || session.dexBytes.isEmpty()) {
1713
+ throw new RuntimeException("C++ DEX library not available");
1714
1714
  }
1715
1715
 
1716
1716
  JSObject result = new JSObject();
@@ -1723,7 +1723,7 @@ public class DexManager {
1723
1723
  String dexName = entry.getKey();
1724
1724
  byte[] dexData = entry.getValue();
1725
1725
 
1726
- String jsonResult = RustDex.listClasses(dexData, filter, 0, 100000);
1726
+ String jsonResult = CppDex.listClasses(dexData, filter, 0, 100000);
1727
1727
  if (jsonResult != null && !jsonResult.contains("\"error\"")) {
1728
1728
  org.json.JSONObject rustResult = new org.json.JSONObject(jsonResult);
1729
1729
  org.json.JSONArray rustClasses = rustResult.optJSONArray("classes");
@@ -1770,8 +1770,8 @@ public class DexManager {
1770
1770
  throw new IllegalArgumentException("Session not found: " + sessionId);
1771
1771
  }
1772
1772
 
1773
- if (!RustDex.isAvailable()) {
1774
- throw new RuntimeException("Rust DEX library not available");
1773
+ if (!CppDex.isAvailable()) {
1774
+ throw new RuntimeException("C++ DEX library not available");
1775
1775
  }
1776
1776
 
1777
1777
  if (session.dexBytes.isEmpty()) {
@@ -1785,7 +1785,7 @@ public class DexManager {
1785
1785
  String dexName = entry.getKey();
1786
1786
  byte[] dexData = entry.getValue();
1787
1787
 
1788
- String jsonResult = RustDex.searchInDex(dexData, query, searchType, caseSensitive, maxResults);
1788
+ String jsonResult = CppDex.searchInDex(dexData, query, searchType, caseSensitive, maxResults);
1789
1789
 
1790
1790
  if (jsonResult != null && !jsonResult.contains("\"error\"")) {
1791
1791
  org.json.JSONObject rustResult = new org.json.JSONObject(jsonResult);
@@ -1848,8 +1848,8 @@ public class DexManager {
1848
1848
  throw new IllegalArgumentException("Session not found: " + sessionId);
1849
1849
  }
1850
1850
 
1851
- if (!RustDex.isAvailable()) {
1852
- throw new RuntimeException("Rust DEX library not available");
1851
+ if (!CppDex.isAvailable()) {
1852
+ throw new RuntimeException("C++ DEX library not available");
1853
1853
  }
1854
1854
 
1855
1855
  // 使用 Rust 获取 Smali
@@ -1857,7 +1857,7 @@ public class DexManager {
1857
1857
  String dexName = entry.getKey();
1858
1858
  byte[] dexData = entry.getValue();
1859
1859
 
1860
- String jsonResult = RustDex.getClassSmali(dexData, className);
1860
+ String jsonResult = CppDex.getClassSmali(dexData, className);
1861
1861
  if (jsonResult != null && !jsonResult.contains("\"error\"")) {
1862
1862
  org.json.JSONObject rustResult = new org.json.JSONObject(jsonResult);
1863
1863
  JSObject result = new JSObject();
@@ -1881,14 +1881,14 @@ public class DexManager {
1881
1881
  throw new IllegalArgumentException("Session not found: " + sessionId);
1882
1882
  }
1883
1883
 
1884
- if (!RustDex.isAvailable()) {
1885
- throw new RuntimeException("Rust DEX library not available");
1884
+ if (!CppDex.isAvailable()) {
1885
+ throw new RuntimeException("C++ DEX library not available");
1886
1886
  }
1887
1887
 
1888
1888
  // 找到类所在的 DEX
1889
1889
  String targetDex = null;
1890
1890
  for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
1891
- String jsonResult = RustDex.getClassSmali(entry.getValue(), className);
1891
+ String jsonResult = CppDex.getClassSmali(entry.getValue(), className);
1892
1892
  if (jsonResult != null && !jsonResult.contains("\"error\"")) {
1893
1893
  targetDex = entry.getKey();
1894
1894
  break;
@@ -1901,7 +1901,7 @@ public class DexManager {
1901
1901
 
1902
1902
  // 使用 Rust 修改类
1903
1903
  byte[] originalDex = session.dexBytes.get(targetDex);
1904
- byte[] modifiedDex = RustDex.modifyClass(originalDex, className, smaliContent);
1904
+ byte[] modifiedDex = CppDex.modifyClass(originalDex, className, smaliContent);
1905
1905
 
1906
1906
  if (modifiedDex == null) {
1907
1907
  throw new RuntimeException("Failed to modify class: " + className);
@@ -1923,8 +1923,8 @@ public class DexManager {
1923
1923
  throw new IllegalArgumentException("Session not found: " + sessionId);
1924
1924
  }
1925
1925
 
1926
- if (!RustDex.isAvailable()) {
1927
- throw new RuntimeException("Rust DEX library not available");
1926
+ if (!CppDex.isAvailable()) {
1927
+ throw new RuntimeException("C++ DEX library not available");
1928
1928
  }
1929
1929
 
1930
1930
  // 添加到第一个 DEX(默认 classes.dex)
@@ -1935,7 +1935,7 @@ public class DexManager {
1935
1935
 
1936
1936
  // 使用 Rust 添加类
1937
1937
  byte[] originalDex = session.dexBytes.get(targetDex);
1938
- byte[] modifiedDex = RustDex.addClass(originalDex, smaliContent);
1938
+ byte[] modifiedDex = CppDex.addClass(originalDex, smaliContent);
1939
1939
 
1940
1940
  if (modifiedDex == null) {
1941
1941
  throw new RuntimeException("Failed to add class: " + className);
@@ -1957,14 +1957,14 @@ public class DexManager {
1957
1957
  throw new IllegalArgumentException("Session not found: " + sessionId);
1958
1958
  }
1959
1959
 
1960
- if (!RustDex.isAvailable()) {
1961
- throw new RuntimeException("Rust DEX library not available");
1960
+ if (!CppDex.isAvailable()) {
1961
+ throw new RuntimeException("C++ DEX library not available");
1962
1962
  }
1963
1963
 
1964
1964
  // 找到类所在的 DEX
1965
1965
  String targetDex = null;
1966
1966
  for (Map.Entry<String, byte[]> entry : session.dexBytes.entrySet()) {
1967
- String jsonResult = RustDex.getClassSmali(entry.getValue(), className);
1967
+ String jsonResult = CppDex.getClassSmali(entry.getValue(), className);
1968
1968
  if (jsonResult != null && !jsonResult.contains("\"error\"")) {
1969
1969
  targetDex = entry.getKey();
1970
1970
  break;
@@ -1977,7 +1977,7 @@ public class DexManager {
1977
1977
 
1978
1978
  // 使用 Rust 删除类
1979
1979
  byte[] originalDex = session.dexBytes.get(targetDex);
1980
- byte[] modifiedDex = RustDex.deleteClass(originalDex, className);
1980
+ byte[] modifiedDex = CppDex.deleteClass(originalDex, className);
1981
1981
 
1982
1982
  if (modifiedDex == null) {
1983
1983
  throw new RuntimeException("Failed to delete class: " + className);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-dex-editor",
3
- "version": "0.0.68",
3
+ "version": "0.0.70",
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",
@@ -1,108 +0,0 @@
1
- package com.aetherlink.dexeditor;
2
-
3
- import android.util.Log;
4
-
5
- /**
6
- * RustDex - Rust 实现的 DEX 解析器 JNI 接口
7
- * 使用 azw413/smali crate 实现高性能 DEX 搜索
8
- */
9
- public class RustDex {
10
- private static final String TAG = "RustDex";
11
- private static boolean libraryLoaded = false;
12
-
13
- static {
14
- try {
15
- System.loadLibrary("dex_rust");
16
- libraryLoaded = true;
17
- Log.d(TAG, "Rust library loaded successfully");
18
- } catch (UnsatisfiedLinkError e) {
19
- Log.w(TAG, "Failed to load Rust library: " + e.getMessage());
20
- libraryLoaded = false;
21
- }
22
- }
23
-
24
- /**
25
- * 检查 Rust 库是否可用
26
- */
27
- public static boolean isAvailable() {
28
- return libraryLoaded;
29
- }
30
-
31
- /**
32
- * 在 DEX 中搜索
33
- * @param dexBytes DEX 文件字节数组
34
- * @param query 搜索查询
35
- * @param searchType 搜索类型: class, method, field, string, code
36
- * @param caseSensitive 是否区分大小写
37
- * @param maxResults 最大结果数
38
- * @return JSON 格式的搜索结果
39
- */
40
- public static native String searchInDex(
41
- byte[] dexBytes,
42
- String query,
43
- String searchType,
44
- boolean caseSensitive,
45
- int maxResults
46
- );
47
-
48
- /**
49
- * 列出 DEX 中的类
50
- * @param dexBytes DEX 文件字节数组
51
- * @param packageFilter 包名过滤器
52
- * @param offset 偏移量
53
- * @param limit 限制数量
54
- * @return JSON 格式的类列表
55
- */
56
- public static native String listClasses(
57
- byte[] dexBytes,
58
- String packageFilter,
59
- int offset,
60
- int limit
61
- );
62
-
63
- /**
64
- * 获取类的 Smali 代码
65
- * @param dexBytes DEX 文件字节数组
66
- * @param className 类名
67
- * @return JSON 格式的 Smali 代码
68
- */
69
- public static native String getClassSmali(
70
- byte[] dexBytes,
71
- String className
72
- );
73
-
74
- /**
75
- * 修改 DEX 中的类
76
- * @param dexBytes DEX 文件字节数组
77
- * @param className 类名
78
- * @param newSmali 新的 Smali 代码
79
- * @return 修改后的 DEX 字节数组,失败返回 null
80
- */
81
- public static native byte[] modifyClass(
82
- byte[] dexBytes,
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
- );
108
- }