Skip to content

Commit f5ea13f

Browse files
committed
shm mappings
1 parent 364978a commit f5ea13f

File tree

4 files changed

+231
-95
lines changed

4 files changed

+231
-95
lines changed

Android.mk

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,29 @@ LOCAL_SHARED_LIBRARIES :=
6060

6161
include $(BUILD_EXECUTABLE)
6262

63+
####################################################################################################
64+
65+
####################################################################################################
66+
#include $(CLEAR_VARS)
67+
68+
LOCAL_MODULE := test_ashmem
69+
70+
LOCAL_MODULE_FILENAME := test_ashmem
71+
72+
cmd-strip = $(TOOLCHAIN_PREFIX)strip --strip-unneeded -x $1
73+
74+
LOCAL_SRC_FILES := unittest/test_ashmem.cpp
75+
76+
LOCAL_CFLAGS := -g -O0 -fvisibility=hidden -pie -fPIE
77+
LOCAL_CPPFLAGS := -g -O0 -std=c++11 -fvisibility=hidden -pie -fPIE
78+
79+
LOCAL_LDFLAGS += -pie -fPIE
80+
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI)
81+
82+
LOCAL_C_INCLUDES += system/core/include/cutils
83+
84+
LOCAL_SHARED_LIBRARIES :=
85+
86+
include $(BUILD_EXECUTABLE)
87+
6388
####################################################################################################

bootstrap.cpp

Lines changed: 7 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,13 @@ static int my_stat(const char *path, struct stat *file_stat)
486486

487487
static ShadowZip* get_cached_shadowzip(FILE *stream)
488488
{
489-
FileExtraData* file_extra_data = get_file_mapping(stream);
489+
FileExtraData* file_extra_data = get_mapping(stream);
490490
return file_extra_data == NULL ? NULL : file_extra_data->shadow_zip;
491491
}
492492

493493
static ShadowZip* get_cached_shadowzip(int fd)
494494
{
495-
FileExtraData* file_extra_data = get_file_mapping(fd);
495+
FileExtraData* file_extra_data = get_mapping(fd);
496496
return file_extra_data == NULL ? NULL : file_extra_data->shadow_zip;
497497
}
498498

@@ -519,7 +519,7 @@ static FILE *my_fopen(const char *path, const char *mode)
519519
return fopen(path, mode);
520520
}
521521

522-
FileExtraData* file_extra_data = save_file_mapping(shadow_zip);
522+
FileExtraData* file_extra_data = save_mapping(shadow_zip);
523523
MY_LOG("shadow apk in fopen: %s, fd:0x%08x, file*: 0x%08llx", path, file_extra_data->fd, (unsigned long long)file_extra_data->file);
524524
return file_extra_data->file;
525525
}
@@ -594,7 +594,7 @@ static int my_fclose(FILE* stream)
594594
{
595595
MY_METHOD("my_fclose: file*: 0x%08llx", (unsigned long long)stream);
596596

597-
FileExtraData* file_extra_data = get_file_mapping(stream);
597+
FileExtraData* file_extra_data = get_mapping(stream);
598598
if (file_extra_data != NULL)
599599
{
600600
clean_mapping_data(file_extra_data);
@@ -655,7 +655,7 @@ static int my_open(const char *path, int flags, ...)
655655
return ret;
656656
}
657657

658-
FileExtraData* file_extra_data = save_file_mapping(shadow_zip);
658+
FileExtraData* file_extra_data = save_mapping(shadow_zip);
659659
MY_LOG("shadow apk in open: %s, fd:0x%08x, file*: 0x%08llx", path, file_extra_data->fd, (unsigned long long)file_extra_data->file);
660660
return file_extra_data->fd;
661661
}
@@ -721,7 +721,7 @@ static int my_close(int fd)
721721
{
722722
MY_METHOD("my_close: 0x%08x", fd);
723723

724-
FileExtraData* file_extra_data = get_file_mapping(fd);
724+
FileExtraData* file_extra_data = get_mapping(fd);
725725
if (file_extra_data != NULL)
726726
{
727727
clean_mapping_data(file_extra_data);
@@ -735,71 +735,6 @@ static int my_close(int fd)
735735

736736
static int init_hook()
737737
{
738-
/*
739-
char path[512] = {0};
740-
snprintf((char*)path, sizeof(path), "libunity.so");
741-
void const* addr = get_module_base(path, sizeof(path)-1);
742-
MY_INFO("libunity addr:0x%zx, path:%s", (size_t)addr, path);
743-
if (addr == NULL){
744-
MY_ERROR("failed to load libunity info");
745-
return -1;
746-
}
747-
748-
void *handle = dlopen(path, RTLD_LAZY);
749-
if (!handle) {
750-
MY_ERROR("failed to load libunity:%s, error:%s", path, dlerror());
751-
return -1;
752-
}
753-
754-
std::vector<const char*> symbol_names;
755-
symbol_names.push_back("fopen");
756-
symbol_names.push_back("fseek");
757-
symbol_names.push_back("ftell");
758-
symbol_names.push_back("fread");
759-
symbol_names.push_back("fgets");
760-
symbol_names.push_back("fclose");
761-
symbol_names.push_back("stat");
762-
symbol_names.push_back("dlopen");
763-
symbol_names.push_back("open");
764-
symbol_names.push_back("read");
765-
symbol_names.push_back("lseek");
766-
symbol_names.push_back("lseek64");
767-
symbol_names.push_back("close");
768-
769-
std::vector<void const *> new_func;
770-
new_func.push_back((void const *)my_fopen);
771-
new_func.push_back((void const *)my_fseek);
772-
new_func.push_back((void const *)my_ftell);
773-
new_func.push_back((void const *)my_fread);
774-
new_func.push_back((void const *)my_fgets);
775-
new_func.push_back((void const *)my_fclose);
776-
new_func.push_back((void const *)my_stat);
777-
new_func.push_back((void const *)my_dlopen);
778-
new_func.push_back((void const *)my_open);
779-
new_func.push_back((void const *)my_read);
780-
new_func.push_back((void const *)my_lseek);
781-
new_func.push_back((void const *)my_lseek64);
782-
new_func.push_back((void const *)my_close);
783-
784-
std::vector<void **> old_func;
785-
old_func.push_back((void**)&old_fopen);
786-
old_func.push_back((void**)&old_fseek);
787-
old_func.push_back((void**)&old_ftell);
788-
old_func.push_back((void**)&old_fread);
789-
old_func.push_back((void**)&old_fgets);
790-
old_func.push_back((void**)&old_fclose);
791-
old_func.push_back((void**)&old_stat);
792-
old_func.push_back((void**)&old_dlopen);
793-
old_func.push_back((void**)&old_open);
794-
old_func.push_back((void**)&old_read);
795-
old_func.push_back((void**)&old_lseek);
796-
old_func.push_back((void**)&old_lseek64);
797-
old_func.push_back((void**)&old_close);
798-
799-
elf_hook(path, addr, symbol_names, new_func, old_func);
800-
801-
//dlclose(handle);
802-
*/
803738
#define HOOK(lib, symbol) \
804739
if(0 != xhook_register(lib, #symbol, (void*)my_##symbol, NULL)){ \
805740
MY_ERROR("failed to find function:%s in %s", #symbol, lib); \
@@ -873,7 +808,7 @@ static void bootstrap()
873808
MY_INFO("bootstrap running %s with apk_path:[%s], patch_so:[%s], patch_dir:[%s]", TARGET_ARCH_ABI,
874809
g_apk_file_path, patch_il2cpp_path.c_str(), g_use_data_path);
875810

876-
bool success = (0 == init_hook()) && (0 == init_file_mapping_data());
811+
bool success = (0 == init_hook()) && (0 == init_mapping_data());
877812
if (success)
878813
{
879814
MY_INFO("bootstrap running with patch:%s", patch_il2cpp_path.c_str());

file_mapping.h

Lines changed: 125 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <dirent.h>
99
#include <errno.h>
1010
#include "log.h"
11+
#include <linux/ashmem.h>
12+
#include <sys/mman.h>
1113

1214
#include <vector>
1315
#include <string>
@@ -21,20 +23,40 @@ struct FileExtraData
2123
FileExtraData* self;
2224
ShadowZip* shadow_zip;
2325
FILE* file;
26+
char* mmap_buffer;
2427
int fd;
2528
};
29+
bool use_shared_mem = false;
30+
static dev_t g_shm_device_id = -1;
31+
static ino_t g_shm_ino = -1;
2632

2733
// posix shm is not supported on Android.
2834
// we should use memfd, but it is not supported in older android(platform api < 26)
2935
// https://developer.android.google.cn/ndk/reference/group/memory.html
3036
// file fd is slow theoratically, but it is ok on a flash disk and I don't notice it.
3137
// no other choice, as the mutex is buggy in fclose with timing irq.
3238

33-
static int init_file_mapping_data()
39+
static int init_mapping_data()
3440
{
41+
FILE* file = ::fopen("/dev/ashmem", "r+");
42+
if (file != NULL){
43+
int fd = fileno(file);
44+
struct stat shm_stat;
45+
memset(&shm_stat, 0, sizeof(struct stat));
46+
if (fstat(fd, &shm_stat) == 0) {
47+
::fclose(file);
48+
g_shm_device_id = shm_stat.st_dev;
49+
g_shm_ino = shm_stat.st_ino;
50+
use_shared_mem = true;
51+
MY_METHOD("shmem mapping is enabled. dev:%lu:%lu", (unsigned long)g_shm_device_id, (unsigned long)g_shm_ino);
52+
return 0;
53+
}
54+
::fclose(file);
55+
}
56+
3557
char fds_dir[512] = {0};
3658
snprintf(fds_dir, sizeof(fds_dir), "%s/rt_fd_mappings", g_use_data_path);
37-
MY_INFO("init_file_mapping_data %s with apk_path:%s", TARGET_ARCH_ABI, fds_dir);
59+
MY_METHOD("init_mapping_data %s with apk_path:%s", TARGET_ARCH_ABI, fds_dir);
3860

3961
//create dir if not exist
4062
DIR* dir = opendir(fds_dir);
@@ -81,13 +103,36 @@ static int init_file_mapping_data()
81103
return 0;
82104
}
83105

84-
static FileExtraData* save_file_mapping(ShadowZip* shadow_zip)
85-
{
86-
FileExtraData* file_extra_data = new FileExtraData();
87-
file_extra_data->magic_num = MY_MAGIC_NUM;
88-
file_extra_data->self = file_extra_data;
89-
file_extra_data->shadow_zip = shadow_zip;
106+
static void save_mem_mapping(FileExtraData* file_extra_data){
107+
file_extra_data->file = ::fopen("/dev/ashmem", "r+");
108+
if (file_extra_data->file == NULL)
109+
{
110+
MY_ERROR("open /dev/ashmem failed! errno:%d", errno);
111+
_exit(-1);
112+
}
113+
int fd = fileno(file_extra_data->file);
114+
file_extra_data->fd = fd;
115+
116+
char name[256] = {0};
117+
snprintf(name, sizeof(name), "%08llx_%d", (unsigned long long)file_extra_data->file, file_extra_data->fd);
118+
ioctl(fd, ASHMEM_SET_NAME, name);
119+
ioctl(fd, ASHMEM_SET_SIZE, sizeof(FileExtraData));
120+
121+
char* buff = (char*)mmap(NULL, sizeof(FileExtraData), PROT_READ | PROT_WRITE, MAP_SHARED, file_extra_data->fd, 0);
122+
if(buff == MAP_FAILED)
123+
{
124+
MY_ERROR("mmap /dev/ashmem failed! errno:%d", errno);
125+
_exit(-1);
126+
}
127+
128+
file_extra_data->mmap_buffer = buff;
129+
memcpy(buff, file_extra_data, sizeof(FileExtraData));
90130

131+
msync(buff, sizeof(FileExtraData), MS_SYNC);
132+
MY_METHOD("FileExtraData saved to mem:0x%08llx. fd:0x%08x, file*: 0x%08llx", (unsigned long long)buff, file_extra_data->fd, (unsigned long long)file_extra_data->file);
133+
}
134+
135+
static void save_file_mapping(FileExtraData* file_extra_data){
91136
char save_path[512] = {0};
92137
snprintf(save_path, sizeof(save_path), "%s/rt_fd_mappings/%08llx", g_use_data_path, (unsigned long long)file_extra_data);
93138
file_extra_data->file = ::fopen(save_path, "wb+");
@@ -103,54 +148,111 @@ static FileExtraData* save_file_mapping(ShadowZip* shadow_zip)
103148
fseek(file_extra_data->file, 0, SEEK_SET);
104149

105150
MY_METHOD("FileExtraData saved to %s. fd:0x%08x, file*: 0x%08llx", save_path, file_extra_data->fd, (unsigned long long)file_extra_data->file);
151+
}
152+
153+
static FileExtraData* save_mapping(ShadowZip* shadow_zip)
154+
{
155+
FileExtraData* file_extra_data = new FileExtraData();
156+
file_extra_data->magic_num = MY_MAGIC_NUM;
157+
file_extra_data->self = file_extra_data;
158+
file_extra_data->shadow_zip = shadow_zip;
159+
160+
if (use_shared_mem){
161+
save_mem_mapping(file_extra_data);
162+
}
163+
else{
164+
save_file_mapping(file_extra_data);
165+
}
166+
106167
return file_extra_data;
107168
}
108169

109-
static FileExtraData* get_file_mapping(int fd)
170+
static FileExtraData* get_mem_mapping(int fd)
110171
{
111-
off_t pos = lseek(fd, 0, SEEK_CUR);
112-
if (pos != 0){return NULL;}
172+
struct stat shm_stat;
173+
memset(&shm_stat, 0, sizeof(struct stat));
174+
if (fstat(fd, &shm_stat) != 0) {
175+
return NULL;
176+
}
177+
if (g_shm_device_id != shm_stat.st_dev || g_shm_ino != shm_stat.st_ino){
178+
return NULL;
179+
}
180+
181+
char* buff = (char*)mmap(NULL, sizeof(FileExtraData), PROT_READ, MAP_SHARED, fd, 0);
182+
if(buff == MAP_FAILED) { return NULL; }
183+
if(*((uint64_t*)buff) != MY_MAGIC_NUM){
184+
munmap(buff, sizeof(FileExtraData));
185+
return NULL;
186+
}
113187

114-
lseek(fd, 0, SEEK_SET);
115188
FileExtraData file_extra_data_copy;
116-
int read_cnt = read(fd, (void*)&file_extra_data_copy, sizeof(FileExtraData));
117-
lseek(fd, 0, SEEK_SET);
189+
memcpy(&file_extra_data_copy, buff, sizeof(FileExtraData));
190+
munmap(buff, sizeof(FileExtraData));
118191

119192
//validate
120-
if (read_cnt != sizeof(FileExtraData)){ return NULL; }
121193
if (file_extra_data_copy.magic_num != MY_MAGIC_NUM) { return NULL; }
122194
if (file_extra_data_copy.fd != fd) { return NULL; }
123195

124196
return file_extra_data_copy.self;
125197
}
126198

127-
static FileExtraData* get_file_mapping(FILE* file)
199+
static FileExtraData* get_file_mapping(int fd)
128200
{
129-
off_t pos = ftell(file);
201+
off_t pos = lseek(fd, 0, SEEK_CUR);
130202
if (pos != 0){return NULL;}
131203

132-
fseek(file, 0, SEEK_SET);
204+
lseek(fd, 0, SEEK_SET);
133205
FileExtraData file_extra_data_copy;
134-
int read_cnt = fread((void*)&file_extra_data_copy, 1, sizeof(FileExtraData), file);
135-
fseek(file, 0, SEEK_SET);
206+
int read_cnt = read(fd, (void*)&file_extra_data_copy, sizeof(FileExtraData));
207+
lseek(fd, 0, SEEK_SET);
136208

137209
//validate
138210
if (read_cnt != sizeof(FileExtraData)){ return NULL; }
139211
if (file_extra_data_copy.magic_num != MY_MAGIC_NUM) { return NULL; }
140-
if (file_extra_data_copy.file != file) { return NULL; }
212+
if (file_extra_data_copy.fd != fd) { return NULL; }
141213

142214
return file_extra_data_copy.self;
143215
}
144216

145-
static void clean_mapping_data(FileExtraData* file_extra_data)
217+
static FileExtraData* get_mapping(int fd)
146218
{
219+
if (use_shared_mem){
220+
return get_mem_mapping(fd);
221+
}
222+
else{
223+
return get_file_mapping(fd);
224+
}
225+
}
226+
227+
static FileExtraData* get_mapping(FILE* file)
228+
{
229+
int fd = fileno(file);
230+
return get_mapping(fd);
231+
}
232+
233+
static void clean_mem_mapping_data(FileExtraData* file_extra_data){
234+
MY_METHOD("FileExtraData deleted mem: 0x%08llx. fd:0x%08x, file*: 0x%08llx", (unsigned long long)file_extra_data->mmap_buffer, file_extra_data->fd, (unsigned long long)file_extra_data->file);
235+
munmap(file_extra_data->mmap_buffer, sizeof(FileExtraData));
236+
}
237+
238+
static void clean_file_mapping_data(FileExtraData* file_extra_data){
147239
char save_path[512] = {0};
148240
snprintf(save_path, sizeof(save_path), "%s/rt_fd_mappings/%08llx", g_use_data_path, (unsigned long long)file_extra_data->self);
149241
unlink(save_path);
242+
MY_METHOD("FileExtraData deleted %s. fd:0x%08x, file*: 0x%08llx", save_path, file_extra_data->fd, (unsigned long long)file_extra_data->file);
243+
}
244+
245+
static void clean_mapping_data(FileExtraData* file_extra_data)
246+
{
247+
if (use_shared_mem){
248+
clean_mem_mapping_data(file_extra_data);
249+
}
250+
else{
251+
clean_file_mapping_data(file_extra_data);
252+
}
150253

151254
fclose(file_extra_data->file);
152255
delete file_extra_data->shadow_zip;
153-
MY_METHOD("FileExtraData deleted %s. fd:0x%08x, file*: 0x%08llx", save_path, file_extra_data->fd, (unsigned long long)file_extra_data->file);
154256

155257
delete file_extra_data->self;
156258
}

0 commit comments

Comments
 (0)