我制作了一个程序,复制了另一个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;
}
正如您在转换器程序中看到的,我从可执行文件中删除了空字节。这是正确的还是程序无法执行? 我的主要问题是我不能将整个程序内容放在数组中。那么如何实现一个存储另一个内容的程序然后执行呢?
gcc
编译器。答案 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()