我已经尝试阅读有关mmap
的文档,但是我仍然很难理解如何使用它。
我想从命令行获取参数,然后将其分配给可执行内存区域。然后,我希望能够从该代码执行。
这是我到目前为止的内容:
int main(int argc, char const *argv[]) {
if (argc != 2) {
printf("Correct input was not provided\n");
exit(1);
}
char assembly_code[256];
const char *read = argv[1];
int x = sscanf(read, "%02hhx", assembly_code);
if (x != 1) {
printf("sscan failed, exited\n");
exit(1);
}
int* map;
size_t size = sizeof(assembly_code) / sizeof(assembly_code[0]);
map = mmap(NULL, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, -1, 0);
((void (*)(void))map)();
return 0;
}
这是我得到的输出/错误:
Segmentation fault: 11
我不知道我是否正确使用了mmap
。如果我是我,我不相信我会正确执行它。
例如,如果此文件使用参数e8200000004889c64831c048ffc04889c74831d2b2040f054831c0b83c0000004831ff0f05e806000000584883c008c3ebf84869210a
运行,则应返回Hi!
,然后终止。我真的不知道如何在映射后获取此输出,或者如何“调用/执行” mmap
。
int x = sscanf(read, "%02hhx", assembly_code);
这仅转换一个字节。我认为没有标准的库函数可以转换整个十六进制字节的字符串。您必须循环调用sscanf
,并根据需要递增输入缓冲区read
和输出缓冲区assembly_code
中的指针。
在mmap
调用中,如果您不想映射文件,则应使用标志MAP_ANONYMOUS
而不是MAP_SHARED
。您还应该检查其返回值(错误时返回MAP_FAILED
)并报告任何错误。同样,返回值原则上是void *
类型而不是int *
(尽管在普通的Unix系统上这没有什么区别)。
mmap
调用(已修复)将返回一个指针,该指针指向填充有零的内存块。它没有理由包含您的assembly_code
,因此您可能必须将其复制到其中,也许是使用memcpy
。或者,您可以移动循环并将十六进制字节直接解析到mmap
分配的区域中。