使用mmap将内容放入分配的内存区域中

问题描述 投票:0回答:1

我已经尝试阅读有关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

c mmap
1个回答
0
投票
  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分配的区域中。

© www.soinside.com 2019 - 2024. All rights reserved.