Last Regrets

通过函数指针来运行汇编(机器码)

· sdttttt

之前已经知道了函数这个玩意在计算机中的本质,本身在栈中存放其实就是一个指针的方式,而指针指向的内容就是在内存中存放的机器码。


解释到这里就已经很明显了,函数其实并不是一定要在编译期载入内存后静态,也就是固定的方式运行的。

我们可以手动开辟内存,输入机器码,然后让指针指向这块内存。从而实现在运行时动态生成函数。

哦呼~想想就有点激动,这个逻辑其实就有点像动态语言,例如PHP,JAVA,Python的解释器的工作方式。

而且这个方式可以不用在语言中编写汇编,可以绕过某些平台无法在C中编写汇编的限制。

首先我们得获取机器码,我这里直接通过反汇编直接获取。

//0x00005555555547a7 <+0>:	55                 	push   rbp
//0x00005555555547a8 <+1>:	48 89 e5           	mov    rbp,rsp
//0x00005555555547ab <+4>:	b8 01 00 00 00     	mov    eax,0x1
//0x00005555555547b0 <+9>:	5d                 	pop    rbp
//0x00005555555547b1 <+10>:	c3                 	ret
int ret() {
    return 1;
}

然后把这些机器码写进内存, 之后进行类型强转之后,就可以直接运行。

char ret_code[] = {
            0x55,
            0x48, 0x89, 0xe5,
            0xb8, 0x10, 0x00, 0x00, 0x00,
            0x5d,
            0xc3
    };

    void *tmp = mmap(
            NULL,
            getpagesize(),
            PROT_READ | PROT_WRITE | PROT_EXEC,
            MAP_ANONYMOUS | MAP_PRIVATE,
            -1,
            0
            );

    memscp3(tmp, ret_code, sizeof(ret_code));

    ret_p p = tmp;

    int bbb = p();

    printf("%d\n", bbb);