我正在解析 .elf 文件以编辑其中的一些详细信息。我使用 open() 打开文件,然后使用 mmap() 为其创建内存映射,以便于编辑。
问题是创建内存映射后出现意外行为。
为了调试问题并查看是否正确使用了 open() 和 mmap() 函数,我精简了代码以简单地打印 .elf 文件的内容。但是,即使我这样做了,打印的内容也与我执行
objdump -s myfile.elf
时得到的输出不同
请记住,这不是我的完整代码,这只是出于问题目的的精简版本,但它仍然无法工作。
我现在正在寻找的是打印文件内容并具有与
objdump
命令相同的输出
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
typedef struct iFi {
unsigned char *pB; // memory mapped file
void *hFmap;
void *hFile;
int handle_File;
unsigned long fSize; // file size
struct stat sts; /* File status */
char szFN[1024]; // file name
} XFILE;
int main (int argc, char **argv) {
if(argc != 2)
return 1;
XFILE myfile;
XFILE *pF = &myfile;
memset (&pF->pB, 0, sizeof (pF->pB));
memset (&pF->hFmap, 0, sizeof (pF->hFmap));
memset (&pF->hFile, 0, sizeof (pF->hFile));
memset (&pF->szFN, 0, sizeof (pF->szFN));
strcpy (pF->szFN, argv[1]);
mode_t perms = S_IRUSR | S_IWUSR;
pF->handle_File = open(pF->szFN, O_RDWR, perms);
if (pF->handle_File < 0) {
perror("open");
return (1);
}
int n = stat (pF->szFN, &pF->sts);
if (n != 0) return(1000); // failed
pF->fSize = pF->sts.st_size;
//pF->hFmap = CreateFileMapping (pF->hFile, NULL, PAGE_READWRITE /*PAGE_WRITECOPY*/, 0, 0, NULL);
pF->pB = static_cast<unsigned char*>(mmap(NULL, pF->fSize, PROT_READ | PROT_WRITE, MAP_SHARED, pF->handle_File, 0));
if (pF->pB == NULL) return 1000; // can't map view of file
printf("Contents of file = 0x%x\n", *pF->pB);
return 0;
}
这是我的预期输出(前 0xFF 字节)
0000 00000320 9d050000 c9050000 cd050000 ... ............
0010 c5050000 c5050000 c5050000 00000000 ................
这是我得到的实际输出
Contents of file = 0x7f
如您所见,我的文件中的任何位置都没有 0x7f,即使我打印 pF->pB 的全部内容,我也会得到:
0x0000000100288000 "\U0000007fELF\U00000001\U00000001\U00000001"
但是,即使我这样做了,打印的内容也与我执行 objdump -s myfile.elf 时得到的输出不同
打印的内容应与您看到的内容相符
$ hd myfile.elf
内存映射文件内容与加载
.elf
二进制文件的过程不同,因为这需要 dlopen(3)
库调用。
Objdump 读取并打印
.elf
特定信息,例如节内容,并要求格式为 ELF,而 mmap(2)
只是将文件内容(任何类型的文件)映射到内存中,因此您可以看到文件内容,就好像它一样是记忆。
这意味着,如果您使用
mmap(2)
进行映射,那么您需要解释ELF标头并通过自己映射地址来搜索部分。