Overriding C library functions, calling original - c

I am a bit puzzled on how and why this code works as it does. I have not actually encountered this in any project I've worked on, and I have not even thought of doing it myself.
override_getline.c:
#include <stdio.h>
#define OVERRIDE_GETLINE
#ifdef OVERRIDE_GETLINE
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
printf("getline &lineptr=%p &n=%p &stream=%p\n", lineptr, n, stream);
return -1; // note: errno has undefined value
}
#endif
main.c:
#include <stdio.h>
int main()
{
char *buf = NULL;
size_t len = 0;
printf("Hello World! %zd\n", getline(&buf, &len, stdin));
return 0;
}
And finally, example compile and run command:
gcc main.c override_getline.c && ./a.out
With the OVERRIDE_GETLINE define, the custom function gets called, and if it is commented out, normal library function gets called, and both work as expected.
Questions
What is the correct term for this? "Overriding", "shadowing", something else?
Is this gcc-specific, or POSIX, or ANSI C, or even undefined in all?
Does it make any difference if function is ANSI C function or (like here) a POSIX function?
Where does the overriding function get called? By other .o files in the same linking, at least, and I presume .a files added to link command too. How about static or dynamic libs added with -l command line option of linker?
If it is possible, how do I call the library version of getline from the overriden getline?

The linker will search the files you provide on the command line first for symbols, before it searches in libraries. This means that as soon as it sees that getline has been defined, it will no longer look for another getline symbol. This is how linkers works on all platforms.
This of course has implications for your fifth point, in that there is no possibility to call the "original" getline, as your function is the original from the point of view of the linker.
For the fifth point, you may want to look at e.g. this old answer.

There's no standard way to have two functions of the same name in your program, but with some UNIX-like implementations (notably GNU libc) you might be able to get away with this:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
ssize_t (*realfunc)(char**, size_t *, FILE*) =
(ssize_t(*)(char**, size_t *, FILE*))(dlsym (RTLD_NEXT, "getline"));
return realfunc(lineptr, n, stream);
}
You will need to link with -ldl for this.

What is happening here is that you are relying on the behaviour of the linker. The linker finds your implementation of getline before it sees the version in the standard library, so it links to your routine. So in effect you are overriding the function via the mechanism of link order. Of course other linkers may behave differently, and I believe the gcc linker may even complain about duplicate symbols if you specify appropriate command line switches.
In order to be able to call both your custom routine and the library routine you would typically resort to macros, e.g.
#ifdef OVERRIDE_GETLINE
#define GETLINE(l, n, s) my_getline(l, n, s)
#else
#define GETLINE(l, n, s) getline(l, n, s)
#endif
#ifdef OVERRIDE_GETLINE
ssize_t my_getline(char **lineptr, size_t *n, FILE *stream)
{
// ...
return getline(lineptr, n, stream);
}
#endif
Note that this requires your code to call getline as GETLINE, which is rather ugly.

What you see is expected behaviour if you linking with shared libraries. Linker will just assign it to your function, as it was first. It will also be correctly called from any other external libraries functions, - because linker will make your function exportable when it will scan linking libraries.
But - if you, say, have no external libraries that links to your function (so it isn't marked exportable, and isn't inserted to symbol table), and then dlopen() some library that want to use it during runtime - it will not find required function. Furthermore, if you first dlopen(RTLD_NOW|RTLD_GLOBAL) original library, every subsequent dlopen()'d library will use this library code, not yours. Your code (or any libraries that you've linked with during compilation phase, not runtime) will still stick with your function, no matter what.

Related

Check if a system implements a function

I'm creating a cross-system application. It uses, for example, the function itoa, which is implemented on some systems but not all. If I simply provide my own itoa implementation:
header.h:115:13: error: conflicting types for 'itoa'
extern void itoa(int, char[]);
In file included from header.h:2:0,
from file.c:2:0,
c:\path\to\mingw\include\stdlib.h:631:40: note: previous declaration of 'itoa' was here
_CRTIMP __cdecl __MINGW_NOTHROW char* itoa (int, char*, int);
I know I can check if macros are predefined and define them if not:
#ifndef _SOME_MACRO
#define _SOME_MACRO 45
#endif
Is there a way to check if a C function is pre-implemented, and if not, implement it? Or to simply un-implement a function?
Given you have already written your own implementation of itoa(), I would recommend that you rename it and use it everywhere. At least you are sure you will get the same behavior on all platforms, and avoid the linking issue.
Don't forget to explain your choice in the comments of your code...
I assume you are using GCC, as I can see MinGW in your path... there's one way the GNU linker can take care of this for you. So you don't know whether there is an itoa implementation or not. Try this:
Create a new file (without any headers) called my_itoa.c:
char *itoa (int, char *, int);
char *my_itoa (int a, char *b, int c)
{
return itoa(a, b, c);
}
Now create another file, impl_itoa.c. Here, write the implementation of itoa but add a weak alias:
char* __attribute__ ((weak)) itoa(int a, char *b, int c)
{
// implementation here
}
Compile all of the files, with impl_itoa.c at the end.
This way, if itoa is not available in the standard library, this one will be linked. You can be confident about it compiling whether or not it's available.
Ajay Brahmakshatriya's suggestion is a good one, but unfortunately MinGW doesn't support weak definition last I checked (see https://groups.google.com/forum/#!topic/mingwusers/44B4QMPo8lQ, for instance).
However, I believe weak references do work in MinGW. Take this minimal example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__ ((weak)) char* itoa (int, char*, int);
char* my_itoa (int a, char* b, int c)
{
if(itoa != NULL) {
return itoa(a, b, c);
} else {
// toy implementation for demo purposes
// replace with your own implementation
strcpy(b, "no itoa");
return b;
}
}
int main()
{
char *str = malloc((sizeof(int)*3+1));
my_itoa(10, str, 10);
printf("str: %s\n", str);
return 0;
}
If the system provides an itoa implementation, that should be used and the output would be
str: 10
Otherwise, you'll get
str: no itoa
There are two really important related points worth making here along the "don't do it like this" lines:
Don't use atoi because it's not safe.
Don't use atoi because it's not a standard function, and there are good standard functions (such as snprintf) which are available to do what you want.
But, putting all this aside for one moment, I want to introduce you to autoconf, part of the GNU build system. autoconf is part of a very comprehensive, very portable set of tools which aim to make it easier to write code which can be built successfully on a wide range of target systems. Some would argue that autoconf is too complex a system to solve just the one problem you pose with just one library function, but as any program grows, it's likely to face more hurdles like this, and getting autoconf set up for your program now will put you in a much stronger position for the future.
Start with a file called Makefile.in which contains:
CFLAGS=--ansi --pedantic -Wall -W
program: program.o
program.o: program.c
clean:
rm -f program.o program
and a file called configure.ac which contains:
AC_PREREQ([2.69])
AC_INIT(program, 1.0)
AC_CONFIG_SRCDIR([program.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for library functions.
AH_TEMPLATE([HAVE_ITOA], [Set to 1 if function atoi() is available.])
AC_CHECK_FUNC([itoa],
[AC_DEFINE([HAVE_ITOA], [1])]
)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and a file called program.c which contains:
#include <stdio.h>
#include "config.h"
#ifndef HAVE_ITOA
/*
* WARNING: This code is for demonstration purposes only. Your
* implementation must have a way of ensuring that the size of the string
* produced does not overflow the buffer provided.
*/
void itoa(int n, char* p) {
sprintf(p, "%d", n);
}
#endif
int main(void) {
char buffer[100];
itoa(10, buffer);
printf("Result: %s\n", buffer);
return 0;
}
Now run the following commands in turn:
autoheader: This generates a new file called config.h.in which we'll need later.
autoconf: This generates a configuration script called configure
./configure: This runs some tests, including checking that you have a working C compiler and, because we've asked it to, whether an itoa function is available. It writes its results into the file config.h for later.
make: This compiles and links the program.
./program: This finally runs the program.
During the ./configure step, you'll see quite a lot of output, including something like:
checking for itoa... no
In this case, you'll see that the config.h find contains the following lines:
/* Set to 1 if function atoi() is available. */
/* #undef HAVE_ITOA */
Alternatively, if you do have atoi available, you'll see:
checking for itoa... yes
and this in config.h:
/* Set to 1 if function atoi() is available. */
#define HAVE_ITOA 1
You'll see that the program can now read the config.h header and choose to define itoa if it's not present.
Yes, it's a long way round to solve your problem, but you've now started using a very powerful tool which can help you in a great number of ways.
Good luck!

Can I intercept normal stdio calls in a C program, do some work and then call the original ones?

I have a bunch of C files that try to read and write CSV and other random data to and from disk using stdio functions like fread(), fwrite(), fseek(). (If it matters, it's for a university assignment where we are to experiment with IO performance using different block sizes, and various structures to track data on disk files and so on.)
What I wanted to do was compile these source files (there are dozens of them)
without the definitions for fopen(), fread(), fwrite() that come from <stdio.h>. I want to supply my own fopen(), fread(), fwrite() where I track some information, like which process tried to read which file, and how many blocks/pages where read and things like that, and then call the normal stdio functions.
I don't want to have to go through every line of every file and change fopen() to my_fopen() .... is there better way to do this at compile time?
I am half way working on a Python program that scans the source files and changes these calls with my functions but it's getting a bit messy and I am kind of lost. I thought maybe there is a better way to do this; if you could point me in the right direction, like what to search for that would be great.
Also I don't want to use some Linux profiling stuff that reports which syscalls where made and what not; I just want to execute some code before calling these functions.
An alternative to the LD_PRELOAD trick (which requires you to write a separate library and works only on Linux) you can use the --wrap option of the GNU linker. See here for an example of this technique.
Main differences with LD_PRELOAD:
no external library needed - it's all in the executable;
no runtime options needed;
works on any platform as long as you are using the GNU toolchain;
works only for the calls that are resolved at link time - dynamic libraries will still use the original functions
No but yes but no. The best way I know of is to LD_PRELOAD a library that provides your own versions of those functions. You can get at the originals by dlopening libc.so (the dlopen NULL trick to get at libc functions isn't applicable here because your library will have already been loaded).
One way of doing it is by redefining all the stdio functions you need. fopen becomes my_fopen, fread becomes my_fread, then have your my_fopen call fopen. This can be done in a header file that you include in the files where you want to replace the calls to fopen. See example below.
main.c:
#include <stdio.h>
#include "my_stdio.h"
int main(void)
{
FILE *f;
char buf[256];
f = fopen("test.cvs", "r");
if(f == NULL)
{
printf("Couldn't open file\n");
return 1;
}
fread(buf, sizeof(char), sizeof(buf), f);
fclose(f);
return 0;
}
my_stdio.c:
#include <stdio.h>
FILE *my_fopen(const char *path, const char *mode)
{
FILE *fp;
printf("%s before fopen\n", __FUNCTION__);
fp = fopen(path,mode);
printf("%s after fopen\n", __FUNCTION__);
return fp;
}
int my_fclose(FILE *fp)
{
int rv;
printf("%s before fclose\n", __FUNCTION__);
rv = fclose(fp);
printf("%s after fclose\n", __FUNCTION__);
return rv;
}
size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t s;
printf("%s before fread\n", __FUNCTION__);
s = fread(ptr,size,nmemb,stream);
printf("%s after fread\n", __FUNCTION__);
return s;
}
size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t s;
printf("%s before fwrite\n", __FUNCTION__);
s = fwrite(ptr,size,nmemb,stream);
printf("%s after fwrite\n", __FUNCTION__);
return s;
}
my_stdio.h:
#ifndef _MY_STDIO_H_
#define _MY_STDIO_H_
#define fopen my_fopen
#define fclose my_fclose
#define fread my_fread
#define fwrite my_fwrite
#endif /* _MY_STDIO_H_ */
Makefile:
main: main.o my_stdio.o
$(CC) -g -o $# main.o my_stdio.o
main.o: main.c
$(CC) -g -c -o $# $<
my_stdio.o: my_stdio.c my_stdio.h
$(CC) -g -c -o $# $<
Another way: Add -Dfread=my_fread to the Makefile CFLAGS for any .o files you wish to "spy" on. Add in my_fread.o that defines my_fread [which has no -D tricks].
Repeat the above for any functions you wish to intercept. About the same as the LD_PRELOAD [in terms of effectiveness and probably easier to implement]. I've done both.
Or create a my_func.h that does the defines and insert a #include "my_func.h" in each file. Dealer's choice
UPDATE
Forgot about another way. Compile normally. Mangle the symbol names in the target .o's [symbol table] (via a custom program or ELF/hex editor): Change fread into something with the same length that doesn't conflict with anything [you can control this]. Target name: qread or frea_ or whatever.
Add your intercept .o's using the new names.
This might seem "dirty", but what we're doing here is a "dirty" job. This is an "old school" [sigh :-)] method that I've used for .o's for which I didn't have the source and before LD_PRELOAD existed.

How do I remove the following 'implicit declaration of function' warnings?

How do I compile the lex file with gcc without receiving the following warnings?
lex.yy.c: In function `yy_init_buffer':
lex.yy.c:1688: warning: implicit declaration of function `fileno'
lex.l: In function `storeLexeme':
lex.l:134: warning: implicit declaration of function `strdup'
These are the libraries I included.
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
%}
The function yy_init_buffer is not in the file. The following is the function storeLexeme.
int storeLexeme() {
for (int i = 0; i < count; i++) {
char *curr = *(symbolTable + i);
if (strcmp(curr, yytext) == 0) {
return i;
}
}
char *lexeme = (char *)malloc(sizeof(char *));
lexeme = (char *)strdup(yytext);
symbolTable[count] = lexeme;
count++;
return (count - 1);
}
How do I remove the warnings?
Neither strdup nor fileno are ISO C functions, they're part of POSIX.
Now whether they're available on your platform depends on your platform.
If you are using the Microsoft tools, you may want to look into _fileno for the latter (fileno was deprecated in VC2005). A rather excellent version of strdup can be found here.
Although, having blown my own horn with that code, you could also use _strdup since it replaces the also-deprecated strdup :-)
These should hopefully work okay as-is since they're in stdio.h and string.h, two of the include files you're already using.
If you're on a UNIX derivative, those functions should be available in stdio.h (for fileno) and string.h (for strdup). Given that it looks like you're already including those files, the problem is likely elsewhere.
One possibility is if you're compiling in one of the strict modes like __STRICT_ANSI__ in gcc), where neither would be defined.
You should have a look at the top of your generated lex.yy.c and lex.l files to confirm that the header files are being included and also check the command line parameters you're passing to the compiler.
I suggest this option (tell the compiler you are using POSIX):
#define _POSIX_C_SOURCE 1
People seem to have tightened up the feature controls in recent years and hopefully when the consistency is good and widespread we can throw away the automake garbage.
I also had this problem while using flex.
I used -std=gnu99rather than -std=c99 which solved the problem.
flex lang.l && gcc -o lexer -std=gnu99 lex.yy.c -lfl
Consider adding the following line:
extern char *strdup(const char *s);
I faced the problem when I compiled with -std=c99 -pedantic -pedantic-errors. Adding the above line solved the problem for me.
You declare the function before you use it:
//declare the function
int storeLexeme();
//use the function here
or include the header where the function is declared.
C implicitly assumes undeclared functions have return type int and deduces the parameters from how you call the function. This is deprecated in C++.
just place your function below the library calls it will be alright;

glibc - force function call (no inline expansion)

I have a question regarding glibc function calls. Is there a flag to tell gcc not to inline a certain glibc function, e.g. memcpy?
I've tried -fno-builtin-memcpy and other flags, but they didn't work. The goal is that the actual glibc memcpy function is called and no inlined code (since the glibc version at compile time differs from the one at runtime). It's for testing purposes only. Normally I wan't do that.
Any solutions?
UPDATE:
Just to make it clearer: In the past memcpy works even with overlapping areas. This has changed meanwhile and I can see this changes when compiling with different glibc versions. So now I want to test if my old code (using memcpy where memmove should have been used) works correct or not on a system with a newer glibc (e.g. 2.14). But to do that, I have to make sure, that the new memcpy is called and no inlined code.
Best regards
This may not be exactly what you're looking for, but it seems to force gcc to generate an indirect call to memcpy():
#include <stdio.h>
#include <string.h>
#include <time.h>
// void *memcpy(void *dest, const void *src, size_t n)
unsigned int x = 0xdeadbeef;
unsigned int y;
int main(void) {
void *(*memcpy_ptr)(void *, const void *, size_t) = memcpy;
if (time(NULL) == 1) {
memcpy_ptr = NULL;
}
memcpy_ptr(&y, &x, sizeof y);
printf("y = 0x%x\n", y);
return 0;
}
The generated assembly (gcc, Ubuntu, x86) includes a call *%edx instruction.
Without the if (time(NULL) == 1) test (which should never succeed, but the compiler doesn't know that), gcc -O3 is clever enough to recognize that the indirect call always calls memcpy(), which can then be replaced by a movl instruction.
Note that the compiler could recognize that if memcpy_ptr == NULL then the behavior is undefined, and again replace the indirect call with a direct call, and then with a movl instruction. gcc 4.5.2 with -O3 doesn't appear to be that clever. If a later version of gcc is, you could replace the memcpy_ptr = NULL with an assignment of some actual function that behaves differently than memcpy().
In theory:
gcc -fno-inline -fno-builtin-inline ...
But then you said -fno-builtin-memcpy didn't stop the compiler from inlining it, so there's no obvious reason why this should work any better.
#undef memcpy
#define mempcy your_memcpy_replacement
Somewhere at the top but after #include obviously
And mark your_memcpy_replacement as attribute((noinline))

Executing machine code in memory

I'm trying to figure out how to execute machine code stored in memory.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE* f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
char* bin = (char*)malloc(len);
fread(bin, 1, len, f);
fclose(f);
return ((int (*)(int, char *)) bin)(argc-1, argv[1]);
}
The code above compiles fine in GCC, but when I try and execute the program from the command line like this:
./my_prog /bin/echo hello
The program segfaults. I've figured out the problem is on the last line, as commenting it out stops the segfault.
I don't think I'm doing it quite right, as I'm still getting my head around function pointers.
Is the problem a faulty cast, or something else?
You need a page with write execute permissions. See mmap(2) and mprotect(2) if you are under unix. You shouldn't do it using malloc.
Also, read what the others said, you can only run raw machine code using your loader. If you try to run an ELF header it will probably segfault all the same.
Regarding the content of replies and downmods:
1- OP said he was trying to run machine code, so I replied on that rather than executing an executable file.
2- See why you don't mix malloc and mman functions:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
char *a=malloc(10);
char *b=malloc(10);
char *c=malloc(10);
memset (a,'a',4095);
memset (b,'b',4095);
memset (c,'c',4095);
puts (a);
memset (c,0xc3,10); /* return */
/* c is not alligned to page boundary so this is NOOP.
Many implementations include a header to malloc'ed data so it's always NOOP. */
mprotect(c,10,PROT_READ|PROT_EXEC);
b[0]='H'; /* oops it is still writeable. If you provided an alligned
address it would segfault */
char *d=mmap(0,4096,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_ANON,-1,0);
memset (d,0xc3,4096);
((void(*)(void))d)();
((void(*)(void))c)(); /* oops it isn't executable */
return 0;
}
It displays exactly this behavior on Linux x86_64 other ugly behavior sure to arise on other implementations.
Using malloc works fine.
OK this is my final answer, please note I used the orignal poster's code.
I'm loading from disk, the compiled version of this code to a heap allocated area "bin", just as the orignal code did (the name is fixed not using argv, and the value 0x674 is from;
objdump -F -D foo|grep -i hoho
08048674 <hohoho> (File Offset: 0x674):
This can be looked up at run time with the BFD (Binary File Descriptor library) or something else, you can call other binaries (not just yourself) so long as they are statically linked to the same set of lib's.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
unsigned char *charp;
unsigned char *bin;
void hohoho()
{
printf("merry mas\n");
fflush(stdout);
}
int main(int argc, char **argv)
{
int what;
charp = malloc(10101);
memset(charp, 0xc3, 10101);
mprotect(charp, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
__asm__("leal charp, %eax");
__asm__("call (%eax)" );
printf("am I alive?\n");
char *more = strdup("more heap operations");
printf("%s\n", more);
FILE* f = fopen("foo", "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
bin = (char*)malloc(len);
printf("read in %d\n", fread(bin, 1, len, f));
printf("%p\n", bin);
fclose(f);
mprotect(&bin, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
asm volatile ("movl %0, %%eax"::"g"(bin));
__asm__("addl $0x674, %eax");
__asm__("call %eax" );
fflush(stdout);
return 0;
}
running...
co tmp # ./foo
am I alive?
more heap operations
read in 30180
0x804d910
merry mas
You can use UPX to manage the load/modify/exec of a file.
P.S. sorry for the previous broken link :|
It seems to me you're loading an ELF image and then trying to jump straight into the ELF header? http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
If you're trying to execute another binary, why don't you use the process creation functions for whichever platform you're using?
An typical executable file has:
a header
entry code that is called before main(int, char **)
The first means that you can't generally expect byte 0 of the file to be executable; intead, the information in the header describes how to load the rest of the file in memory and where to start executing it.
The second means that when you have found the entry point, you can't expect to treat it like a C function taking arguments (int, char **). It may, perhaps, be usable as a function taking no paramters (and hence requiring nothing to be pushed prior to calling it). But you do need to populate the environment that will in turn be used by the entry code to construct the command line strings passed to main.
Doing this by hand under a given OS would go into some depth which is beyond me; but I'm sure there is a much nicer way of doing what you're trying to do. Are you trying to execute an external file as a on-off operation, or load an external binary and treat its functions as part of your program? Both are catered for by the C libraries in Unix.
It is more likely that that it is the code that is jumped to by the call through function-pointer that is causing the segfault rather than the call itself. There is no way from the code you have posted to determine that that code loaded into bin is valid. Your best bet is to use a debugger, switch to assembler view, break on the return statement and step into the function call to determine that the code you expect to run is indeed running, and that it is valid.
Note also that in order to run at all the code will need to be position independent and fully resolved.
Moreover if your processor/OS enables data execution prevention, then the attempt is probably doomed. It is at best ill-advised in any case, loading code is what the OS is for.
What you are trying to do is something akin to what interpreters do. Except that an interpreter reads a program written in an interpreted language like Python, compiles that code on the fly, puts executable code in memory and then executes it.
You may want to read more about just-in-time compilation too:
Just in time compilation
Java HotSpot JIT runtime
There are libraries available for JIT code generation such as the GNU lightning and libJIT, if you are interested. You'd have to do a lot more than just reading from file and trying to execute code, though. An example usage scenario will be:
Read a program written in a scripting-language (maybe
your own).
Parse and compile the source into an
intermediate language understood by
the JIT library.
Use the JIT library to generate code
for this intermediate
representation, for your target platform's CPU.
Execute the JIT generated code.
And for executing the code you'd have to use techniques such as using mmap() to map the executable code into the process's address space, marking that page executable and jumping to that piece of memory. It's more complicated than this, but its a good start in order to understand what's going on beneath all those interpreters of scripting languages such as Python, Ruby etc.
The online version of the book "Linkers and Loaders" will give you more information about object file formats, what goes on behind the scenes when you execute a program, the roles of the linkers and loaders and so on. It's a very good read.
You can dlopen() a file, look up the symbol "main" and call it with 0, 1, 2 or 3 arguments (all of type char*) via a cast to pointer-to-function-returning-int-taking-0,1,2,or3-char*
Use the operating system for loading and executing programs.
On unix, the exec calls can do this.
Your snippet in the question could be rewritten:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
return execv(argv[1],argv+2);
}
Executable files contain much more than just code. Header, code, data, more data, this stuff is separated and loaded into different areas of memory by the OS and its libraries. You can't load a program file into a single chunk of memory and expect to jump to it's first byte.
If you are trying to execute your own arbitrary code, you need to look into dynamic libraries because that is exactly what they're for.

Resources