Calling a function (main ()) from a binary in C

I have a simple c program, my_bin.c:

#include <stdio.h> int main() { printf("Success!\n"); return 0; } 

I compile it with gcc and get the executable: my_bin.

Now I want to call main (or run this my_bin) using another C program. I did this with mmap and the function pointer as follows:

 #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> int main() { void (*fun)(); int fd; int *map; fd = open("./my_bin", O_RDONLY); map = mmap(0, 8378, PROT_READ, MAP_SHARED, fd, 0); fun = map; fun(); return 0; } 

EDIT 1: PROT_EXEC added Due to a clearer answer from the answers ... I want to call an external binary program in a second program.

I do not know how to initialize a function pointer with the address main (other programs). any idea?

EDIT 2:

Why seg fault, after googling, understood, due to my size and mmap offset argument. It should be a multiple of the number of pages. [Link: Segfault when using mmap in C to read binary files

Now the code looks like this:

 #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> int main() { void (*fun)(); int fd; int *map; int offset = 8378; int pageoffset = offset % getpagesize(); fd = open("./my_bin", O_RDONLY); if(fd == -1) { printf("Err opening file\n"); return -1; } map = mmap(0, 8378 + pageoffset, PROT_READ|PROT_EXEC, MAP_SHARED, fd, offset - pageoffset); perror("Err\n"); //This is printing err and Success! //fun = map; // If I uncomment this and //fun(); // this line then, still it // print err and Success! from perror // but later it says Illegal instruction. return 0; } 

Still with fun () or without it does not print ... not sure how to specify the address of main ().

Edit 2 [SOLVED]:

First: I didnโ€™t read the definition correctly, I already gave the address from which I should read the binary. Secondly: mmap: size and offset should be a multiple of the page size.

+4
source share
3 answers

main() usually not the first function in a C program. The compiler will add some installation / initialization code to, among other things, install the environment, receive command line arguments, parse them into an array of strings, something like this.

A problem arises when the new main() function starts to tune memory allocation routines - basically it will destroy all the important data structures of your main application.

If you want to execute a function (i.e. without main() ), then compile your C code into a shared library and load it with dlopen() or the equivalent of your OS.

If you really need main() , use fork() and exec() .

+6
source

Typically, an executable file created by compilation and linking is not a simple binary image that can be loaded into memory and executed. (There are certain goals of the computing platform where they exist.) Usually, a special program called the loader should read the executable file, prepare the memory using the contents and instructions in the file, and use special system calls to start the program execution as a new process.

For example, executables usually contain some data that must be copied to memory and then marked for reading, some data that must be copied to memory and then marked for read and write, and some data (called "text" or program instructions) to be copied to memory and marked as executable. The executable file usually also contains some other information about preparing the memory, such as allocating a certain amount of initially cleared memory, allocating a certain amount for the stack space for which the address is started (usually not main ), and so on.

One difficult aspect is that the executable file contains information about which parts of the program text and data should be changed depending on which memory addresses are used. The addresses where data and text are stored in memory may not be known at compile time, so the compiler writes some prototype code, and the loader must configure the code after it resolves to the addresses.

Another complication is that the executable file may contain references to characters in dynamic libraries. The loader should check these links and load the necessary dynamic libraries.

As you can see, downloading is not an easy process. You cannot just copy the map of the executable file and switch to it, even if you can find out where main launched in it.

Some systems provide an interface to the bootloader. They are commonly used with dynamic libraries. Instead of creating a standalone executable program, you will create a dynamic library. Then you can use the calls to the dynamic library interface to load the library, find the addresses of the subprograms in it, and call these procedures.

Typically, a programming environment does not provide a convenient way to load an executable file and call its main routine. It may be easier to create a dynamic library instead of creating an executable file, and then load the dynamic library and call the subroutine inside it. In addition, there are ways to call the executable file as a separate process, so that it essentially runs separately, like a command entered on the command line, without exchanging memory with the calling process.

+1
source

The โ€œcorrectโ€ IMHO solution when linking functionality in one executable file is not calling main () from another function. Rather, create a function that terminates main () and calls it as from main () s.

 int success() { printf("Success!\n"); return 0; } int main() { return success(); } 

To call an external system call, use system

-1
source

Source: https://habr.com/ru/post/1434027/


All Articles