require 实现

  • require函数在实现上是依次调用package.searchers(lua51中是package.loaders)中的载入函数,成功后返回。在loadlib.c文件里有四个载入函数的实现,分别为searcher_preload, searcher_Lua, searcher_C, searcher_Croot。
  • searcher_preload是从读取LUA_REGISTRYINDEX的_PRELOAD字段。已经require过的文件会写入到该表中
  • searcher_Lua是依据文件名称查找package.path中的全部路径的lua文件。存在文件则返回
  • searcher_C是搜索package.cpath中的全部路径下的库文件
  • searcher_Croot是对require(“a.b.c”)的情况,读取a库。然后查找函数名为lua_a_b_c的lua_CFunction函数
static void findloader (lua_State *L, const char *name) {
int i;
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
/* iterate over available searchers to find a loader */
for (i = 1; ; i++) {
lua_rawgeti(L, 3, i); /* get a searcher */
if (lua_isnil(L, -1)) { /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
}
  • 如今要实如今require时能读取加密文件,有两种办法,一种是直接改动源码。即改动第二个载入函数,又一次实现当中读取文件内容的函数,另外一种办法是在lua中改动package.searchers表。在载入器的第一和另外一种之间加入一个载入器函数,该载入器模拟searcher_Lua函数。搜索path路径,然后逐个匹配文件。然后读取文件内容,解密。然后调用load载入并返回(c中为luaL_loadbufferx),这里在载入时最好传入文件名称作为来源參数。方便在调试信息中定位.
  • 加密方案可使用相似xxtea轻量级的加密算法
  • 在对lua文件进行加密打包时。能够在文件头写入指定的签名内容。以方便在解密前预先推断是否为有效的加密文件

改动lua源码方案

  • 在searcher_Lua中终于是调用lua_load(L, getF, &lf, lua_tostring(L, -1), mode)载入源文件,该函数的第二个參数getF是一个lua_Reader函数,所以这里能够重写该函数以实现解密,也能够向外部暴露一个接口用来将自己定义的文件读取函数作为參数传给lua_load。以下是原版的getF实现
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
(void)L; /* not used */
if (lf->n > 0) { /* are there pre-read characters to be read? */
*size = lf->n; /* return them (chars already in buffer) */
lf->n = 0; /* no more pre-read characters */
}
else { /* read a block from file */
/* 'fread' can return > 0 *and* set the EOF flag. If next call to
'getF' called 'fread', it might still wait for user input.
The next check avoids this problem. */
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
}
return lf->buff;
}

外部改动载入器方案

  • 直接改动package.searchers表,向当中加入载入器,c版实现例如以下
void addLuaSearcher(lua_CFunction func)
{
if (!func) return; // stack content after the invoking of the function
// get loader table
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "loaders"); /* L: package, loaders */
// insert loader into index 2
lua_pushcfunction(m_state, func); /* L: package, loaders, func */
for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
{
lua_rawgeti(m_state, -2, i - 1); /* L: package, loaders, func, function */
// we call lua_rawgeti, so the loader table now is at -3
lua_rawseti(m_state, -3, i); /* L: package, loaders, func */
}
lua_rawseti(m_state, -2, 2); /* L: package, loaders */
// set loaders into package
lua_setfield(m_state, -2, "loaders"); /* L: package */
lua_pop(m_state, 1);
}
  • 载入器函数实现依据传入的文件名称。逐个匹配的package.path中的内容,存在文件后,然后读取文件内容,解密,最后再将解出的内容调用load载入并返回(c中为luaL_loadbufferx),实现能够參照lua源码中的searcher_Lua实现

lua 代码加密方案的更多相关文章

  1. cocos对lua代码加密

    1.0 cocos luacompile 用法 我用的普通的cocos2d lua,没用quick,quick好像可以对整个资源包括图像和音频都加密,打包成zip.但我没用quick.看了下luaco ...

  2. cocos2d 3.3 lua 代码加密 luac

    1.0 cocos luacompile 使用方法 我用的普通的cocos2d lua,没用quick,quick好像能够对整个资源包含图像和音频都加密,打包成zip.我看了下luacompile 的 ...

  3. 【Web技术】399- 浅谈前端代码加密

    作者简介:于航,PayPal Senior Software Engineer,在 PayPal 上海负责 Global GRT 平台相关的技术研发工作.曾任职于阿里巴巴.Tapatalk 等企业.f ...

  4. cocos lua 加密方案

    cocos2d使用的是luajit,lua原生编译出来的bytecode和luajit是不兼容的,所以直接用luac法编译出来的bytecode脚本无法在cocos2d中使用. 目前所指的解决方案有2 ...

  5. 如何保护你的 Python 代码 (一)—— 现有加密方案

    https://zhuanlan.zhihu.com/p/54296517 0 前言 去年11月在PyCon China 2018 杭州站分享了 Python 源码加密,讲述了如何通过修改 Pytho ...

  6. [转帖]如何保护你的 Python 代码 (一)—— 现有加密方案

    如何保护你的 Python 代码 (一)—— 现有加密方案 Prodesire Python猫 1周前

  7. [自动化-脚本]002.cocos2dx-lua lua代码windows加密批处理

    在开发软件的时候,我们都会在项目上线时候对代码进行加密,用来防止被不法分子盗走牟利.不同的语言有不同的加密方式,比较出名的有加壳,代码混淆等.在Lua开发cocos2dx的时候,框架会有提供加密的脚本 ...

  8. 关于cocos2dx手游lua文件加密的解决方式

    非常多使用cocos2dx+lua做游戏的同学.都会想到一个问题,我的游戏一旦公布,如何才干保证的我脚本代码不被破解.不泄露代码.尽管这和开源.共享的原则不合.可是代码也是coder的劳动成果,理应得 ...

  9. iOS代码加密常用加密方式

    iOS代码加密常用加密方式 iOS代码加密常用加密方式,常见的iOS代码加密常用加密方式算法包括MD5加密.AES加密.BASE64加密,三大算法iOS代码加密是如何进行加密的,且看下文 MD5 iO ...

随机推荐

  1. 利用localStorage实现对ueditor编辑内容定时保存为草稿

    直接看代码吧 1.引入ueditor和ueditor的使用我就不细说了 详情请戳http://blog.csdn.net/wangdianyong/article/details/39780709 2 ...

  2. Eclipse设置打印线

    在调出Preferences之后,选中Text Editors.先选中Show print margin,在Print margin column框中填入180就可以,然后选择以下的Print mar ...

  3. javax.mail 遇到501 mail from address must be same as authorization user 的問題

    使用不同的兩個帳戶发送email时,第一个账户可以发送成功,但到第二个账户的时候就报出了501 mail from address must be same as authorization user ...

  4. 使用 Reachability 获取网络状态

    Reachability source https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Int ...

  5. 计算一元一次方程Y=kX+b

    开发过程中用不到一元一次方程吗?非也,iOS开发中经常会遇到根据某个ScrollView动态偏移量的值来实时设置一个View的透明度,你敢说你不用一元一次方程你能搞定? 想把一个动画效果做好,经常会遇 ...

  6. Go 语言简介(上)— 语法

    周末天气不好,只能宅在家里,于是就顺便看了一下Go语言,觉得比较有意思,所以写篇文章介绍一下.我想写一篇你可以在乘坐地铁或公交车上下班时就可以初步了解一门语言的文章.所以,下面的文章主要是以代码和注释 ...

  7. mac的cpu处理器个数、核数、超线程

    处理器:1个 每个核的L2缓存大小:256KB L3缓存大小:3MB 核数:2个 2个核却有4个CPU:使用了超线程技术--双核四线程 macOS,查看CPU信息:sysctl machdep.cpu ...

  8. UVA 10474 (13.08.04)

     Where is the Marble?  Raju and Meena love to play with Marbles. They have got a lotof marbles with ...

  9. C# 实现的异步 Socket 服务器

    介绍 我最近需要为一个.net项目准备一个内部线程通信机制. 项目有多个使用ASP.NET,Windows 表单和控制台应用程序的服务器和客户端构成. 考虑到实现的可能性,我下定决心要使用原生的soc ...

  10. ElementUI的提示框的使用记录

    1.popover点击之后隐藏 问题描述:做了一个通知面板功能,下面提示信息有路由,每次点击消息呢,就跳转到了路由页面,但是此时这个面板没关闭,希望将其关闭 解决:官方文档有个属性 <div&g ...