For testing LD_PRELOAD, I wrote my own getpid, which prints something before calling the original getpid using dlsym. The code is given below.
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <dlfcn.h>
typedef pid_t (*getpidType)(void);
pid_t getpid(void)
{
printf("Hello, getpid!\n");
getpidType f = (getpidType)dlsym(RTLD_NEXT, "getpid");
return f();
}
However when I use such getpid in my program and run it using LD_PRELOAD, by typing LD_PRELOAD=./prelib.so ./prog, I get the following error.
./prog: symbol lookup error: ./prelib.so: undefined symbol: dlsym
But If I do LD_PRELOAD=./prelib.so bash -c 'echo $$', there is no such error. Any idea what is going on here.
Linking it with libdl.so.2 by using -ldl in the makefile solved the problem.
Related
I am trying to wrap the GLIBC math functions including summation, division, multiplication, Cosine, log, and etc. I found a similar post here.
I have created a wrapper script for the log function in which prints something before calculation. Something like this for log function:
#include <dlfcn.h>
#include <stdio.h>
#include <math.h>
static double (*real_log)(double dbl);
double log(double dbl)
{
printf("value is %0.16f\n" , dbl);
real_log = dlsym(RTLD_NEXT, "log");
real_log(dbl);
}
And the test file is something like this:
#include <stdio.h>
#include <math.h>
int main () {
double var;
var = log(2.7);
printf("log is equal to %0.16f\n" , var);
return 0;
}
I have re-compiled the wrapper to create the shared library by this command: gcc -fPIC -shared -o libpreload.so wrapper.c -ldl.
I compiled test file: gcc -fno-builtin-log test.c -o test -lm.
Then I run my test script using: LD_PRELOAD=/path/to/libpreload.so ./test
The output now prints
value is 2.7000000000000002
log is equal to 0.0000000000000000
The log returns zero value while I expect to get the real calculation like this:
value is 2.7000000000000002
log is equal to 0.9932517730102834
I'm so beginner on C programming and also Glibc functionality.
I would appreciate any ideas.
I'm trying to use InetPtonW:
if(InetPtonW(AF_INET, argv[1], &ThisSenderInfo.sin_addr)<=0) {
return 1;
}
However I get the following message when compiling:
warning: implicit declaration of function 'InetPtonW' [-Wimplicit-function-declaration]
undefined reference to `InetPtonW'
collect2.exe: error: ld returned 1 exit status
I've read the documentation located here and I've followed everything but still can't get it to work.
• I'm compiling with Ws2_32 library gcc test.c -o test -lws2_32 using MinGW
• I've included the needed header files #include <ws2tcpip.h> and #include <windows.h>
• I've tried using InetPton but it returns the same error
• Running on Windows 10
I recall running into this exact issue some many months ago. #alk's comment points to a question whose accepted answer feels very similar to what fixed it for me.
You should be able to #define a version macro (or two) before your #include lines to fix it.
While I feel strongly that the aforementioned answer is correct, I'll update this answer later today when I can verify.
Update!
The code I was referencing above doesn't have InetPtonW in it anymore but it had the necessary #defines in it. Here's a brief example that compiles on my machine (win10/mingw64/gcc 8.2.0):
Z:\Some\Directory>gcc test.c -o test -lmswsock -lws2_32
#define NTDDI_VERSION NTDDI_VISTA
#define WINVER _WIN32_WINNT_VISTA
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
/* This is "test.c", please pardon the lack of error checking. */
int main(void) {
BYTE ipbuf[4] = {0};
WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);
printf("%d: ", InetPtonW(AF_INET, L"127.0.0.1", &ipbuf));
for(int i = 0; i < 4; ++i)
printf("%hhu.", ipbuf[i]);
WSACleanup();
}
Output should look like:
Z:\Some\Directory>gcc test.c -o test -lmswsock -lws2_32
Z:\Some\Directory>test
1: 127.0.0.1.
Z:\Some\Directory>
It's a linking error. which say that, included library path, the given function not found. please make sure your dll library path for InetPtonW or make sure that is available in your system or not.
I am writing a program using execv() that compiles and runs another program. I've written up a simple C program named helloWorld.c that when executed outputs, "Hello world," and a second file named testExec.c that is supposed to compile and run helloWorld.c. I've been looking around everywhere to find a way to do this, but I haven't found any answers. The code in testExec.c is:
#include <stdio.h>
#include <unistd.h>
int main(){
char *args[] = {"./hellWorld.c", "./a.out", NULL};
execv("usr/bin/cc", args);
return 0;
}
testExec.c compiles with no errors. However, when I run it I get an error that says, "fatal error: -fuse-linker-plugin, but liblto_plugin.so not found. compilation terminated." Which I think means helloWorld.c is being compiled but when it comes time to run helloWorld.c this error is thrown. I thought maybe that was because I had a.out and helloWorld.c prefaced with './'. I removed './' from both, then either one individually, and still no luck.
I also did 'sudo apt-get install build-essential' along with 'sudo apt-get install gcc'. I wasn't sure if that would resolve the issue but I really wasn't sure what else to try. Anyway, any help would be appreciated!
You're missing the leading slash when calling cc.
Also, the first argument in the argument list is the name of the executable. The actual arguments come after that. You're also not using -o to specify the name of the output file.
#include <stdio.h>
#include <unistd.h>
int main(){
char *args[] = {"cc", "-o", "./a.out", "./hellWorld.c", NULL};
execv("/usr/bin/cc", args);
return 0;
}
EDIT:
The above only compiles. If you want to compile and run, you can do this:
#include <stdio.h>
#include <unistd.h>
int main(){
system("cc -o ./a.out ./hellWorld.c");
execl("./a.out", "a.out", NULL);
return 0;
}
Although this is probably best done as a shell script:
#!/bin/sh
cc -o ./a.out ./hellWorld.c
./a.out
This question already has answers here:
Where is clone() method in sched.h on Mac OS X
(2 answers)
Closed 9 years ago.
I would like to use the clone system call on OS X. It's a Unix system call so it shouldn't be a problem, right? I have successfully tried using fork, vfork and other similar functions. Here is the program I'm trying:
#include <sched.h> //Clone resides here
#include <stdlib.h> //standard library
#include <stdio.h>
#include <time.h>
#include <limits.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/types.h>
int helloWorld();
int main(int argc, char *argv[])
{
int (*functionPointer)() = &helloWorld; //The first argument of clone accepts a pointer to a function which must return int
void **childStack = (void**)malloc(1024); //We will give our child 1kB of stack space
clone(functionPointer, childStack, 0, NULL); //First arugment is the function to be called, second one is our stack, CLONE_VM means to share memory, last NULL PID description
return 0;
}
int helloWorld()
{
printf("Hello (clone) world!\r\n");
return 0;
}
Compiling with gcc -o test my_file.c gives:
Undefined symbols for architecture x86_64:
"_clone", referenced from:
_main in ccG3qOjx.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Feel free to ignore the comments, since I'm just learning. And one more thing.. if I try to pass CLONE_VM in the arguments it doesn't even compile giving me the error:
my_file.c: In function ‘main’:
my_file.c:12: error: ‘CLONE_VM’ undeclared (first use in this function)
my_file.c:12: error: (Each undeclared identifier is reported only once
my_file.c:12: error: for each function it appears in.)
Am I missing an #include? If so, which one?
What am I doing wrong and how to fix it?
clone is specific to Linux, so for OS X you're stuck with fork, or use threads if you can manage with that.
say I have a parent and a child, the child calls a function "hello" in the child with dlopen. Can the child then call a function "world" in the parent? I keep getting symbol lookup error: ./child.so: undefined symbol: world
here are the files. parent.c
#include <dlfcn.h>
typedef void (*fptr)();
#include <stdio.h>
int main () {
void*handle=dlopen("./child.so",RTLD_LAZY);
fptr f=dlsym(handle,"hello");
f();
return 0;
}
void world() {
printf ("world");
}
and child.c
#include <stdio.h>
void hello () {
printf ("hello");
world();
}
Yes, it a dlopen-ed module can call functions from the calling program, provided that the calling program has been linked with the -rdynamic option.
BTW, most plugins need that feature: a firefox plugin obviously wants to call firefox functions.
Read also about visibility function __attribute__ ... Read also Drepper's How to Write Shared Libraries long paper and dlopen(3) man page.
I found the answer on google
http://www.justskins.com/forums/dlopen-calling-functions-other-104185.html
gcc -rdynamic hello.c -ldl
Surprisingly it can. I've personally seen it happen.
You may need to link to the executable with -rdynamic