android lua sd卡,[原创]基于VA框架DUMP-LUA源码和动态替换

1.修改VA的lib目录下的IOUniformer.cpp文件

d0e5f28d292c8d3878038eb74c83b080.png

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卡

ba4f072e81398e6f8ae833ae78f96936.png

动态替换lua文件

04b5df7052782eafaf4afc696ce9701a.png

最后于 2018-4-27 11:30

被gelenlen编辑

,原因:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值