【问题标题】:Embedding any file into gcc compiled program and accessing it inside program将任何文件嵌入到 gcc 编译的程序中并在程序中访问它
【发布时间】:2020-05-03 14:17:04
【问题描述】:

我正在制作一个程序,我想在文件中读取并将文件的内容存储到实际程序中。然后程序一旦运行,就可以用嵌入的文件创建一个新文件。

Program.c compile with picture.jpg
Program is now the output file that has picture.jpg inside of it
Program runs and then creates a new file called pic.jpg
Program reads somewhere(?) in its own code to find the data of the picture.jpg
Program writes the data to pic.jpg
Now pic.jpg and picture.jpg are the same file.

我做了一些阅读,发现了一篇解释它的小文章:https://codeplea.com/embedding-files-in-c-programs

“替代方案 - 直接链接 Blob”的底部

我的问题是,如何

extern const char binary_some_file_jpg_start[];
extern const char binary_some_file_jpg_end[];

告诉我我的数据在哪里?那些是随机的名字,它仍然知道去哪里找数据吗?

【问题讨论】:

    标签: c unix gcc ld


    【解决方案1】:

    已经阅读了这篇文章(这不是必需的;您的问题应该独立存在),我不清楚数组是如何确定的。文章使用

    gcc -c my_program.c -o my_program.o
    ld -r -b binary -o some_file.o some_file.jpg
    gcc my_program.o some_file.o -o my_program
    

    将 JPG 文件 some_file.jpg 嵌入到目标文件 (some_file.o)。

    GNU ld 手册页涵盖了-b binary。根据经验,从image.jpg 创建(二进制)对象文件后,您会定义一些符号:

    $ ld -r -b binary -o image.o image.jpg
    $ nm image.o
    00000000000442d0 D _binary_image_jpg_end
    00000000000442d0 A _binary_image_jpg_size
    0000000000000000 D _binary_image_jpg_start
    $
    

    ld -r -b binary … 操作的输出是一个定义了三个符号的“目标文件”,其中包含一个 .data 部分并定义了三个符号。符号名称由ld 从它要处理的二进制文件的名称中确定。

    $ objdump -h image.o
    
    image.o:     file format elf64-x86-64
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .data         000442d0  0000000000000000  0000000000000000  00000040  2**0
                      CONTENTS, ALLOC, LOAD, DATA
    $ objdump -t image.o
    
    image.o:     file format elf64-x86-64
    
    SYMBOL TABLE:
    0000000000000000 l    d  .data  0000000000000000 .data
    0000000000000000 g       .data  0000000000000000 _binary_image_jpg_start
    00000000000442d0 g       .data  0000000000000000 _binary_image_jpg_end
    00000000000442d0 g       *ABS*  0000000000000000 _binary_image_jpg_size
    
    $
    

    请注意,这些符号的开头有一个下划线。您可以使用此代码打印出地址等。请注意,它使用t 限定符来表示ptrdiff_t 类型——这是减去两个指针的结果的类型:

    #include <stdio.h>
    
    extern char _binary_image_jpg_start[];
    extern char _binary_image_jpg_end[];
    
    int main(void)
    {
        printf("Image start: %p\n", _binary_image_jpg_start);
        printf("Image end:   %p\n", _binary_image_jpg_end);
        printf("Image size:  0x%tx\n", _binary_image_jpg_end - _binary_image_jpg_start);
        return 0;
    }
    

    示例输出:

    $ gcc -o image main.c image.o
    $ ./image
    Image start: 0x6008e8
    Image end:   0x644bb8
    Image size:  0x442d0
    $
    

    计算的图像大小对应于nm image.o 给出的大小。所以代码可以继续从数组_binary_image_jpg_start中读取数据。

    这取决于 GNU ld 程序的代码特性。它可能不适用于任何其他 ld — 除非程序模拟 GNU ld

    使用 GCC 9.2.0 和 GNU ld (GNU Binutils) 2.25.1 在古董 RHEL 5(2.6.18-128.el5 #1 SMP,日期 2008-12-17)上创建的演示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 2011-07-07
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多