1.修改VA的lib目录下的IOUniformer.cpp文件
2.添加函数声明//保存文件 data:文件数据 data_len:文件长度 path:保存的位置
void saveFile(const char* data ,size_t data_len, const char* path);
//hook函数
int luaL_loadbuffer_mod (lua_State *L, const char *buff, size_t size,const char *name);
//原函数
int (*luaL_loadbuffer_orig)(lua_State *L, const char *buff, size_t size,const char *name);
//so加载的时候寻找 luaL_loadBuffer 符号并hook
void onSoLoaded(const char *name, void *handle);
//分割文件路径 path:文件路径 dirve:windows盘符 dir:目录 fname:文件名 ext:扩展名
void _splitpath( char *path, char *drive, char *dir, char *fname, char *ext);
static void _split_whole_name( char *whole_name, char *fname, char *ext);
3.具体代码如下
其中有一些变量和结构体为lua独有的,所以记得下载lua源码并放到和“IOUniformer.cpp”同一目录下并包含进去。
//当SO加载的时候进行HOOK
void onSoLoaded(const char *name, void *handle) {
//ALOGD("[dumplua] already found so name: %s",name);
if (strstr(name, "cocos2dlua")) {
ALOGD("[dumplua] found libcocos2dlua.so");
void *luaL_loadbuffer = dlsym(handle, "luaL_loadbuffer");
// ALOGD("[dumplua] luaL_loadbuffer found : %p",luaL_loadbuffer);
if (luaL_loadbuffer == NULL) {
ALOGD("[dumplua] luaL_loadbuffer not found!");
ALOGD("[dumplua] dlsym err: %s", dlerror());
} else {
ALOGD("[dumplua] luaL_loadBuffer found:%p", luaL_loadbuffer);
MSHookFunction(luaL_loadbuffer, (void *) &luaL_loadbuffer_mod,
(void **) &luaL_loadbuffer_orig);
}
}
}
/************** hook code *******************/
#define _MAX_DRIVE 3
#define _MAX_DIR 256
#define _MAX_FNAME 256
#define _MAX_EXT 256
//由于mkdir无法创建多级目录,所以此函数为创建多级目录使用
int createMultiLevelDir(char *sPathName) {
char DirName[256];
int i, len;
strcpy(DirName, sPathName);
len = strlen(DirName);
if ('/' != DirName[len - 1]) {
strcat(DirName, "/");
len++;
}
for (i = 1; i < len; i++) {
if ('/' == DirName[i]) {
DirName[i] = '\0';
if (access(DirName, F_OK) != 0) {
if (mkdir(DirName, 0777) == -1) {
ALOGD("[dumpulua] mkdir() failed!");
return -1;
}
}
DirName[i] = '/';
}
}
return 0;
}
//保存LUA文件到Sdcard
void saveFile(const char *data, size_t data_len, const char *path) {
FILE* outfile;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
string filename(path);
string _path("/sdcard/lua/");
_path.append(filename);
char *s = new char[100];
strcpy(s,_path.c_str());
_splitpath(s, drive, dir, fname, ext);
//如果文件已经存在直接返回
if(0 == access(s,F_OK))
{
ALOGD("[dumpulua] path:%s Exist",s);
return;
} else {
//创建目录
createMultiLevelDir(dir);
ALOGD("[dumpulua] path:%s New file",s);
}
FILE *file = fopen(s, "wb+");
if (file != NULL) {
fwrite(data , sizeof(unsigned char) , data_len , file);
fclose(file);
}
}
int findStr(const char *str, char strList[][30], int len) {
int x = -1;
for (int i = 0; i < len; i++) {
if (strstr(str, strList[i]) != NULL) {
return i;
}
}
return x;
}
size_t new_size = 0;
#define REPLACE_LIST_SIZE 5
//动态替换LUA文件
char *dynamicReplaceLuaFile(const char *name) {
FILE *t_file;
int index = 0;
char *base_path = "/sdcard/t_lua/";
char replaceLuaList[][30] = {"M_Attack_Bullet.luac","init_questLib_sub1.luac", "QuestConfig.luac", "Hero4.luac","Hero3GroundSkill1.luac"};
index = findStr(name, replaceLuaList, REPLACE_LIST_SIZE);
if (index >= 0) {
char *fullPath = new char[100];
memset(fullPath, 0, 100);
strcat(fullPath, base_path);
strcat(fullPath, replaceLuaList[index]);
if ((t_file = fopen(fullPath, "r")) != NULL) {
//替换文件
fseek(t_file, 0, SEEK_END);
new_size = ftell(t_file);
ALOGD("[dumpulua] file:%s size:%d", fullPath, new_size);
fseek(t_file, 0, SEEK_SET);
char *new_buff = (char *) alloca(new_size + 1);
fread(new_buff, new_size, 1, t_file);
fclose(t_file);
return new_buff;
} else {
ALOGD("[dumpulua] can't open file:%s replaceFile:%s", fullPath, name);
return NULL;
}
} else{
return NULL;
}
}
#define _DUMP_LUA_
#define _DYNAMIC_REPLACE_LUA_FILE_
int luaL_loadbuffer_mod(lua_State *L, const char *buff, size_t size, const char *name) {
// 保存(dump)lua文件
#ifdef _DUMP_LUA_P
string s(name);
if (s.length() < 128) {
saveFile(buff,size,name);
return luaL_loadbuffer_orig(L,buff,size,name);
}
return luaL_loadbuffer_orig(L,buff,size,name);
#endif
//动态替换lua文件
#ifdef _DYNAMIC_REPLACE_LUA_FILE_
char *newBuff = dynamicReplaceLuaFile(name);
if (NULL != newBuff) {
luaL_loadbuffer_orig(L, newBuff, new_size, name);
ALOGD("[dumpulua] replace done! file:%s size:%d",name,new_size);
}
else{
int ret = luaL_loadbuffer_orig(L, buff, size, name);
return ret;
}
#endif
int ret = luaL_loadbuffer_orig(L, buff, size, name);
return ret;
}
char *xrindex(char *s, char c) {
char *pc = new char[100];//足够长
strcpy(pc, s);
int len = 0;
while (*pc != 0) {
len++;
pc++;
}
for (int i = len; i >= 0; i--) {
if (*(s + i) == c) return s + i;
}
return NULL;
}
//分割路径
void _splitpath(char *path, char *drive, char *dir, char *fname, char *ext) {
char *p_whole_name;
drive[0] = '\0';
if (NULL == path) {
dir[0] = '\0';
fname[0] = '\0';
ext[0] = '\0';
return;
}
if ('/' == path[strlen(path)]) {
strcpy(dir, path);
fname[0] = '\0';
ext[0] = '\0';
return;
}
p_whole_name = xrindex(path, '/');
if (NULL != p_whole_name) {
p_whole_name++;
_split_whole_name(p_whole_name, fname, ext);
snprintf(dir, p_whole_name - path, "%s", path);
} else {
_split_whole_name(path, fname, ext);
dir[0] = '\0';
}
}
static void _split_whole_name(char *whole_name, char *fname, char *ext) {
char *p_ext;
p_ext = xrindex(whole_name, '.');
if (NULL != p_ext) {
strcpy(ext, p_ext);
snprintf(fname, p_ext - whole_name + 1, "%s", whole_name);
} else {
ext[0] = '\0';
strcpy(fname, whole_name);
}
}
/************** hook code *******************/
4.效果图如下:
dump lua文件已存在不保存,不存在的话保存到SD卡
动态替换lua文件
最后于 2018-4-27 11:30
被gelenlen编辑
,原因: