capacitor-dex-editor 0.0.69 → 0.0.71

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 +146 -50
  35. package/package.json +1 -1
  36. package/android/src/main/java/com/aetherlink/dexeditor/RustDex.java +0 -203
  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,495 @@
1
+ #pragma once
2
+
3
+ #include <cstdint>
4
+ #include <string>
5
+ #include <unordered_map>
6
+
7
+ namespace axml {
8
+
9
+ // 复杂类型单位(dimension 和 fraction)
10
+ enum ComplexUnit {
11
+ COMPLEX_UNIT_PX = 0, // 像素
12
+ COMPLEX_UNIT_DIP = 1, // 设备独立像素 (dp)
13
+ COMPLEX_UNIT_SP = 2, // 缩放独立像素 (sp)
14
+ COMPLEX_UNIT_PT = 3, // 点
15
+ COMPLEX_UNIT_IN = 4, // 英寸
16
+ COMPLEX_UNIT_MM = 5, // 毫米
17
+ COMPLEX_UNIT_FRACTION = 0, // 百分比 (%)
18
+ COMPLEX_UNIT_FRACTION_PARENT = 1 // 父容器百分比 (%p)
19
+ };
20
+
21
+ // 属性值类型 (完整列表参考 axmldec)
22
+ enum ResourceValueType : uint8_t {
23
+ TYPE_NULL = 0x00, // 空值
24
+ TYPE_REFERENCE = 0x01, // 资源引用 @resource
25
+ TYPE_ATTRIBUTE = 0x02, // 属性引用 ?attr
26
+ TYPE_STRING = 0x03, // 字符串
27
+ TYPE_FLOAT = 0x04, // 浮点数
28
+ TYPE_DIMENSION = 0x05, // 尺寸值 (100dp, 50sp)
29
+ TYPE_FRACTION = 0x06, // 百分比值 (50%, 25%p)
30
+ TYPE_DYNAMIC_REFERENCE = 0x07, // 动态资源引用
31
+
32
+ TYPE_FIRST_INT = 0x10,
33
+ TYPE_INT_DEC = 0x10, // 十进制整数
34
+ TYPE_INT_HEX = 0x11, // 十六进制整数
35
+ TYPE_INT_BOOLEAN = 0x12, // 布尔值
36
+
37
+ TYPE_FIRST_COLOR_INT = 0x1c,
38
+ TYPE_INT_COLOR_ARGB8 = 0x1c, // #AARRGGBB
39
+ TYPE_INT_COLOR_RGB8 = 0x1d, // #RRGGBB
40
+ TYPE_INT_COLOR_ARGB4 = 0x1e, // #ARGB
41
+ TYPE_INT_COLOR_RGB4 = 0x1f, // #RGB
42
+ TYPE_LAST_COLOR_INT = 0x1f,
43
+ TYPE_LAST_INT = 0x1f
44
+ };
45
+
46
+ // 解析复杂类型值 (dimension/fraction)
47
+ inline std::string parse_complex_value(uint32_t data, bool is_fraction) {
48
+ constexpr float MANTISSA_MULT = 1.0f / (1 << 8);
49
+ constexpr float RADIX_MULTS[] = {
50
+ MANTISSA_MULT * 1.0f,
51
+ MANTISSA_MULT * 1.0f / (1 << 7),
52
+ MANTISSA_MULT * 1.0f / (1 << 15),
53
+ MANTISSA_MULT * 1.0f / (1 << 23)
54
+ };
55
+
56
+ float value = static_cast<int32_t>(data & 0xffffff00) * RADIX_MULTS[(data >> 4) & 0x3];
57
+ uint8_t unit = data & 0xf;
58
+
59
+ char buf[64];
60
+ if (is_fraction) {
61
+ value *= 100.0f;
62
+ switch (unit) {
63
+ case COMPLEX_UNIT_FRACTION:
64
+ snprintf(buf, sizeof(buf), "%.2f%%", value);
65
+ break;
66
+ case COMPLEX_UNIT_FRACTION_PARENT:
67
+ snprintf(buf, sizeof(buf), "%.2f%%p", value);
68
+ break;
69
+ default:
70
+ snprintf(buf, sizeof(buf), "%.2f", value);
71
+ }
72
+ } else {
73
+ // 整数值去掉小数点
74
+ if (value == static_cast<int>(value)) {
75
+ switch (unit) {
76
+ case COMPLEX_UNIT_PX:
77
+ snprintf(buf, sizeof(buf), "%dpx", static_cast<int>(value));
78
+ break;
79
+ case COMPLEX_UNIT_DIP:
80
+ snprintf(buf, sizeof(buf), "%ddp", static_cast<int>(value));
81
+ break;
82
+ case COMPLEX_UNIT_SP:
83
+ snprintf(buf, sizeof(buf), "%dsp", static_cast<int>(value));
84
+ break;
85
+ case COMPLEX_UNIT_PT:
86
+ snprintf(buf, sizeof(buf), "%dpt", static_cast<int>(value));
87
+ break;
88
+ case COMPLEX_UNIT_IN:
89
+ snprintf(buf, sizeof(buf), "%din", static_cast<int>(value));
90
+ break;
91
+ case COMPLEX_UNIT_MM:
92
+ snprintf(buf, sizeof(buf), "%dmm", static_cast<int>(value));
93
+ break;
94
+ default:
95
+ snprintf(buf, sizeof(buf), "%d", static_cast<int>(value));
96
+ }
97
+ } else {
98
+ switch (unit) {
99
+ case COMPLEX_UNIT_PX:
100
+ snprintf(buf, sizeof(buf), "%.2fpx", value);
101
+ break;
102
+ case COMPLEX_UNIT_DIP:
103
+ snprintf(buf, sizeof(buf), "%.2fdp", value);
104
+ break;
105
+ case COMPLEX_UNIT_SP:
106
+ snprintf(buf, sizeof(buf), "%.2fsp", value);
107
+ break;
108
+ case COMPLEX_UNIT_PT:
109
+ snprintf(buf, sizeof(buf), "%.2fpt", value);
110
+ break;
111
+ case COMPLEX_UNIT_IN:
112
+ snprintf(buf, sizeof(buf), "%.2fin", value);
113
+ break;
114
+ case COMPLEX_UNIT_MM:
115
+ snprintf(buf, sizeof(buf), "%.2fmm", value);
116
+ break;
117
+ default:
118
+ snprintf(buf, sizeof(buf), "%.2f", value);
119
+ }
120
+ }
121
+ }
122
+ return std::string(buf);
123
+ }
124
+
125
+ // 编码复杂类型值
126
+ inline bool encode_complex_value(const std::string& str, uint32_t& data, bool& is_dimension) {
127
+ float value = 0.0f;
128
+ uint8_t unit = 0;
129
+ is_dimension = true;
130
+
131
+ // 尝试解析尺寸值
132
+ char unit_str[8] = {0};
133
+ if (sscanf(str.c_str(), "%f%7s", &value, unit_str) >= 1) {
134
+ std::string unit_s = unit_str;
135
+
136
+ if (unit_s == "dp" || unit_s == "dip") {
137
+ unit = COMPLEX_UNIT_DIP;
138
+ } else if (unit_s == "sp") {
139
+ unit = COMPLEX_UNIT_SP;
140
+ } else if (unit_s == "px") {
141
+ unit = COMPLEX_UNIT_PX;
142
+ } else if (unit_s == "pt") {
143
+ unit = COMPLEX_UNIT_PT;
144
+ } else if (unit_s == "in") {
145
+ unit = COMPLEX_UNIT_IN;
146
+ } else if (unit_s == "mm") {
147
+ unit = COMPLEX_UNIT_MM;
148
+ } else if (unit_s == "%" || unit_s == "%p") {
149
+ is_dimension = false;
150
+ unit = (unit_s == "%p") ? COMPLEX_UNIT_FRACTION_PARENT : COMPLEX_UNIT_FRACTION;
151
+ value /= 100.0f; // 百分比需要除以100
152
+ } else if (unit_s.empty()) {
153
+ // 纯数值
154
+ unit = COMPLEX_UNIT_PX;
155
+ } else {
156
+ return false;
157
+ }
158
+
159
+ // 编码值
160
+ constexpr float MANTISSA_MULT = 1.0f / (1 << 8);
161
+ int radix = 0;
162
+ float encoded_value = value / MANTISSA_MULT;
163
+
164
+ // 选择合适的基数
165
+ if (encoded_value >= 0x800000 || encoded_value <= -0x800000) {
166
+ radix = 0;
167
+ } else if (encoded_value >= 0x10000 || encoded_value <= -0x10000) {
168
+ radix = 1;
169
+ encoded_value *= (1 << 7);
170
+ } else if (encoded_value >= 0x200 || encoded_value <= -0x200) {
171
+ radix = 2;
172
+ encoded_value *= (1 << 15);
173
+ } else {
174
+ radix = 3;
175
+ encoded_value *= (1 << 23);
176
+ }
177
+
178
+ int32_t mantissa = static_cast<int32_t>(encoded_value) & 0xffffff00;
179
+ if (mantissa == 0 && value != 0) {
180
+ mantissa = static_cast<int32_t>(value) << 8;
181
+ }
182
+
183
+ data = (mantissa & 0xffffff00) | ((radix & 0x3) << 4) | (unit & 0xf);
184
+ return true;
185
+ }
186
+
187
+ return false;
188
+ }
189
+
190
+ // 解析颜色值为字符串
191
+ inline std::string format_color(uint32_t data, uint8_t type) {
192
+ char buf[16];
193
+ switch (type) {
194
+ case TYPE_INT_COLOR_ARGB8:
195
+ snprintf(buf, sizeof(buf), "#%08X", data);
196
+ break;
197
+ case TYPE_INT_COLOR_RGB8:
198
+ snprintf(buf, sizeof(buf), "#%06X", data & 0xFFFFFF);
199
+ break;
200
+ case TYPE_INT_COLOR_ARGB4:
201
+ snprintf(buf, sizeof(buf), "#%04X", data & 0xFFFF);
202
+ break;
203
+ case TYPE_INT_COLOR_RGB4:
204
+ snprintf(buf, sizeof(buf), "#%03X", data & 0xFFF);
205
+ break;
206
+ default:
207
+ snprintf(buf, sizeof(buf), "#%08X", data);
208
+ }
209
+ return std::string(buf);
210
+ }
211
+
212
+ // 解析颜色字符串为值
213
+ inline bool parse_color_string(const std::string& str, uint32_t& data, uint8_t& type) {
214
+ if (str.empty() || str[0] != '#') return false;
215
+
216
+ std::string hex = str.substr(1);
217
+ try {
218
+ data = std::stoul(hex, nullptr, 16);
219
+
220
+ switch (hex.length()) {
221
+ case 8: // #AARRGGBB
222
+ type = TYPE_INT_COLOR_ARGB8;
223
+ break;
224
+ case 6: // #RRGGBB
225
+ type = TYPE_INT_COLOR_RGB8;
226
+ // 补充 alpha 通道
227
+ data |= 0xFF000000;
228
+ break;
229
+ case 4: // #ARGB
230
+ type = TYPE_INT_COLOR_ARGB4;
231
+ break;
232
+ case 3: // #RGB
233
+ type = TYPE_INT_COLOR_RGB4;
234
+ break;
235
+ default:
236
+ return false;
237
+ }
238
+ return true;
239
+ } catch (...) {
240
+ return false;
241
+ }
242
+ }
243
+
244
+ // Android 属性资源 ID 映射表 (基于 axmldec)
245
+ // 资源 ID 格式: 0x01010XXX (android:xxx 属性)
246
+ inline const char* get_android_attr_name(uint32_t res_id) {
247
+ static const std::unordered_map<uint32_t, const char*> ANDROID_ATTRS = {
248
+ // 核心属性 0x01010000 - 0x010100ff
249
+ {0x01010000, "theme"},
250
+ {0x01010001, "label"},
251
+ {0x01010002, "icon"},
252
+ {0x01010003, "name"},
253
+ {0x01010004, "manageSpaceActivity"},
254
+ {0x01010005, "allowClearUserData"},
255
+ {0x01010006, "permission"},
256
+ {0x01010007, "readPermission"},
257
+ {0x01010008, "writePermission"},
258
+ {0x01010009, "protectionLevel"},
259
+ {0x0101000a, "permissionGroup"},
260
+ {0x0101000b, "sharedUserId"},
261
+ {0x0101000c, "hasCode"},
262
+ {0x0101000d, "persistent"},
263
+ {0x0101000e, "enabled"},
264
+ {0x0101000f, "debuggable"},
265
+ {0x01010010, "exported"},
266
+ {0x01010011, "process"},
267
+ {0x01010012, "taskAffinity"},
268
+ {0x01010013, "multiprocess"},
269
+ {0x01010014, "finishOnTaskLaunch"},
270
+ {0x01010015, "clearTaskOnLaunch"},
271
+ {0x01010016, "stateNotNeeded"},
272
+ {0x01010017, "excludeFromRecents"},
273
+ {0x01010018, "authorities"},
274
+ {0x01010019, "syncable"},
275
+ {0x0101001a, "initOrder"},
276
+ {0x0101001b, "grantUriPermissions"},
277
+ {0x0101001c, "priority"},
278
+ {0x0101001d, "launchMode"},
279
+ {0x0101001e, "screenOrientation"},
280
+ {0x0101001f, "configChanges"},
281
+ {0x01010020, "description"},
282
+ {0x01010021, "targetPackage"},
283
+ {0x01010022, "handleProfiling"},
284
+ {0x01010023, "functionalTest"},
285
+ {0x01010024, "value"},
286
+ {0x01010025, "resource"},
287
+ {0x01010026, "mimeType"},
288
+ {0x01010027, "scheme"},
289
+ {0x01010028, "host"},
290
+ {0x01010029, "port"},
291
+ {0x0101002a, "path"},
292
+ {0x0101002b, "pathPrefix"},
293
+ {0x0101002c, "pathPattern"},
294
+ {0x0101002d, "action"},
295
+ {0x0101002e, "data"},
296
+ {0x0101002f, "targetClass"},
297
+
298
+ // 视图属性
299
+ {0x010100d0, "id"},
300
+ {0x010100d1, "tag"},
301
+ {0x010100d2, "scrollX"},
302
+ {0x010100d3, "scrollY"},
303
+ {0x010100d4, "background"},
304
+ {0x010100d5, "padding"},
305
+ {0x010100d6, "paddingLeft"},
306
+ {0x010100d7, "paddingTop"},
307
+ {0x010100d8, "paddingRight"},
308
+ {0x010100d9, "paddingBottom"},
309
+ {0x010100da, "focusable"},
310
+ {0x010100db, "focusableInTouchMode"},
311
+ {0x010100dc, "visibility"},
312
+ {0x010100dd, "fitsSystemWindows"},
313
+ {0x010100de, "scrollbars"},
314
+ {0x010100df, "fadingEdge"},
315
+ {0x010100e0, "fadingEdgeLength"},
316
+ {0x010100e1, "nextFocusLeft"},
317
+ {0x010100e2, "nextFocusRight"},
318
+ {0x010100e3, "nextFocusUp"},
319
+ {0x010100e4, "nextFocusDown"},
320
+ {0x010100e5, "clickable"},
321
+ {0x010100e6, "longClickable"},
322
+ {0x010100e7, "saveEnabled"},
323
+ {0x010100e8, "drawingCacheQuality"},
324
+ {0x010100e9, "duplicateParentState"},
325
+
326
+ // 布局属性
327
+ {0x010100f4, "layout_width"},
328
+ {0x010100f5, "layout_height"},
329
+ {0x010100f6, "layout_margin"},
330
+ {0x010100f7, "layout_marginLeft"},
331
+ {0x010100f8, "layout_marginTop"},
332
+ {0x010100f9, "layout_marginRight"},
333
+ {0x010100fa, "layout_marginBottom"},
334
+
335
+ // 文本属性
336
+ {0x01010095, "textSize"},
337
+ {0x01010096, "typeface"},
338
+ {0x01010097, "textStyle"},
339
+ {0x01010098, "textColor"},
340
+ {0x01010099, "textColorHighlight"},
341
+ {0x0101009a, "textColorHint"},
342
+ {0x0101009b, "textColorLink"},
343
+
344
+ // gravity
345
+ {0x010100af, "gravity"},
346
+ {0x010100b3, "layout_gravity"},
347
+
348
+ // 方向
349
+ {0x010100c4, "orientation"},
350
+
351
+ // 更多文本属性
352
+ {0x0101014f, "text"},
353
+ {0x01010150, "hint"},
354
+
355
+ // 尺寸
356
+ {0x01010140, "minWidth"},
357
+ {0x01010141, "minHeight"},
358
+ {0x0101011f, "maxWidth"},
359
+ {0x01010120, "maxHeight"},
360
+
361
+ // SDK 版本
362
+ {0x0101020c, "minSdkVersion"},
363
+ {0x01010270, "targetSdkVersion"},
364
+ {0x01010271, "maxSdkVersion"},
365
+
366
+ // 版本信息
367
+ {0x0101021b, "versionCode"},
368
+ {0x0101021c, "versionName"},
369
+
370
+ // 应用属性
371
+ {0x01010224, "installLocation"},
372
+ {0x0101026c, "largeHeap"},
373
+ {0x0101028e, "hardwareAccelerated"},
374
+ {0x010102b7, "supportsRtl"},
375
+ {0x01010473, "extractNativeLibs"},
376
+ {0x010104d6, "usesCleartextTraffic"},
377
+
378
+ // Activity 属性
379
+ {0x0101022b, "windowSoftInputMode"},
380
+ {0x01010362, "parentActivityName"},
381
+
382
+ // Service 属性
383
+ {0x01010020, "foregroundServiceType"},
384
+
385
+ // 权限相关
386
+ {0x01010003, "name"},
387
+
388
+ // 更多属性可以按需添加...
389
+ };
390
+
391
+ auto it = ANDROID_ATTRS.find(res_id);
392
+ if (it != ANDROID_ATTRS.end()) {
393
+ return it->second;
394
+ }
395
+ return nullptr;
396
+ }
397
+
398
+ // 反向查找:属性名 -> 资源 ID
399
+ inline uint32_t get_android_attr_id(const std::string& name) {
400
+ static const std::unordered_map<std::string, uint32_t> NAME_TO_ID = {
401
+ {"theme", 0x01010000},
402
+ {"label", 0x01010001},
403
+ {"icon", 0x01010002},
404
+ {"name", 0x01010003},
405
+ {"permission", 0x01010006},
406
+ {"readPermission", 0x01010007},
407
+ {"writePermission", 0x01010008},
408
+ {"protectionLevel", 0x01010009},
409
+ {"sharedUserId", 0x0101000b},
410
+ {"hasCode", 0x0101000c},
411
+ {"persistent", 0x0101000d},
412
+ {"enabled", 0x0101000e},
413
+ {"debuggable", 0x0101000f},
414
+ {"exported", 0x01010010},
415
+ {"process", 0x01010011},
416
+ {"taskAffinity", 0x01010012},
417
+ {"launchMode", 0x0101001d},
418
+ {"screenOrientation", 0x0101001e},
419
+ {"configChanges", 0x0101001f},
420
+ {"description", 0x01010020},
421
+ {"value", 0x01010024},
422
+ {"resource", 0x01010025},
423
+ {"mimeType", 0x01010026},
424
+ {"scheme", 0x01010027},
425
+ {"host", 0x01010028},
426
+ {"port", 0x01010029},
427
+ {"path", 0x0101002a},
428
+ {"pathPrefix", 0x0101002b},
429
+ {"pathPattern", 0x0101002c},
430
+ {"action", 0x0101002d},
431
+ {"data", 0x0101002e},
432
+
433
+ {"id", 0x010100d0},
434
+ {"tag", 0x010100d1},
435
+ {"background", 0x010100d4},
436
+ {"padding", 0x010100d5},
437
+ {"paddingLeft", 0x010100d6},
438
+ {"paddingTop", 0x010100d7},
439
+ {"paddingRight", 0x010100d8},
440
+ {"paddingBottom", 0x010100d9},
441
+ {"focusable", 0x010100da},
442
+ {"visibility", 0x010100dc},
443
+ {"clickable", 0x010100e5},
444
+
445
+ {"layout_width", 0x010100f4},
446
+ {"layout_height", 0x010100f5},
447
+ {"layout_margin", 0x010100f6},
448
+ {"layout_marginLeft", 0x010100f7},
449
+ {"layout_marginTop", 0x010100f8},
450
+ {"layout_marginRight", 0x010100f9},
451
+ {"layout_marginBottom", 0x010100fa},
452
+
453
+ {"textSize", 0x01010095},
454
+ {"typeface", 0x01010096},
455
+ {"textStyle", 0x01010097},
456
+ {"textColor", 0x01010098},
457
+
458
+ {"gravity", 0x010100af},
459
+ {"layout_gravity", 0x010100b3},
460
+ {"orientation", 0x010100c4},
461
+
462
+ {"text", 0x0101014f},
463
+ {"hint", 0x01010150},
464
+
465
+ {"minWidth", 0x01010140},
466
+ {"minHeight", 0x01010141},
467
+ {"maxWidth", 0x0101011f},
468
+ {"maxHeight", 0x01010120},
469
+
470
+ {"minSdkVersion", 0x0101020c},
471
+ {"targetSdkVersion", 0x01010270},
472
+ {"maxSdkVersion", 0x01010271},
473
+
474
+ {"versionCode", 0x0101021b},
475
+ {"versionName", 0x0101021c},
476
+
477
+ {"installLocation", 0x01010224},
478
+ {"largeHeap", 0x0101026c},
479
+ {"hardwareAccelerated", 0x0101028e},
480
+ {"supportsRtl", 0x010102b7},
481
+ {"extractNativeLibs", 0x01010473},
482
+ {"usesCleartextTraffic", 0x010104d6},
483
+
484
+ {"windowSoftInputMode", 0x0101022b},
485
+ {"parentActivityName", 0x01010362},
486
+ };
487
+
488
+ auto it = NAME_TO_ID.find(name);
489
+ if (it != NAME_TO_ID.end()) {
490
+ return it->second;
491
+ }
492
+ return 0;
493
+ }
494
+
495
+ } // namespace axml
@@ -0,0 +1,147 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+ #include <vector>
5
+ #include <cstdint>
6
+ #include <map>
7
+ #include "android_resources.h"
8
+
9
+ namespace axml {
10
+
11
+ struct Attribute {
12
+ std::string namespace_uri;
13
+ std::string name;
14
+ std::string value;
15
+ uint32_t type;
16
+ uint32_t data;
17
+ };
18
+
19
+ struct Element {
20
+ std::string namespace_uri;
21
+ std::string name;
22
+ std::vector<Attribute> attributes;
23
+ std::vector<Element> children;
24
+ std::string text;
25
+ };
26
+
27
+ class AxmlParser {
28
+ public:
29
+ AxmlParser() = default;
30
+ ~AxmlParser() = default;
31
+
32
+ bool parse(const std::vector<uint8_t>& data);
33
+
34
+ const Element& root() const { return root_; }
35
+ std::string to_xml(int indent = 0) const;
36
+
37
+ std::string get_package_name() const;
38
+ std::string get_version_name() const;
39
+ int get_version_code() const;
40
+ std::string get_min_sdk() const;
41
+ std::string get_target_sdk() const;
42
+ std::vector<std::string> get_permissions() const;
43
+ std::vector<std::string> get_activities() const;
44
+ std::vector<std::string> get_services() const;
45
+ std::vector<std::string> get_receivers() const;
46
+
47
+ std::string get_info() const;
48
+
49
+ private:
50
+ std::vector<uint8_t> data_;
51
+ std::vector<std::string> string_pool_;
52
+ Element root_;
53
+
54
+ bool parse_string_pool(size_t& offset);
55
+ bool parse_resource_map(size_t& offset);
56
+ bool parse_elements(size_t& offset);
57
+
58
+ std::string element_to_xml(const Element& elem, int indent) const;
59
+ std::string get_attribute_value(const Element& elem, const std::string& name) const;
60
+ };
61
+
62
+ struct ResourceValue {
63
+ uint8_t type;
64
+ uint32_t data;
65
+ std::string string_value;
66
+ };
67
+
68
+ struct SearchResult {
69
+ std::string element_path;
70
+ std::string element_name;
71
+ std::string attribute_name;
72
+ std::string attribute_value;
73
+ int element_index;
74
+ };
75
+
76
+ class AxmlEditor {
77
+ public:
78
+ AxmlEditor() = default;
79
+ ~AxmlEditor() = default;
80
+
81
+ bool load(const std::vector<uint8_t>& data);
82
+ std::vector<uint8_t> save();
83
+ bool is_loaded() const { return !data_.empty(); }
84
+
85
+ bool set_package_name(const std::string& name);
86
+ bool set_version_name(const std::string& name);
87
+ bool set_version_code(int code);
88
+ bool set_min_sdk(int sdk);
89
+ bool set_target_sdk(int sdk);
90
+
91
+ // Permission management
92
+ bool add_permission(const std::string& permission);
93
+ bool remove_permission(const std::string& permission);
94
+
95
+ // Activity management
96
+ bool add_activity(const std::string& activity_name, bool exported = false);
97
+ bool remove_activity(const std::string& activity_name);
98
+
99
+ // Generic element management
100
+ bool add_element(const std::string& parent_path, const std::string& element_name,
101
+ const std::vector<std::pair<std::string, std::string>>& attributes);
102
+ bool remove_element(const std::string& element_path);
103
+
104
+ std::vector<SearchResult> search_by_attribute(const std::string& attr_name, const std::string& value_pattern) const;
105
+ std::vector<SearchResult> search_by_element(const std::string& element_name) const;
106
+ std::vector<SearchResult> search_by_value(const std::string& value_pattern) const;
107
+
108
+ bool set_attribute(const std::string& element_path, const std::string& attr_name, const std::string& new_value);
109
+ bool set_attribute_by_index(int element_index, const std::string& attr_name, const std::string& new_value);
110
+
111
+ const Element& root() const { return root_; }
112
+ const std::vector<std::string>& string_pool() const { return string_pool_; }
113
+
114
+ private:
115
+ std::vector<uint8_t> data_;
116
+ std::vector<std::string> string_pool_;
117
+ Element root_;
118
+ std::vector<uint32_t> resource_ids_;
119
+
120
+ struct ChunkInfo {
121
+ size_t string_pool_offset;
122
+ size_t string_pool_size;
123
+ size_t resource_map_offset;
124
+ size_t resource_map_size;
125
+ size_t xml_content_offset;
126
+ };
127
+ ChunkInfo chunk_info_;
128
+
129
+ bool parse_internal();
130
+ int find_or_add_string(const std::string& str);
131
+ bool rebuild_binary();
132
+ void search_element(const Element& elem, const std::string& path, int& index,
133
+ const std::string& attr_name, const std::string& value_pattern,
134
+ std::vector<SearchResult>& results) const;
135
+
136
+ // Helper methods for element manipulation
137
+ std::vector<uint8_t> create_start_element(const std::string& name,
138
+ const std::vector<std::pair<std::string, std::string>>& attrs,
139
+ uint32_t line_number = 1);
140
+ std::vector<uint8_t> create_end_element(const std::string& name, uint32_t line_number = 1);
141
+ bool insert_element_after(size_t offset, const std::vector<uint8_t>& element_data);
142
+ bool remove_element_at(size_t start_offset, size_t end_offset);
143
+ size_t find_element_end(size_t start_offset);
144
+ size_t find_parent_element_end(const std::string& parent_name);
145
+ };
146
+
147
+ } // namespace axml