IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    在 MIPS 平台上运行时动态生成指令并执行 (2)

    hev发表于 2011-12-04 11:38:43
    love 0

    上次是直接在可执行的栈中写入指令并转移至执行的,这次在当栈和堆都不可执行的情况下,分配空间、写入指令并执行。还是直接看代码吧。

    #include 
    #include 
    #include mman.h>
    
    int main(int argc, char *argv[])
    {
    	unsigned int *insn = NULL;
    
    	insn = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
    				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    	if(MAP_FAILED != insn)
    	{
    		printf("%p\n", insn);
    		insn[0] = 0x1000ffff;
    		insn[1] = 0x00000000;
    		__asm__ volatile (
    					"jr %0 \n\t"
    					"nop \n\t"
    					::"r"(insn)
    				);
    		munmap(insn, 4096);
    	}
    	else
    	{
    		printf("%s\n", strerror(errno));
    	}
    
    	return 0;
    }
    

    在上面的代码中,使用系统调用 mmap 分配了一块 4096 字节的可读写、可执行的私有、匿名 VMA,并在此 VMA 中写入指令并转移至执行了。

    我们来看一下此程序的运行时输出与 maps:

    0x2ac88000
    
    00400000-00404000 r-xp 00000000 08:04 262145                             /home/heiher/tmp/test
    00410000-00414000 rw-p 00000000 08:04 262145                             /home/heiher/tmp/test
    2ac64000-2ac88000 r-xp 00000000 08:02 917518                             /lib/ld-2.14.so
    2ac88000-2ac8c000 rwxp 00000000 00:00 0 
    2ac94000-2ac98000 rw-p 00020000 08:02 917518                             /lib/ld-2.14.so
    2ac98000-2aca8000 rw-p 00000000 00:00 0 
    2acb4000-2ae0c000 r-xp 00000000 08:02 918040                             /lib/libc-2.14.so
    2ae0c000-2ae18000 ---p 00158000 08:02 918040                             /lib/libc-2.14.so
    2ae18000-2ae1c000 r--p 00154000 08:02 918040                             /lib/libc-2.14.so
    2ae1c000-2ae20000 rw-p 00158000 08:02 918040                             /lib/libc-2.14.so
    2ae20000-2ae24000 rw-p 00000000 00:00 0 
    7fc04000-7fc28000 rwxp 00000000 00:00 0                                  [stack]
    7fff4000-7fff8000 r-xp 00000000 00:00 0                                  [vdso]
    

    我们看到确定多出了一个我们所需要的 VMA:

    2ac88000-2ac8c000 rwxp 00000000 00:00 0 
    

    但其长度却不是 4096 字节,而是 16K(16384)。这是因为我们当前的操作系统页面长度是 16K(16384),分配一个VMA至少需要一个完整的页面,当小于它的时候也需要分配一个完整的页面。

    如何让进程的栈和堆都不可执行呢?有没有办法可以修改代码段的数据?在上面分配了 4096 字节的内存,而实际则是 16K,那么其 4096 之后的空间是否可以使用呢?动态生成指令随后立即执行是否有问题呢?

    Over!



沪ICP备19023445号-2号
友情链接