在C程序中嵌入二进制代码

在C程序中嵌入二进制代码,c,binary,C,Binary,我正试图用C语言编写一个程序,该程序能够使用选项调用某些二进制文件(例如lsof、netstat)。该程序的目的是从计算机收集法医数据,同时该程序不应使用正在分析的计算机二进制文件,因为它们可能会受到危害。因此,要求已嵌入C程序中的经认证/未经压缩的二进制文件(例如lsof、netstat-antpu等)或由存储在usb驱动器中的C程序调用 例如,使用“ls”命令的二进制文件,我使用链接器创建了一个对象文件,如下所示: 使用以下命令,我从对象文件中提取了以下入口点 下一步是使用我可能需要的一些选

我正试图用C语言编写一个程序,该程序能够使用选项调用某些二进制文件(例如lsof、netstat)。该程序的目的是从计算机收集法医数据,同时该程序不应使用正在分析的计算机二进制文件,因为它们可能会受到危害。因此,要求已嵌入C程序中的经认证/未经压缩的二进制文件(例如lsof、netstat-antpu等)或由存储在usb驱动器中的C程序调用

  • 例如,使用“ls”命令的二进制文件,我使用链接器创建了一个对象文件,如下所示:
  • 使用以下命令,我从对象文件中提取了以下入口点
  • 下一步是使用我可能需要的一些选项(例如“ls-al”)从主程序调用“function”。因此,我制作了一个C程序来调用对象文件的入口点

  • 然后,我用以下gcc选项编译了程序

  • 这是主程序:

    #include <stdio.h>
    
    extern int _binary_bin_x86_2_4_ls_start();
    
    int main(void)  
    {
        _binary_bin_x86_2_4_ls_start();
        return 0;
    }
    
    #包括
    extern int二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制;
    内部主(空)
    {
    _二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制二进制;
    返回0;
    }
    
    当我运行程序时,我遇到了一个分段错误。我在testld程序中使用objdump检查了入口点,链接似乎成功了。那么为什么我会遇到分割错误呢? 我还需要使用选项调用“ls”。我如何做到这一点,即使用参数“-al”调用“函数”


    谢谢。

    二进制文件的ELF头不是函数。你不能这么说。如果可以的话(就像在一些古老的二进制格式中),这将是一个非常糟糕的主意,因为它永远不会返回

    如果要在中游运行另一个程序,请执行以下操作:

    int junk;
    pid_t pid;
    if (!(pid = fork())) {
        execl("ls", "/bin/ls", ...); /* this results in running ls in current directory which is probably what you want but maybe you need to adjust */
        _exit(3);
    }
    if (pid > 0) waitpid(pid, &junk, 0);
    
    为简洁起见,省略了错误处理


    在您的情况下,您应该将自己的二进制文件副本与程序一起提供。

    二进制文件的ELF头不是函数。你不能这么说。如果可以的话(就像在一些古老的二进制格式中),这将是一个非常糟糕的主意,因为它永远不会返回

    如果要在中游运行另一个程序,请执行以下操作:

    int junk;
    pid_t pid;
    if (!(pid = fork())) {
        execl("ls", "/bin/ls", ...); /* this results in running ls in current directory which is probably what you want but maybe you need to adjust */
        _exit(3);
    }
    if (pid > 0) waitpid(pid, &junk, 0);
    
    为简洁起见,省略了错误处理


    在您的情况下,您应该将自己的二进制文件副本与您的程序一起提供。

    这并不像听起来那么容易,因为存储二进制数据通常会在不可执行的数据段中结束。您必须首先自己将其重新定位到一个可执行段中,并围绕该段创建一个新进程,以便可以类似于
    exec
    的方式调用它。简而言之,您必须重新实现操作系统的动态加载程序。如果这不是一个或类似的加载程序,我会感到惊讶。。。。可能会,也可能不会满足您的所有需求,但它可能会回答一些关于可行性的问题。最简单的方法可能是嵌入二进制文件,然后在需要时将其写入文件,并使用
    exec
    例程之一执行该文件。或者,当您通过该程序进行复制时,只需复制您自己的其他二进制文件。但这可能是一个X-Y问题:要从受损系统收集法医数据,根本不应该运行该系统。您应该直接从其存储中复制数据(例如,移除其存储并使用另一台计算机读取数据,或者,如果硬件不完全不受信任,则以“目标磁盘模式”[Mac功能]引导它并读取数据)。我注意到了您的取证方案,并准备了内核模式的rootkit。这并不像听起来那么简单,因为存储二进制数据通常会在不可执行的数据段中结束。您必须首先自己将其重新定位到一个可执行段中,并围绕该段创建一个新进程,以便可以类似于
    exec
    的方式调用它。简而言之,您必须重新实现操作系统的动态加载程序。如果这不是一个或类似的加载程序,我会感到惊讶。。。。可能会,也可能不会满足您的所有需求,但它可能会回答一些关于可行性的问题。最简单的方法可能是嵌入二进制文件,然后在需要时将其写入文件,并使用
    exec
    例程之一执行该文件。或者,当您通过该程序进行复制时,只需复制您自己的其他二进制文件。但这可能是一个X-Y问题:要从受损系统收集法医数据,根本不应该运行该系统。您应该直接从其存储中复制数据(例如,移除其存储并用另一台计算机读取数据,或者,如果硬件并非完全不受信任,则在“目标磁盘模式”[Mac功能]下引导它并读取数据)。我注意到了您的取证方案,并准备了一个内核模式的rootkit。问题是,他们不想在系统上使用二进制文件,因此
    execl(“/bin/ls”…)
    不是一个可接受的解决方案。@EricPostChil:我明白了。我做了一个小小的修正。他可以将二进制文件作为文件发送并正常调用。问题是他们不想在系统上使用二进制文件,因此
    execl(“/bin/ls”…)
    不是一个可接受的解决方案。@EricPostChil:我明白了。我做了一个小小的修正。他可以将二进制文件作为文件发送,并正常调用它们。
    #include <stdio.h>
    
    extern int _binary_bin_x86_2_4_ls_start();
    
    int main(void)  
    {
        _binary_bin_x86_2_4_ls_start();
        return 0;
    }
    
    int junk;
    pid_t pid;
    if (!(pid = fork())) {
        execl("ls", "/bin/ls", ...); /* this results in running ls in current directory which is probably what you want but maybe you need to adjust */
        _exit(3);
    }
    if (pid > 0) waitpid(pid, &junk, 0);