How to wrap existing function in C - c

I am trying to wrap existing function.
below code is perfectly worked.
#include<stdio.h>
int __real_main();
int __wrap_main()
{
printf("Wrapped main\n");
return __real_main();
}
int main()
{
printf("main\n");
return 0;
}
command:
gcc main.c -Wl,-wrap,main
output:
Wrapped main
main
So i have changed main function with temp. my goal is to wrap temp() function.
Below is the code
temp.c
#include<stdio.h>
int temp();
int __real_temp();
int __wrap_temp()
{
printf("Wrapped temp\n");
return __real_temp();
}
int temp()
{
printf("temp\n");
return 0;
}
int main()
{
temp();
return 0;
}
command:
gcc temp.c -Wl,-wrap,temp
output:
temp
Wrapped temp is not printing. please guide me to wrap funciton temp.

The manpage for ld says:
--wrap=symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to "__wrap_symbol". Any
undefined reference to "__real_symbol" will be resolved to symbol.
The keyword here is undefined.
If you put the definition temp in the same translation unit as the code that uses it, it will not be undefined in the code that uses it.
You need to split the code definition and the code that uses it:
#!/bin/sh
cat > user.c <<'EOF'
#include<stdio.h>
int temp(void);
int __real_temp(void);
int __wrap_temp()
{
printf("Wrapped temp\n");
return __real_temp();
}
int main()
{
temp();
return 0;
}
EOF
cat > temp.c <<'EOF'
#include<stdio.h>
int temp()
{
printf("temp\n");
return 0;
}
EOF
gcc user.c -Wl,-wrap,temp temp.c # OK
./a.out
Splitting the build into two separate compiles perhaps makes it clearer:
$ gcc -c user.c
$ gcc -c temp.c
$ nm user.o temp.o
temp.o:
U puts
0000000000000000 T temp
user.o:
0000000000000015 T main
U puts
U __real_temp
U temp
0000000000000000 T __wrap_temp
Now since temp is undefined in user.c, the linker can do its __real_/__wrap_magic on it.
$ gcc user.o temp.o -Wl,-wrap=temp
$ ./a.out
Wrapped temp
temp

The answer proposed by PSCocik works great if you can split the function you want to override from the function that will call it. However if you want to keep the callee and the caller in the same source file the --wrap option will not work.
Instead you can use __attribute__((weak)) before the implementation of the callee in order to let someone reimplement it without GCC yelling about multiple definitons.
For example suppose you want to mock the world function in the following hello.c code unit. You can prepend the attribute in order to be able to override it.
#include "hello.h"
#include <stdio.h>
__attribute__((weak))
void world(void)
{
printf("world from lib\n");
}
void hello(void)
{
printf("hello\n");
world();
}
And you can then override it in another unit file. Very useful for unit testing/mocking:
#include <stdio.h>
#include "hello.h"
/* overrides */
void world(void)
{
printf("world from main.c\n");
}
int main(void)
{
hello();
return 0;
}

Related

How to hook a self-defined function in C?

I am studying how to hook a self-defined function through dynamical linking using LD_PRELOAD.
However, most of the tutorials try to hook a libc function, e.g. puts().
Is it possible to hook a self-defined function, too?
I am trying the following code
//test.c
#include <stdio.h>
int ptest(){
printf("test!\n");
return 0;
}
int main(void){
printf("%d\n", ptest());
return 0;
}
//hook.c
//compile: "gcc hook.c -shared -fPIC -Wall -o hook.so"
#include <stdio.h>
int ptest(){
printf("fake!\n");
return 1;
}
run
LD_PRELOAD=./hook.so ./test
Result (It means nothing changed by hook.so)
test!
0
What I expect
fake!
1

How call and compile function from elf to my binary?

I have a binary file (ELF) that I don't write, but I want to use 1 function from this binary (I know the address/offset of the function), that function not exported from the binary.
My goal is to call this function from my C code that I write and compile this function statically in my binary (I compile with gcc).
How can I do that please?
I am going to answer the
call to this function from my c code that I write
part.
The below works under certain assumptions, like dynamic linking and position independent code. I haven't thought for too long about what happens if they are broken (let's experiment/discuss, if there's interest).
$ cat lib.c
int data = 42;
static int foo () { return data; }
gcc -fpic -shared lib.c -o lib.so
$ nm lib.so | grep foo
00000000000010e9 t foo
The above reproduces having the address that you know. The address we know now is 0x10e9. It is the virtual address of foo before relocation. We'll model the relocation the dynamic loader does by hand by simply adding the base address at which lib.so gets loaded.
$ cat 1.c
#define _GNU_SOURCE
#include <stdio.h>
#include <link.h>
#include <string.h>
#include <elf.h>
#define FOO_VADDR 0x10e9
typedef int(*func_t)();
int callback(struct dl_phdr_info *info, size_t size, void *data)
{
if (!(strstr(info->dlpi_name, "lib.so")))
return 0;
Elf64_Addr addr = info->dlpi_addr + FOO_VADDR;
func_t f = (func_t)addr;
int res = f();
printf("res = %d\n", res);
return 0;
}
int main()
{
void *handle = dlopen("./lib.so", RTLD_LAZY);
if (!handle) {
puts("failed to load");
return 1;
}
dl_iterate_phdr(&callback, NULL);
dlclose(handle);
return 0;
}
And now...
$ gcc 1.c -ldl && ./a.out
res = 42
Voila -- it worked! That was fun.
Credit: this was helpful.
If you have questions, feel free to read the man and ask in the comments.
As for
compile this function statically in my binary
I don't know off the bat. This would be trickier. Why do you want that? Also, do you know whether the function depends on some data (or maybe it calls other functions) in the original ELF file, like in the example above?

shared libraries and visibility to user's memory

When I use a shared library via dlopen, can the library code "see" memory of my process that calls dlopen? For example, I would like to pass a pointer to memory allocated by my application to the library API.
I'm on Linux/x86 if it is important.
The answer is yes, it can. Here is a simple quick example for illustration purposes.
The library code (in file myso.c):
void setInt( int * i )
{
*i = 12345;
}
The library can be built as follows:
gcc -c -fPIC myso.c
gcc -shared -Wl,-soname,libmy.so -o libmy.so myso.o -lc
Here is the client code (main.c):
#include <stdio.h>
#include <dlfcn.h>
typedef void (*setint_t)( int * );
int main()
{
void * h = dlopen("./libmy.so", RTLD_NOW);
if (h)
{
puts("Loaded library.");
setint_t setInt = dlsym( h, "setInt" );
if (setInt) {
puts("Symbol found");
int k;
setInt(&k);
printf("The int is %d\n", k);
}
}
return 0;
}
Now build and run the code. Make sure main.c and the library are in the same directory, in which we execute the following:
user#fedora-21 ~]$ gcc main.c -ldl
[user#fedora-21 ~]$ ./a.out
Loaded library.
Symbol found
The int is 12345
As one can see, the library was able to write to the memory of the integer k.

Unable to call a pointer to function returning a pointer

I'm stuck with a weird problem.
I have two files a.c and b.c as follows:
b.c:
#include <stdlib.h>
int *foo() {
int *x;
x = (int *) malloc(sizeof(int));
*x = 4;
return x;
}
I compile b.c to b.so using gcc:
$ gcc -o b.so -shared -fpic
a.c:
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *hdl;
hdl = dlopen("./b.so", RTLD_LAZY);
int *((*fn)(void));
int *x;
x = (*fn)();
fn = dlsym(hdl, "foo");
printf("%d", *x);
}
I compile a.c using gcc:
$ gcc -fpic -ldl a.c
Now when I run it:
$ ./a.out
Segmentation fault
Where I'm I going wrong?
This works when the function in b.c doesn't return a pointer.
And moreover, I tried checking for errors using dlerror(), but it reports none.
By inspection, you are using fn before you have initialized it. It doesn't yet point to foo, it doesn't yet point to anything in particular, and I suspect the resultant behavior is undefined.
You are not finding the symbol and calling the function.
When you do x = (*fn)(); it doesnt make call to the function foo from b.c.
You have to first get the symbol loaded into your function pointer.
int *x;
fn = dlsym(hdl, "foo");
x = fn();
printf("%d", *x);
The above should work.
EDIT:
Sample program for dlopen,dlsym can be found here with man page info for the same.
Could be just a problem with your example, but in the code you provide, you need to switch the following lines:
x = (*fn)();
fn = dlsym(hdl, "foo");
These two lines appear to be in the wrong order:
x = (*fn)();
fn = dlsym(hdl, "foo");

enumerated datatypes and gcc

I have a function in which one of the function arguments is an integer. During function invocation I am passing an enumerated datatype to this function. After building using gcc, any access to the INTEGER variable inside the function causes a segmentation fault.
Sample code:
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
}
First off, The enum is defined in main() and does not exist for somefun(). You should define the enum outside of main, although I cannot see how this is causing a crash.
After defining the enum outside of the main you should define somefun to be somefun( E_STATE nState ) and test again.
I compiled and ran that code exactly (cut & paste) on my computer, using gcc version 4.2.4, with no errors or segmentation fault. I believe the problem might be somewhere else.
Actually runs for me:
bash $ cat bar.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
int main (int argc, char *argv [])
{
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar.c -o bar
bar.c: In function 'main':
bar.c:22: warning: unused variable 'E_STATE'
bash $ ./bar
Hello?
bash $
Made a couple of changes, but it ran without them. (1) added a tag in the switch just so it had something; (2) added the #include <stdio.h> and printf so I could tell that it had run; (3) added the return 0; to eliminate an uninteresting warning.
It did run successfully with none of the changes, it just didn't do anything visible.
So, what's the OS, what's the hardware architecture?
Update
The code changed while I was trying it, so here's a test of the updated version:
bash $ cat bar-prime.c
#include <stdio.h>
void somefun (unsigned int nState)
{
switch (nState) // <-- Crashes on this line
{
//
// functionality here ...
//
default:
printf("Hello?\n");
}
}
enum {
UNDEFINED = -1,
STATE_NICE,
STATE_GREEDY
} E_STATE;
int main (int argc, char *argv [])
{
somefun (STATE_NICE);
return 0;
}
bash $ gcc -Wall bar-prime.c -o bar-prime && ./bar-prime
Hello?
bash $
Still works. Are you getting a core file in your version? Have you tried getting a stack trace?
Your situation is like specific to sun sparc hardware or similar. Please post uname -a and output of dmesg
From all your answers it seems that the code is logically correct, and I need to investigate the real reason for the crash. I will investigate it and post it soon.

Resources