Reputation: 91
I made a program which copies all contents of another c prog (binary file), writes them to another file and then executes it (execve()
) after adding execution permission to it (chmod()
).
Now I want to store all the contents of the file in an array inside the prog (I use hex representation) and then execute it. For this purpose I created another program in C which converts a file to hex representation here is the source code of these two programs:
#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: program that converts file to hex reprentation
#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;
}
As you can see in my converter program i remove the null bytes from the executable file. Is that correct or will the program fail to executes? My main issue is that I cant fit the whole program content inside an array. So how can I implement a program that stores the contents of another and then executes them?
gcc
compiler.Upvotes: 0
Views: 183
Reputation: 679
You can embed the exe to your program like specified here: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967
Just remember when writing the file to disk to use fopen with binary mode: fopen("myexe.exe", wb");
Upvotes: 0
Reputation: 2539
If you have binary file like following [A prog, B prog] and you know where B prog starts in your executable you could use mmap like in this thread.
UPDATE (only for linux) from this :
#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;
}
This will output "Hello, world!"
To manage big executable files you can make converter that will generate c header file like following:
//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,
....
and then include it in your main program and use as in example above.
Upvotes: 1