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

昨天晚上回去后实在无聊睡不着,拿着身边的 Yeeloong 笔记本随便找点事干干,想到了 JIT 的原理,于是简单的验证了一下运行时动态生成指令并执行。

我先找了一下进程中哪个 VMA 是可以执行的,使用命令 cat /proc/self/maps 可以找到:

00400000-0040c000 r-xp 00000000 08:02 524311                             /bin/cat
00418000-0041c000 rw-p 00008000 08:02 524311                             /bin/cat
0041c000-00440000 rwxp 00000000 00:00 0                                  [heap]
2b9c8000-2b9ec000 r-xp 00000000 08:02 917518                             /lib/ld-2.14.so
2b9f8000-2b9fc000 rw-p 00020000 08:02 917518                             /lib/ld-2.14.so
2ba18000-2bb70000 r-xp 00000000 08:02 918040                             /lib/libc-2.14.so
2bb70000-2bb7c000 ---p 00158000 08:02 918040                             /lib/libc-2.14.so
2bb7c000-2bb80000 r--p 00154000 08:02 918040                             /lib/libc-2.14.so
2bb80000-2bb84000 rw-p 00158000 08:02 918040                             /lib/libc-2.14.so
2bb84000-2bb88000 rw-p 00000000 00:00 0 
2bb88000-2bd88000 r--p 00000000 08:02 786854                             /usr/lib/locale/locale-archive
7ff70000-7ff94000 rwxp 00000000 00:00 0                                  [stack]
7fff4000-7fff8000 r-xp 00000000 00:00 0                                  [vdso]

从上面的结果中可以看到 heap 和 stack 两个 VMA 的权限属性都是 rwxp,意味着我可以向里面存入指令并执行。

我选择了在栈中存入两条指令,然后转过去执行。代码如下:

#include <stdio.h>
 
int main(int argc, char *argv[])
{
	unsigned int insn[] =
	{
		0x1000ffff,
		0x00000000
	};
 
	__asm__ volatile (
				"jr %0 \n\t"
				"nop \n\t"
				::"r"(insn)
			);
 
	return 0;
}

编译程序后,执行这个程序就会进入栈里的死循环了。

你可能会想到这个操作系统的 heap 和 stack 具有可执行权限是不安全的,我确认了一下 x86 里没有可执行权限的,那么当没有可执行权限又应该怎么办呢?我们下次再说。

Over!

Leave a Reply

Your email address will not be published. Required fields are marked *