cod*_*her 4 c mmap binary-data
我有简单的c程序,比如my_bin.c:
#include <stdio.h>
int main()
{
printf("Success!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用gcc编译它并得到了可执行文件:my_bin.
现在我想使用另一个C程序调用main(或运行此my_bin).我用mmap和函数指针做了这样的事情:
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
void (*fun)();
int fd;
int *map;
fd = open("./my_bin", O_RDONLY);
map = mmap(0, 8378, PROT_READ, MAP_SHARED, fd, 0);
fun = map;
fun();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑1:添加PROT_EXEC从响应中更清楚......我想在第二个程序中调用外部二进制程序.
我不知道如何使用main(其他程序)的地址初始化函数指针.任何的想法?
为什么seg故障,谷歌搜索后,想通了,因为我的大小和mmap的偏移量参数.它应该是pagesize的倍数.[参考:Segfault在C中使用mmap读取二进制文件
现在代码看起来像:
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
void (*fun)();
int fd;
int *map;
int offset = 8378;
int pageoffset = offset % getpagesize();
fd = open("./my_bin", O_RDONLY);
if(fd == -1) {
printf("Err opening file\n");
return -1;
}
map = mmap(0, 8378 + pageoffset, PROT_READ|PROT_EXEC,
MAP_SHARED, fd, offset - pageoffset);
perror("Err\n"); //This is printing err and Success!
//fun = map; // If I uncomment this and
//fun(); // this line then, still it
// print err and Success! from perror
// but later it says Illegal instruction.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
仍然有趣()或没有它不打印...不知道如何给main()地址.
第一件事:我没有正确读取定义,我已经给出了我应该读取二进制文件的地址.第二:mmap:size和offset应该是pagesize的倍数.
main()通常不是C程序中的第一个函数.链接器将在此之前放置一些setup/init代码,其中包括设置环境,获取命令行参数,将它们解析为字符串数组,这样的东西.
当新main()函数开始设置内存分配例程时会出现问题- 基本上,这会破坏主应用程序的所有重要数据结构.
如果你想执行一个函数(即没有main()),那么将你的C代码编译成一个共享库,并用dlopen()你的操作系统等效加载它.
如果你真的需要main(),请使用fork()和exec().