Windows下动态加载可执行代码原理简述

来源:网络 责任编辑:栏目编辑 发表时间:2013-07-01 19:38 点击:

 

问C#里面能不能动态加载SIMD的汇编代码。C#我不知道,反正c/c++下面这事情很好做。顺手花了几个小时写了个例子和这篇博客。

 

总的来说,windows下要动态加载binary的话,基本上分以下几步。

 

1. 首先要得到可执行代码的binary。 无论是在程序里面编译也好,或者从什么地方读出来,或者用户手把手的敲进去。

 

2. 为这些binary分配一段具有可执行属性的内存。这是因为有Data Execution Prevention的存在,一般用malloc和new分配的内存页面不具有可执行这个属性,一旦执行就会产生STATUS_ACCESS_VIOLATION的异常。

 

3. 下一步就是要跳转到这段内存上去执行了,可能要写一些汇编指令,在调用的过程中要注意栈是否平衡。

 

 

基本上就是这三点了,下面来看具体的代码:

 

第一步,拿到可执行的binary。这里我写了一个用SIMD指令的fastercopy函数,然后编译以后把它的二进制代码写成一个数组。

 

int emitcode[] = {0x83ec8b55,0x565340ec,0x0c758b57,0x8b087d8b, 0x348d104d,0xcf3c8dce,0x6f0fd9f7,0x6f0fce04, 0x0f08ce4c,0x10ce546f,0xce5c6f0f,0x646f0f18, 0x6f0f20ce,0x0f28ce6c,0x30ce746f,0xce7c6f0f, 0x04e70f38,0x4ce70fcf,0xe70f08cf,0x0f10cf54, 0x18cf5ce7,0xcf64e70f,0x6ce70f20,0xe70f28cf, 0x0f30cf74,0x38cf7ce7,0x7508c183,0xf8ae0fad, 0x5e5f770f,0x5de58b5b,0xccccccc3};fastercopy函数是这样写的

 

View Code

void fastercopy(void* dst, void* src, int len){    __asm {        mov esi, [src] // source array        mov edi, [dst] // destination array        mov ecx, [len] // number of QWORDS (8 bytes)        lea esi, [esi+ecx*8] // end of source        lea edi, [edi+ecx*8] // end of destination        neg ecx // use a negative offsetcopyloop:        movq mm0, qword ptr[esi+ecx*8]        movq mm1, qword ptr[esi+ecx*8+8]        movq mm2, qword ptr[esi+ecx*8+16]        movq mm3, qword ptr[esi+ecx*8+24]        movq mm4, qword ptr[esi+ecx*8+32]        movq mm5, qword ptr[esi+ecx*8+40]        movq mm6, qword ptr[esi+ecx*8+48]        movq mm7, qword ptr[esi+ecx*8+56]        movntq qword ptr[edi+ecx*8], mm0        movntq qword ptr[edi+ecx*8+8], mm1        movntq qword ptr[edi+ecx*8+16], mm2        movntq qword ptr[edi+ecx*8+24], mm3        movntq qword ptr[edi+ecx*8+32], mm4        movntq qword ptr[edi+ecx*8+40], mm5        movntq qword ptr[edi+ecx*8+48], mm6        movntq qword ptr[edi+ecx*8+56], mm7        add ecx, 8        jnz copyloop        sfence // flush write buffer        emms    }}

第二步,分配内存了。这里调用的是VirtualAlloc这个windows函数。在最后一个参数指定PAGE_EXECUTE_READWRITE属性。

 

    void* address = NULL;    address= VirtualAlloc(NULL,            sizeof(emitcode),            MEM_COMMIT|MEM_RESERVE,            PAGE_EXECUTE_READWRITE);        memcpy(address,emitcode,sizeof(emitcode));  

 

第三步,调用这个存在address中的代码。

 

可以自己写汇编代码调用:<

    相关新闻>>

      发表评论
      请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
      用户名: 验证码:点击我更换图片
      最新评论 更多>>

      推荐热点

      • dos命令原来也能这样用?允许查找未知子目录指定文件
      •  windows的磁盘操作之八——格式化分区的思考
      • windows篇-第三章 安装和配置DNS服务器
      • windows篇-第二章 安装和配置Web服务器
      • windows篇-第一章 windows server 2008安装和简单配置
      •  windows server 2003断开远程之后自动注销用户
      • Windows服务器下用IIS Rewrite组件为IIS设置伪静态方法
      • Windows 2008 R2 SP1部署WSUS 3.0 SP2
      • Windows 7秘籍揭秘:用“手”写公式

      快速直达

      操作系统导航

      LinuxWindows虚拟机
      网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
      Copyright © 2008-2015 计算机技术学习交流网. 版权所有

      豫ICP备11007008号-1