capacitor-dex-editor 0.0.18 → 0.0.20
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.
|
@@ -44,7 +44,7 @@ public class DexEditorPluginPlugin extends Plugin {
|
|
|
44
44
|
Log.d(TAG, "Executing action: " + action);
|
|
45
45
|
|
|
46
46
|
// 在后台线程执行,避免阻塞UI
|
|
47
|
-
|
|
47
|
+
new Thread(() -> {
|
|
48
48
|
try {
|
|
49
49
|
JSObject result = dispatchAction(action, params);
|
|
50
50
|
call.resolve(result);
|
|
@@ -55,7 +55,7 @@ public class DexEditorPluginPlugin extends Plugin {
|
|
|
55
55
|
error.put("error", e.getMessage());
|
|
56
56
|
call.resolve(error);
|
|
57
57
|
}
|
|
58
|
-
});
|
|
58
|
+
}).start();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -1736,67 +1736,71 @@ public class DexManager {
|
|
|
1736
1736
|
|
|
1737
1737
|
Log.d(TAG, "Merged DEX written to: " + mergedDexFile.getAbsolutePath());
|
|
1738
1738
|
|
|
1739
|
-
|
|
1740
|
-
|
|
1739
|
+
zipFile.close();
|
|
1740
|
+
|
|
1741
|
+
// 2. 直接替换 APK 中的 DEX(MT 管理器的方式)
|
|
1742
|
+
// 使用 ZipOutputStream 重新写入 APK,只替换 DEX 部分
|
|
1743
|
+
java.io.File apkFile = new java.io.File(apkPath);
|
|
1744
|
+
java.io.File tempApkFile = new java.io.File(apkPath + ".tmp");
|
|
1745
|
+
|
|
1746
|
+
Log.d(TAG, "Replacing DEX in APK...");
|
|
1747
|
+
|
|
1748
|
+
java.util.zip.ZipFile originalZip = new java.util.zip.ZipFile(apkFile);
|
|
1741
1749
|
java.util.zip.ZipOutputStream zos = new java.util.zip.ZipOutputStream(
|
|
1742
|
-
new java.io.FileOutputStream(
|
|
1750
|
+
new java.io.BufferedOutputStream(new java.io.FileOutputStream(tempApkFile)));
|
|
1743
1751
|
|
|
1744
|
-
//
|
|
1745
|
-
|
|
1752
|
+
// 设置不压缩,加快速度
|
|
1753
|
+
zos.setMethod(java.util.zip.ZipOutputStream.STORED);
|
|
1754
|
+
|
|
1755
|
+
java.util.Enumeration<? extends java.util.zip.ZipEntry> entries = originalZip.entries();
|
|
1746
1756
|
while (entries.hasMoreElements()) {
|
|
1747
1757
|
java.util.zip.ZipEntry entry = entries.nextElement();
|
|
1748
|
-
if (entry.getName().equals(dexPath)) {
|
|
1749
|
-
// 跳过原 DEX,稍后添加新的
|
|
1750
|
-
continue;
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
// 复制其他条目
|
|
1754
|
-
java.util.zip.ZipEntry newEntry = new java.util.zip.ZipEntry(entry.getName());
|
|
1755
|
-
zos.putNextEntry(newEntry);
|
|
1756
1758
|
|
|
1757
|
-
if (
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1759
|
+
if (entry.getName().equals(dexPath)) {
|
|
1760
|
+
// 替换 DEX 文件
|
|
1761
|
+
byte[] dexBytes = readFileBytes(mergedDexFile);
|
|
1762
|
+
java.util.zip.ZipEntry newEntry = new java.util.zip.ZipEntry(dexPath);
|
|
1763
|
+
newEntry.setMethod(java.util.zip.ZipEntry.STORED);
|
|
1764
|
+
newEntry.setSize(dexBytes.length);
|
|
1765
|
+
newEntry.setCompressedSize(dexBytes.length);
|
|
1766
|
+
newEntry.setCrc(calculateCrc32(dexBytes));
|
|
1767
|
+
zos.putNextEntry(newEntry);
|
|
1768
|
+
zos.write(dexBytes);
|
|
1769
|
+
zos.closeEntry();
|
|
1770
|
+
} else {
|
|
1771
|
+
// 复制原条目(保持原压缩方式)
|
|
1772
|
+
java.util.zip.ZipEntry newEntry = new java.util.zip.ZipEntry(entry);
|
|
1773
|
+
zos.putNextEntry(newEntry);
|
|
1774
|
+
if (!entry.isDirectory()) {
|
|
1775
|
+
java.io.InputStream is = originalZip.getInputStream(entry);
|
|
1776
|
+
byte[] buf = new byte[8192];
|
|
1777
|
+
int len;
|
|
1778
|
+
while ((len = is.read(buf)) != -1) {
|
|
1779
|
+
zos.write(buf, 0, len);
|
|
1780
|
+
}
|
|
1781
|
+
is.close();
|
|
1761
1782
|
}
|
|
1762
|
-
|
|
1783
|
+
zos.closeEntry();
|
|
1763
1784
|
}
|
|
1764
|
-
zos.closeEntry();
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
// 添加修改后的 DEX
|
|
1768
|
-
java.util.zip.ZipEntry newDexEntry = new java.util.zip.ZipEntry(dexPath);
|
|
1769
|
-
zos.putNextEntry(newDexEntry);
|
|
1770
|
-
java.io.FileInputStream fis = new java.io.FileInputStream(mergedDexFile);
|
|
1771
|
-
while ((len = fis.read(buffer)) != -1) {
|
|
1772
|
-
zos.write(buffer, 0, len);
|
|
1773
1785
|
}
|
|
1774
|
-
fis.close();
|
|
1775
|
-
zos.closeEntry();
|
|
1776
1786
|
|
|
1777
1787
|
zos.close();
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
Log.d(TAG, "Modified APK written to: " + outputApk.getAbsolutePath());
|
|
1781
|
-
|
|
1782
|
-
// 3. 替换原 APK(先备份)
|
|
1783
|
-
java.io.File backupApk = new java.io.File(apkPath + ".backup");
|
|
1784
|
-
java.io.File originalApkFile = new java.io.File(apkPath);
|
|
1785
|
-
|
|
1786
|
-
// 复制原 APK 作为备份
|
|
1787
|
-
copyFile(originalApkFile, backupApk);
|
|
1788
|
+
originalZip.close();
|
|
1788
1789
|
|
|
1789
|
-
//
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1790
|
+
// 用临时文件替换原文件
|
|
1791
|
+
if (!apkFile.delete()) {
|
|
1792
|
+
Log.e(TAG, "Failed to delete original APK");
|
|
1793
|
+
}
|
|
1794
|
+
if (!tempApkFile.renameTo(apkFile)) {
|
|
1795
|
+
// 如果 rename 失败,尝试复制
|
|
1796
|
+
copyFile(tempApkFile, apkFile);
|
|
1797
|
+
tempApkFile.delete();
|
|
1798
|
+
}
|
|
1794
1799
|
|
|
1795
|
-
Log.d(TAG, "APK updated successfully
|
|
1800
|
+
Log.d(TAG, "APK updated successfully: " + apkPath);
|
|
1796
1801
|
|
|
1797
1802
|
result.put("success", true);
|
|
1798
|
-
result.put("message", "Smali
|
|
1799
|
-
result.put("backupPath", backupApk.getAbsolutePath());
|
|
1803
|
+
result.put("message", "Smali 保存成功!APK 已更新");
|
|
1800
1804
|
|
|
1801
1805
|
// 清理临时文件
|
|
1802
1806
|
cleanupTempDir(tempDir);
|
|
@@ -1810,6 +1814,30 @@ public class DexManager {
|
|
|
1810
1814
|
return result;
|
|
1811
1815
|
}
|
|
1812
1816
|
|
|
1817
|
+
/**
|
|
1818
|
+
* 读取文件为字节数组
|
|
1819
|
+
*/
|
|
1820
|
+
private byte[] readFileBytes(java.io.File file) throws java.io.IOException {
|
|
1821
|
+
java.io.FileInputStream fis = new java.io.FileInputStream(file);
|
|
1822
|
+
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
|
1823
|
+
byte[] buffer = new byte[8192];
|
|
1824
|
+
int len;
|
|
1825
|
+
while ((len = fis.read(buffer)) != -1) {
|
|
1826
|
+
baos.write(buffer, 0, len);
|
|
1827
|
+
}
|
|
1828
|
+
fis.close();
|
|
1829
|
+
return baos.toByteArray();
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
/**
|
|
1833
|
+
* 计算 CRC32
|
|
1834
|
+
*/
|
|
1835
|
+
private long calculateCrc32(byte[] data) {
|
|
1836
|
+
java.util.zip.CRC32 crc = new java.util.zip.CRC32();
|
|
1837
|
+
crc.update(data);
|
|
1838
|
+
return crc.getValue();
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1813
1841
|
/**
|
|
1814
1842
|
* 复制文件
|
|
1815
1843
|
*/
|