当前位置: 首页 > news >正文

网站开发日程安排/网络推广工作室

网站开发日程安排,网络推广工作室,免费发短信的在线网站,怎么在国外网站赚钱最近在为distri.lua实现一个lua调试系统,有一个简单的需求,lua导入一个文件的时候,将这个文件的文件名记录下来, 以方便调试器在设置断点的时候判断是否一个合法的文件. lua导入文件是通过luaL_loadfilex实现的,一个简单的思路就是修改luaL_loadfilex,在luaL_loadfilex中调用一…

最近在为distri.lua实现一个lua调试系统,有一个简单的需求,lua导入一个文件的时候,将这个文件的文件名记录下来,
以方便调试器在设置断点的时候判断是否一个合法的文件.

lua导入文件是通过luaL_loadfilex实现的,一个简单的思路就是修改luaL_loadfilex,在luaL_loadfilex中调用一个外部定义的函数将导入的文件名传给那个外部函数,由它记录下来.
但这种侵入式的方案,除非在逼不得已的情况下不应该使用.

另一个思路是hook luaL_loadfilex,在运行时用另外一个函数替换luaL_loadfilex,由这个替换函数去记录下需要的信息
然后在跳转回原luaL_loadfilex的执行流程上.

与是我从decode中提取除了Hook.h,Hook.c稍加调整以适应Linux系统.

hook的原理很简单:

    * 首先,使用mprotect将luaL_loadfilex所在代码段设置为可读/可写/可执行,以避免在修改代码时出现段访问异常* 之后需要把luaL_loadfilex最前面的一段指令替换成一个跳转指令,跳转到替换函数中去执行.为了在替换函数执行完之后可以正确的回到luaL_loadfilex的正常执行路径上,需要把luaL_loadfilex中被替换部分的指令保存下来,然后在后面再添加一条跳转指令,调到luaL_loadfilex后面的执行路径去.

被替换掉的指令布局和执行流程如下图:

    luaL_loadfilex:jmp hook-------------其余指令  <-------------------------------------------------||hook:                                                                |执行必要的记录                                               |--保存的代码----                                             |luaL_loadfilex中被替换的指令                                 |jmp其余指令--------------------------------------------------|                      

HookFunction实现如下:

    void* HookFunction(void* function, void* hook){// Don't allow rehooking of the same function since that screws things up.assert(!GetIsHooked(function, hook));if (GetIsHooked(function, hook)){return NULL;}// Missing from windows.h//#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000// Jump instruction is 5 bytes.const int jumpSize = 5;// Compute the instruction boundary so we don't override half an instruction.int boundary = GetInstructionBoundary(function, jumpSize);size_t pagesize = sysconf(_SC_PAGE_SIZE);unsigned char* trampoline = NULL;trampoline = (unsigned char*)/*aligned_alloc*/memalign(pagesize,pagesize);if(mprotect(trampoline, pagesize, PROT_WRITE|PROT_READ|PROT_EXEC)){free(trampoline);return NULL;}// Copy the original bytes to the trampoline area and append a jump back// to the original function (after our jump).memcpy(trampoline, function, boundary);AdjustRelativeJumps(trampoline, boundary, ((unsigned char*)function) - trampoline);WriteJump(trampoline + boundary, ((unsigned char*)function) + boundary);void *ptr = (void*)(((size_t)function/pagesize)*pagesize);// Give ourself write access to the region.if(!mprotect(ptr, pagesize, PROT_WRITE|PROT_READ|PROT_EXEC)){// Fill the area with nops and write the jump instruction to our// hook function.memset(function, 0x90, boundary);WriteJump(function, hook);// Restore the original protections.//VirtualProtect(function, boundary, protection, &protection);mprotect(ptr, pagesize, PROT_READ|PROT_EXEC);// Flush the cache so we know that our new code gets executed.//FlushInstructionCache(GetCurrentProcess(), NULL, NULL);return trampoline;//return 0;}    free(trampoline);return NULL;//return -1;        }

本以为一切就这样结束了,运行程序的时候,正确的进入了替换函数,但在执行完记录操作要回到luaL_loadfilex后续执行流程的时候程序
挂了,报段访问异常.

为啥呢,我们看下WriteJump的实现:

/*** Writes a relative jmp instruction.*/
void WriteJump(void* dst, void* address)
{unsigned char* jump = (unsigned char*)(dst);// Setup a jump instruction.jump[0] = 0xE9;*((unsigned long*)(&jump[1])) = (unsigned long)(address) - (unsigned long)(dst) - 5;}

使用的是E9跳转指令+4字节的立即数做相对rip计数器的跳转.这在32位程序下这是没问题的,因为trampoline和luaL_loadfilex的位移差必定
在4字节的范围内.但我程序的运行环境是64位的,这个时候程序就出问题了, trampoline和luaL_loadfilex的位移差已经超过4个字节.这就导致
[jmp其余指令]跳转到到错误的地址上了.

如何解决这个问题:

*   用FF指令做跳转,但这个方案要修改的地方就多了,除了` WriteJump`,还有`AdjustRelativeJumps`并且还会导致指令长度变长.*   用static数据区保存luaL_loadfilex中被替换的指令,使得位移差被控制在4字节以内.

针对我的需求,我选择了方案2,下面是修改过的HookFunction和WriteJump以及使用示例:

    /*** Writes a relative jmp instruction.*/void WriteJump(void* dst, void* address){unsigned char* jump = (unsigned char*)(dst);// Setup a jump instruction.jump[0] = 0xE9;*((unsigned int*)(&jump[1])) = (unsigned int)((unsigned long)(address) - (unsigned long)(dst) - 5);}void* HookFunction(void* function, void* hook,void *saveaddr,size_t saveaddr_size){// Don't allow rehooking of the same function since that screws things up.assert(!GetIsHooked(function, hook));if (GetIsHooked(function, hook)){return NULL;}// Missing from windows.h//#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000// Jump instruction is 5 bytes.const int jumpSize = 5;// Compute the instruction boundary so we don't override half an instruction.int boundary = GetInstructionBoundary(function, jumpSize);if(saveaddr_size < (size_t)boundary) return NULL;size_t pagesize = sysconf(_SC_PAGE_SIZE);if(mprotect(saveaddr, boundary, PROT_WRITE|PROT_READ|PROT_EXEC)){//free(trampoline);return NULL;}// Copy the original bytes to the trampoline area and append a jump back// to the original function (after our jump).memcpy(saveaddr, function, boundary);AdjustRelativeJumps(saveaddr, boundary, ((unsigned char*)function) - (unsigned char*)saveaddr);WriteJump(saveaddr + boundary, ((unsigned char*)function) + boundary);void *ptr = (void*)(((size_t)function/pagesize)*pagesize);// Give ourself write access to the region.if(!mprotect(ptr, pagesize, PROT_WRITE|PROT_READ|PROT_EXEC)){// Fill the area with nops and write the jump instruction to our// hook function.memset(function, 0x90, boundary);WriteJump(function, hook);// Restore the original protections.//VirtualProtect(function, boundary, protection, &protection);mprotect(ptr, pagesize, PROT_READ|PROT_EXEC);// Flush the cache so we know that our new code gets executed.//FlushInstructionCache(GetCurrentProcess(), NULL, NULL);return saveaddr;//return 0;}    return NULL;//return -1;}

使用示例

    int (*ori_luaL_loadfilex)(lua_State *L, const char *filename,const char *mode) = NULL;int my_luaL_loadfilex(lua_State *L, const char *filename,const char *mode){printf("%s\n",filename);//记录导入的lua文件,供调试器使用return ori_luaL_loadfilex(L,filename,mode);}static char luaL_loadfilex_buf[4096] __attribute__((aligned(4096)));int debug_init(){ori_luaL_loadfilex = HookFunction(luaL_loadfilex,my_luaL_loadfilex,luaL_loadfilex_buf,4096);if(!ori_luaL_loadfilex){return -1;}   return 0;}

转载于:https://www.cnblogs.com/sniperHW/p/3946279.html

http://www.jmfq.cn/news/5079961.html

相关文章:

  • 那个做图网站叫什么/百度浏览器网页版
  • 悦然wordpress建站服务/百度游戏中心app
  • 开源课程 视频网站模板/营销策划书案例
  • 中山网站建设制作 .超凡科技/电子商务网络营销
  • 深圳 汽车网站建设/苹果自研搜索引擎或为替代谷歌
  • 新冠肺炎疫情最新公布/seo搜索引擎专员
  • 聊城做网站的公司/公司网站制作流程
  • html5 手机 手机网站/长沙seo优化价格
  • 长宁网站推广公司/快速建站
  • 请假条模板/上海百度搜索排名优化
  • 章丘区网站建设/深圳外贸网站制作
  • 英国设计网站/网站不收录怎么办
  • 黑龙江新闻夜航/短视频seo是什么
  • 公司名字大全3个字/汕头seo网站推广
  • 合肥网站营销/百度百家
  • 个人网站开发用什么语言/网络营销有哪些特点
  • wordpress4.0.x/班级优化大师使用指南
  • pc端网站建设相关查阅资料/关键词搜索查找工具
  • 北京公司摇号需要哪些资格条件/福建搜索引擎优化
  • 购物网站建设带来的社会效益/开网站需要什么流程
  • 电气网站建设/南阳网站优化公司
  • wordpress 坏图片/seo教程书籍
  • 手机网站 后台/流量推广app
  • 做钢材的都用什么网站/营销推广怎么做
  • 网站建设发票税点/seo秘籍优化课程
  • 自学网站有哪些自学网/广告买卖网
  • ccd设计公司很厉害吗/汕头seo管理
  • 万网域名注册官网邮箱/河北seo推广公司
  • css样式模板网站/推广普通话的内容简短
  • 游戏充值网站怎么做/app推广是什么工作