capacitor-dex-editor 0.0.69 → 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.
- package/android/build.gradle +22 -0
- package/android/src/main/cpp/CMakeLists.txt +57 -0
- package/android/src/main/cpp/apk/apk_handler.cpp +121 -0
- package/android/src/main/cpp/apk/zip_utils.cpp +425 -0
- package/android/src/main/cpp/arsc/arsc_parser.cpp +390 -0
- package/android/src/main/cpp/dex/dex_builder.cpp +752 -0
- package/android/src/main/cpp/dex/dex_parser.cpp +620 -0
- package/android/src/main/cpp/dex/smali_disasm.cpp +1223 -0
- package/android/src/main/cpp/dex/smali_to_java.cpp +576 -0
- package/android/src/main/cpp/include/apk/apk_handler.h +41 -0
- package/android/src/main/cpp/include/apk/zip_utils.h +57 -0
- package/android/src/main/cpp/include/arsc/arsc_parser.h +98 -0
- package/android/src/main/cpp/include/dex/dex_builder.h +189 -0
- package/android/src/main/cpp/include/dex/dex_parser.h +137 -0
- package/android/src/main/cpp/include/dex/smali_disasm.h +127 -0
- package/android/src/main/cpp/include/dex/smali_to_java.h +50 -0
- package/android/src/main/cpp/include/xml/android_resources.h +495 -0
- package/android/src/main/cpp/include/xml/axml_parser.h +147 -0
- package/android/src/main/cpp/jni_bridge.cpp +872 -0
- package/android/src/main/cpp/third_party/miniz.c +646 -0
- package/android/src/main/cpp/third_party/miniz.h +605 -0
- package/android/src/main/cpp/third_party/miniz_common.h +97 -0
- package/android/src/main/cpp/third_party/miniz_export.h +6 -0
- package/android/src/main/cpp/third_party/miniz_tdef.c +1597 -0
- package/android/src/main/cpp/third_party/miniz_tdef.h +199 -0
- package/android/src/main/cpp/third_party/miniz_tinfl.c +770 -0
- package/android/src/main/cpp/third_party/miniz_tinfl.h +150 -0
- package/android/src/main/cpp/third_party/miniz_zip.c +4895 -0
- package/android/src/main/cpp/third_party/miniz_zip.h +454 -0
- package/android/src/main/cpp/third_party/nlohmann_json/CMakeLists.txt +0 -0
- package/android/src/main/cpp/third_party/nlohmann_json/single_include/nlohmann/json.hpp +24765 -0
- package/android/src/main/cpp/xml/axml_parser.cpp +1701 -0
- package/android/src/main/java/com/aetherlink/dexeditor/CppDex.java +295 -0
- package/android/src/main/java/com/aetherlink/dexeditor/DexManager.java +20 -20
- package/package.json +1 -1
- package/android/src/main/java/com/aetherlink/dexeditor/RustDex.java +0 -203
- 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
|
@@ -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 (!
|
|
1713
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 (!
|
|
1774
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 (!
|
|
1852
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 (!
|
|
1885
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
1927
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 (!
|
|
1961
|
-
throw new RuntimeException("
|
|
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 =
|
|
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 =
|
|
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,203 +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
|
-
|
|
109
|
-
// ==================== 方法级操作 ====================
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* 列出类中的所有方法
|
|
113
|
-
* @param dexBytes DEX 文件字节数组
|
|
114
|
-
* @param className 类名
|
|
115
|
-
* @return JSON 格式的方法列表
|
|
116
|
-
*/
|
|
117
|
-
public static native String listMethods(
|
|
118
|
-
byte[] dexBytes,
|
|
119
|
-
String className
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 获取单个方法的 Smali 代码
|
|
124
|
-
* @param dexBytes DEX 文件字节数组
|
|
125
|
-
* @param className 类名
|
|
126
|
-
* @param methodName 方法名
|
|
127
|
-
* @param methodSignature 方法签名(可为空字符串表示不限制)
|
|
128
|
-
* @return JSON 格式的方法 Smali 代码
|
|
129
|
-
*/
|
|
130
|
-
public static native String getMethod(
|
|
131
|
-
byte[] dexBytes,
|
|
132
|
-
String className,
|
|
133
|
-
String methodName,
|
|
134
|
-
String methodSignature
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* 添加方法到类
|
|
139
|
-
* @param dexBytes DEX 文件字节数组
|
|
140
|
-
* @param className 类名
|
|
141
|
-
* @param methodSmali 方法的 Smali 代码
|
|
142
|
-
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
143
|
-
*/
|
|
144
|
-
public static native byte[] addMethod(
|
|
145
|
-
byte[] dexBytes,
|
|
146
|
-
String className,
|
|
147
|
-
String methodSmali
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* 删除类中的方法
|
|
152
|
-
* @param dexBytes DEX 文件字节数组
|
|
153
|
-
* @param className 类名
|
|
154
|
-
* @param methodName 方法名
|
|
155
|
-
* @param methodSignature 方法签名(可为空字符串表示不限制)
|
|
156
|
-
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
157
|
-
*/
|
|
158
|
-
public static native byte[] deleteMethod(
|
|
159
|
-
byte[] dexBytes,
|
|
160
|
-
String className,
|
|
161
|
-
String methodName,
|
|
162
|
-
String methodSignature
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// ==================== 字段级操作 ====================
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 列出类中的所有字段
|
|
169
|
-
* @param dexBytes DEX 文件字节数组
|
|
170
|
-
* @param className 类名
|
|
171
|
-
* @return JSON 格式的字段列表
|
|
172
|
-
*/
|
|
173
|
-
public static native String listFields(
|
|
174
|
-
byte[] dexBytes,
|
|
175
|
-
String className
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* 添加字段到类
|
|
180
|
-
* @param dexBytes DEX 文件字节数组
|
|
181
|
-
* @param className 类名
|
|
182
|
-
* @param fieldSmali 字段的 Smali 定义(如 ".field public myField:I")
|
|
183
|
-
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
184
|
-
*/
|
|
185
|
-
public static native byte[] addField(
|
|
186
|
-
byte[] dexBytes,
|
|
187
|
-
String className,
|
|
188
|
-
String fieldSmali
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* 删除类中的字段
|
|
193
|
-
* @param dexBytes DEX 文件字节数组
|
|
194
|
-
* @param className 类名
|
|
195
|
-
* @param fieldName 字段名
|
|
196
|
-
* @return 修改后的 DEX 字节数组,失败返回 null
|
|
197
|
-
*/
|
|
198
|
-
public static native byte[] deleteField(
|
|
199
|
-
byte[] dexBytes,
|
|
200
|
-
String className,
|
|
201
|
-
String fieldName
|
|
202
|
-
);
|
|
203
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|