Skip to content

Commit 80b94dc

Browse files
committed
Add crc32 to prevent multiple dex extraction
1 parent ca90c69 commit 80b94dc

File tree

5 files changed

+145
-5
lines changed

5 files changed

+145
-5
lines changed

module/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ perl -0777 -i -pe 's/(forkAndSpecializePost[\W\w]+?{[\W\w]*?)}/$1 fingerprin
3131
perl -0777 -i -pe 's/(specializeAppProcessPre[\W\w]+?{[\W\w]+?)}/$1 fingerprintPre(env, appDataDir, niceName);\n}/' $MODULE_TEMPLATE/module/src/main/cpp/main.cpp
3232
perl -0777 -i -pe 's/(specializeAppProcessPost[\W\w]+?{[\W\w]+?)}/$1 fingerprintPost(env, MAGISK_MODULE_TYPE_RIRU);\n}/' $MODULE_TEMPLATE/module/src/main/cpp/main.cpp
3333
perl -0777 -i -pe 's/^/#include "fingerprint.h"\n/' $MODULE_TEMPLATE/module/src/main/cpp/main.cpp
34-
perl -i -pe 's/(main\.cpp)/$1 fingerprint.cpp zygisk_main.cpp resource_extractor.cpp/g' $MODULE_TEMPLATE/module/src/main/cpp/CMakeLists.txt
34+
perl -i -pe 's/(main\.cpp)/$1 fingerprint.cpp zygisk_main.cpp resource_extractor.cpp crc32.cpp/g' $MODULE_TEMPLATE/module/src/main/cpp/CMakeLists.txt
3535
$MODULE_TEMPLATE/gradlew -p $MODULE_TEMPLATE clean \
3636
-PVERSION_NAME=$VERSION_NAME \
3737
-PVERSION_CODE=$VERSION_CODE \

module/src/cpp/crc32.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <stdlib.h>
4+
#include "crc32.h"
5+
#include "log.h"
6+
7+
// 静态成员初始化
8+
uint32_t CRC32::crc32_table[256];
9+
bool CRC32::table_initialized = false;
10+
11+
// 初始化CRC32表
12+
void CRC32::initCRC32Table() {
13+
uint32_t c;
14+
for (int i = 0; i < 256; i++) {
15+
c = i;
16+
for (int j = 0; j < 8; j++) {
17+
c = (c & 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
18+
}
19+
crc32_table[i] = c;
20+
}
21+
table_initialized = true;
22+
}
23+
24+
// 获取文件大小,文件不存在返回-1
25+
size_t CRC32::getFileSize(const char* filename) {
26+
FILE* file = fopen(filename, "rb");
27+
if (!file) {
28+
LOGE("Failed to open file: %s", filename);
29+
return -1; // 文件不存在
30+
}
31+
32+
fseek(file, 0, SEEK_END);
33+
size_t size = ftell(file);
34+
fclose(file);
35+
36+
return size;
37+
}
38+
39+
// 计算文件的CRC32值
40+
uint32_t CRC32::calculateFileCRC32(const char* filename) {
41+
if (!table_initialized) {
42+
initCRC32Table();
43+
}
44+
45+
FILE* file = fopen(filename, "rb");
46+
if (!file) {
47+
LOGE("Failed to open file: %s", filename);
48+
return 0;
49+
}
50+
51+
const size_t buffer_size = 8192; // 8KB缓冲区
52+
unsigned char* buffer = (unsigned char*)malloc(buffer_size);
53+
if (!buffer) {
54+
LOGE("Failed to allocate memory for buffer");
55+
fclose(file);
56+
return 0;
57+
}
58+
59+
uint32_t crc = 0xFFFFFFFF;
60+
size_t bytes_read;
61+
62+
// 一次读取多个字节以提高性能
63+
while ((bytes_read = fread(buffer, 1, buffer_size, file)) > 0) {
64+
for (size_t i = 0; i < bytes_read; i++) {
65+
crc = crc32_table[(crc ^ buffer[i]) & 0xFF] ^ (crc >> 8);
66+
}
67+
}
68+
69+
free(buffer);
70+
fclose(file);
71+
return crc ^ 0xFFFFFFFF;
72+
}
73+
74+
// 验证文件CRC32是否匹配预期值
75+
bool CRC32::verifyFileCRC32(const char* filename, uint32_t expected_crc) {
76+
uint32_t actual_crc = calculateFileCRC32(filename);
77+
return (actual_crc == expected_crc);
78+
}
79+
80+
// 验证文件大小和CRC32是否匹配预期值
81+
bool CRC32::verifyFileSizeAndCRC32(const char* filename, size_t expected_size, uint32_t expected_crc) {
82+
// 首先检查文件大小
83+
size_t actual_size = getFileSize(filename);
84+
if (actual_size == -1) {
85+
LOGE("File does not exist: %s", filename);
86+
return false;
87+
}
88+
89+
if (actual_size != expected_size) {
90+
LOGE("File size mismatch. Expected: %zu, Actual: %zu", expected_size, actual_size);
91+
return false;
92+
}
93+
94+
// 如果大小匹配,再检查CRC32
95+
uint32_t actual_crc = calculateFileCRC32(filename);
96+
if (actual_crc != expected_crc) {
97+
LOGE("CRC32 mismatch. Expected: 0x%08X, Actual: 0x%08X", expected_crc, actual_crc);
98+
return false;
99+
}
100+
101+
LOGI("File verification passed: %s", filename);
102+
return true;
103+
}

module/src/cpp/crc32.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef CRC32_H
2+
#define CRC32_H
3+
4+
#include <stdint.h>
5+
6+
class CRC32 {
7+
public:
8+
// 获取文件大小,文件不存在返回-1
9+
static size_t getFileSize(const char* filename);
10+
11+
// 计算文件的CRC32值
12+
static uint32_t calculateFileCRC32(const char* filename);
13+
14+
// 验证文件CRC32是否匹配预期值
15+
static bool verifyFileCRC32(const char* filename, uint32_t expected_crc);
16+
17+
// 验证文件大小和CRC32是否匹配预期值
18+
static bool verifyFileSizeAndCRC32(const char* filename, size_t expected_size, uint32_t expected_crc);
19+
20+
private:
21+
// 初始化CRC32表
22+
static void initCRC32Table();
23+
24+
// CRC32表
25+
static uint32_t crc32_table[256];
26+
static bool table_initialized;
27+
};
28+
29+
#endif // CRC32_H

module/src/cpp/resource_extractor.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
#include <sys/stat.h>
55
#include <unistd.h>
66
#include "log.h"
7+
#include "crc32.h"
78

89
// 声明外部符号,这些符号是由objcopy工具生成的
910
extern "C" {
1011
// DEX资源的开始、结束地址和大小
1112
extern const uint8_t _binary_classes_dex_start[];
1213
extern const uint8_t _binary_classes_dex_end[];
13-
extern const size_t _binary_classes_dex_size;
14+
extern const size_t _binary_classes_dex_size; // BUG, size zero
1415
}
1516

1617
/**
@@ -20,11 +21,18 @@ extern "C" {
2021
* @return 是否成功提取
2122
*/
2223
extern "C" bool extractDexResource(const char* outputPath) {
23-
LOGI("Extracting DEX resource to: %s", outputPath);
24-
2524
// 计算资源大小
2625
size_t resourceSize = reinterpret_cast<size_t>(_binary_classes_dex_end) -
2726
reinterpret_cast<size_t>(_binary_classes_dex_start);
27+
// 验证文件大小和CRC32
28+
if (CRC32::verifyFileSizeAndCRC32(outputPath, resourceSize, RESOURCE_CRC32)) {
29+
LOGI("%s verification passed!", outputPath);
30+
return true;
31+
} else {
32+
LOGE("%s verification failed!", outputPath);
33+
}
34+
35+
LOGI("Extracting DEX resource to: %s", outputPath);
2836
if (access(outputPath, 0) == 0 && remove(outputPath) != 0) {
2937
LOGE("Error delete file %s reason: %s", outputPath, strerror(errno));
3038
return -1;

0 commit comments

Comments
 (0)