将程序存储在另一个程序

时间:2016-09-05 14:21:47

标签: c file binary

我制作了一个程序,复制了另一个c prog(二进制文件)的所有内容,将它们写入另一个文件,然后在向其添加执行权限后执行它(execve())( chmod())。

现在我想将文件的所有内容存储在prog中的数组中(我使用 hex 表示),然后执行它。为此我在C中创建了另一个程序,它将文件转换为十六进制表示,这里是这两个程序的源代码:

#include <stdio.h> //program used for execution
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

unsigned char prog []= {}// thats the string i am planning to use so i can store the program 

void FileCreate(const char *in) {

  FILE *fp2 = fopen(in,"wb"); // create afile in binary form with write permission
  if (fp2==NULL) {  //error checking
    fclose(in);
    printf("file '%s' isn't here...\n", in);
    exit(1);
  }

  int ch;  
  int i = 0;
  for (i=0; i<sizeof(prog);++i) { 
    ch = prog[i];
    fputc(ch, fp2);
  }

  fclose(fp2);
}

int main (int argc,char *argv[]){
  if (argc != 2) {
     fprintf(stderr, "Usage: %s [file_name]\n", argv[0]);
     exit(1);
  }
  FileCreate(argv[1]);
  char *cmd[] = {argv[1], NULL};
  int err = chmod (argv[1], S_IXUSR);
  if (err==-1){
     perror ("Change mode");
     exit(1);
  }
  err = execve (cmd[0], cmd,NULL);
  if (err==-1){
    perror ("Execute file");
    exit(1);
  }
  return 0;
}

converter.c :将文件转换为十六进制表示的程序

#include <stdio.h>
int main (void) {
  unsigned char data[1024];
  size_t numread, i;

  while ((numread = read(0, data, 1024)) > 0) {
    for (i = 0; i < numread; i++) {
       if(data[i] != 0){ //remove null bytes
       printf("0x%02x,", data[i]);
    }
  }
}

  return 0;
}

正如您在转换器程序中看到的,我从可执行文件中删除了空字节。这是正确的还是程序无法执行? 我的主要问题是我不能将整个程序内容放在数组中。那么如何实现一个存储另一个内容的程序然后执行呢?

  • 我正在使用Linux环境和gcc编译器。
  • 这些程序是出于教育目的而进行的,它们不属于作业或练习。
  • 如果您需要任何进一步的信息,现在就让我

2 个答案:

答案 0 :(得分:1)

如果您有二进制文件,例如以下[A prog,B prog]并且您知道B prog在可执行文件中的开始位置,您可以使用this thread中的mmap。

来自this

更新(仅适用于Linux):

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

unsigned char mya[] =   {
              0x50,0x57,0x56,0x52,0xe8,
              0x00,0x00,0x00,0x00,0x5e,
              0x48,0x81,0xc6,0x24,0x00,
              0x00,0x00,0x48,0xc7,0xc0,
              0x01,0x00,0x00,0x00,0x48,
              0xc7,0xc7,0x01,0x00,0x00,
              0x00,0x48,0xc7,0xc2,0x0e,
              0x00,0x00,0x00,0x0f,0x05,
              0x5a,0x5e,0x5f,0x5a,0xc3,
              0x48,0x65,0x6c,0x6c,0x6f,
              0x2c,0x20,0x57,0x6f,0x72,
              0x6c,0x64,0x21,0x0a,0x00
            };

int main(int argc, char**argv)
{
  void *addr = (void*)((unsigned long)mya & ((0UL - 1UL) ^ 0xfff));/*get memory page*/
  int ans = mprotect(addr, 1, PROT_READ|PROT_WRITE|PROT_EXEC);/*set page attributes*/
  if (ans)
  {
    perror("mprotect");
    exit(EXIT_FAILURE);
  }

  ((void(*)(void))mya)();/*execute array*/

  return 0;
}

这将输出&#34; Hello,world!&#34;

要管理大型可执行文件,您可以制作生成c头文件的转换器,如下所示:

//data.h
static unsigned char executable[] =
{
0x50, 0x36, 0x0A, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 
0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4D, 0x50, 0x0A, 0x32, 0x37, 
0x37, 0x20, 0x31, 0x36, 0x32, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0xFF, 0xFF, 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
....

然后将其包含在主程序中并按上面的示例使用。

答案 1 :(得分:0)

您可以将exe嵌入到您的程序中,如下所示:http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967

记住将文件写入磁盘时要使用fopen和二进制模式:fun1()