eclipse CDT /usr/bin/ld: cannot find -l<libname> - linux

this is my code :
#include <stdio.h>
#include <stdlib.h>
#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <libimobiledevice/installation_proxy.h>
#include <libimobiledevice/notification_proxy.h>
#include <libimobiledevice/afc.h>
int main(void) {
idevice_t phone = NULL;
char *udid = NULL;
idevice_new(&phone, udid);
puts("!!!hello!!!"); /* prints !!!Hello World!!! */
return EXIT_SUCCESS;
}
i installed libimobiledevice library and this is
#ls /usr/lib/i386-linux-gnu | grep libimob
libimobiledevice.a
libimobiledevice.so
libimobiledevice.so.4
libimobiledevice.so.4.0.1
but why in configure CDT to use shared library like picture CDT error ?
/usr/bin/ld: cannot find -llibimobiledevice

Under libraries add imobiledevice instead of libimobiledevice. When you use -lx, linker searches for libx.so. In your case linker searched for liblibimobiledevice.so which it could not find.

In Mars Eclipse, to add third party libraries it was only possible from
C++/Build->Setting->Cross G++ Link-> Miscellaneous.
I wasted two hours adding libraries to by other methods, but this one worked for me.

Related

How to force g++ to respect #define _POSIX_C_SOURCE 200809L

I need to use strerror_r to translate error numbers into human readable messages compiled with g++ on Linux Debian Bullseye. The man page notes:
int strerror_r(int errnum, char *buf, size_t buflen);
/* XSI-compliant */
char *strerror_r(int errnum, char *buf, size_t buflen);
/* GNU-specific */
strerror_r():
The XSI-compliant version is provided if:
(_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
Otherwise, the GNU-specific version is provided.
We have two different types of the return value: int or char* depending on the version defined by _POSIX_C_SOURCE. I have this small test program:
~$ cat strerror_r.c
#include <string.h>
#include <stdio.h>
// #define _POSIX_C_SOURCE 200112L
// #undef _GNU_SOURCE
#define ERROR_BUFFER_LEN (size_t)256
int main(int argc, char **argv)
{
#if _POSIX_C_SOURCE < 200112L
char* ret;
#else
int ret;
#endif
char errorBuffer[ERROR_BUFFER_LEN];
int errno;
errno = 0;
ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
fprintf(stderr, "Error message by pointer = '%s'\n", ret);
fprintf(stderr, "Content of errorBuffer = '%s'\n", errorBuffer);
return 0;
}
If I compile it with gcc everything is as expected:
$ gcc strerror_r.c && ./a.out; rm a.out
Error message by pointer = '(null)'
Content of errorBuffer = 'Success'
If I compile it with g++ I get this:
$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
24 | ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| char*
rm: cannot remove 'a.out': No such file or directory
If I try to force the needed version by uncommenting
#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE
I get:
$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c:7: warning: "_POSIX_C_SOURCE" redefined
7 | #define _POSIX_C_SOURCE 200112L
|
In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
from /usr/include/string.h:26,
from strerror_r.c:3:
/usr/include/features.h:281: note: this is the location of the previous definition
281 | # define _POSIX_C_SOURCE 200809L
|
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
24 | ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| char*
rm: cannot remove 'a.out': No such file or directory
What I'm missing here? Why g++ does not compile the default thread save version of strerror_r? I need that version. How can I fix it?
Reference
Feature Test Macros
You need to specify the #define and #undef directives before you include any header files, so the first few lines should look like this:
#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE
#include <string.h>
#include <stdio.h>
That's because those header files or internal header files they include need those values defined to choose the proper variant. If you define them after including the headers, the headers don't see the right values and they don't include the version you want.
Often people specify these values on the command like with the -D and -U arguments so they are always specified before header files are included.

On Linux, why does this library loaded with LD_PRELOAD catch only some openat() calls?

I am trying to intercept openat() calls with the following library comm.c. This is very standard minimal example, nothing special about it. I compile it with
>gcc -shared -Wall -fPIC -Wl,-init,init comm.c -o comm.so
I am pasting this standard minimal example to show that, I thought, I knew what I was doing.
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
typedef int (*openat_type)(int, const char *, int, ...);
static openat_type g_orig_openat;
void init() {
g_orig_openat = (openat_type)dlsym(RTLD_NEXT,"openat");
}
int openat(int dirfd, const char* pathname, int flags, ...) {
int fd;
va_list ap;
if (flags & (O_CREAT)) {
va_start(ap, flags);
fd = g_orig_openat(dirfd, pathname, flags, va_arg(ap, mode_t));
}
else
fd = g_orig_openat(dirfd, pathname, flags);
printf("openat dirfd %d pathname %s\n", dirfd, pathname);
return fd;
}
I am running a tar command, again a minimal example, untarring an archive containing a single file foobar, to a pre-existing subdirectory dir:
>strace -f tar xf foobar.tar -C dir 2>&1 | grep openat
openat(AT_FDCWD, "dir", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
openat(4, "foobar", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0600) = -1 EEXIST (File exists)
openat(4, "foobar", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0600) = 5
However,
>LD_PRELOAD=./comm.so tar xf foobar.tar -C dir
openat dirfd 4 pathname foobar
openat dirfd 4 pathname foobar
OK, I know how to handle this - I have done this before - the reason for this kind of discrepancy, is that the system call openat() that is shown by strace is not done by the same-named user function openat(). To find out what that other user function is, one gets the sources, rebuilds them, and finds out.
So, I got the sources for my tar:
>$(which tar) --version
tar (GNU tar) 1.26
I got the tar 1.26 sources and rebuilt them myself, and, lo and behold, if I use the binary tar that I built, rather than the above installed one, then comm.so does catch all 3 openat calls!
So that means there is no "other user function".
Please help, what is possibly going on here??
NO, the question is not answered by that previous question. That previous answer simply said, the library call may be differently named, than the underlying system call. Here, that is NOT the case because I recompiled the same code myself, and there are no other library calls in there.
According to the discussion mentioned, openat will probably be called by different symbol or function. The system call dumped by tool such as strace is raw system call. It might be wrapped by user function or glibc. If you want intercept it by LD_PRELOAD, you need to find out those wrapper instead of openat. To my experience, you can try intercept open64 or open, it can redirect to openat which you observe on strace.
The link is one example to wrap openat from open64.

mknod() not creating named pipe

I'm trying to create a FIFO named pipe using the mknod() command:
int main() {
char* file="pipe.txt";
int state;
state = mknod(file, S_IFIFO & 0777, 0);
printf("%d",state);
return 0;
}
But the file is not created in my current directory. I tried listing it by ls -l . State returns -1.
I found similar questions here and on other sites and I've tried the solution that most suggested:
int main() {
char* file="pipe.txt";
int state;
unlink(file);
state = mknod(file, S_IFIFO & 0777, 0);
printf("%d",state);
return 0;
}
This made no difference though and the error remains. Am I doing something wrong here or is there some sort of system intervention which is causing this problem?
Help.. Thanks in advance
You are using & to set the file type instead of |. From the docs:
The file type for path is OR'ed into the mode argument, and the
application shall select one of the following symbolic
constants...
Try this:
state = mknod(file, S_IFIFO | 0777, 0);
Because this works:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char* file="pipe.txt";
int state;
unlink(file);
state = mknod(file, S_IFIFO | 0777, 0);
printf("state %d\n", state);
return 0;
}
Compile it:
gcc -o fifo fifo.c
Run it:
$ strace -e trace=mknod ./fifo
mknod("pipe.txt", S_IFIFO|0777) = 0
state 0
+++ exited with 0 +++
See the result:
$ ls -l pipe.txt
prwxrwxr-x. 1 lars lars 0 Jul 16 12:54 pipe.txt

Is there a way can view real process cmdline on linux?

Here is a simple code to fake process name and cmdline on linux:
#include <string.h>
#include <sys/prctl.h>
#include <stdio.h>
#include <unistd.h>
#define NewName "bash"
#define ProcNameMaxLen 16
int main(int argc, char **argv){
int oldlen = strlen(*argv);
char procname[ProcNameMaxLen];
memset(*argv, 0, oldlen);
memccpy(*argv, NewName, 0, oldlen); //modify cmdline
memccpy(procname, NewName, 0, ProcNameMaxLen);
prctl(PR_SET_NAME, procname); //modify procname
sleep(60);
return 0;
}
After run this code I can't view real name by ps,
but something can find in /proc/xxx/exe and /proc/xxx/environ, but so cumbersome.
is there a good way can view real information with all process?
I think this is a big security problem because i usually check process by ps on my server.
way 1: lsof -d txt
Wait more answer...
lsof will tell you the original executable name as it is one of the open files of the malicious process. You can inspect a number of processes using the -p option, or query a single user with the -u option.

Problems on injecting into printf using LD_PRELOAD method

I was hacking printf() of glibc in one of my project and encountered some problem. Could you please give some clues? And one of my concern is why the same solution for malloc/free works perfect!
As attached, “PrintfHank.c” contains my own solution of printf() which will be preloaded before standard library; and “main.c” just outputs a sentence using printf(). After editing two files, I issued following commands:
compile main.c
gcc –Wall –o main main.c
create my own library
gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
test the new library
LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
But I received “hello world” instead of “within my own printf” in the console. When hacking malloc/free functions, it’s okay.
I log in my system as “root” and am using 2.6.23.1-42.fc8-i686. Any comments will be highly appreciated!!
main.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
PrintfHank.c
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <dlfcn.h>
static int (*orig_printf)(const char *format, ...) = NULL;
int printf(const char *format, ...)
{
if (orig_printf == NULL)
{
orig_printf = (int (*)(const char *format, ...))dlsym(RTLD_NEXT, "printf");
}
// TODO: print desired message from caller.
return orig_printf("within my own printf\n");
}
This question is ancient, however:
In your main.c, you've got a newline at the end and aren't using any of the formatting capability of printf.
If I look at the output of LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1 (I've renamed your files somewhat), then near the bottom I can see
17246: transferring control: ./hello
17246:
17246: symbol=puts; lookup in file=./hello [0]
17246: symbol=puts; lookup in file=./printhack.so [0]
17246: symbol=puts; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17246: binding file ./hello [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `puts' [GLIBC_2.2.5]
and no actual mention of printf. puts is basically printf without the formatting and with an automatic line break at the end, so this evidently the result of gcc being "helpful" by replacing the printf with a puts.
To make your example work, I removed the \n from the printf, which gives me output like:
17114: transferring control: ./hello
17114:
17114: symbol=printf; lookup in file=./hello [0]
17114: symbol=printf; lookup in file=./printhack.so [0]
17114: binding file ./hello [0] to ./printhack.so [0]: normal symbol `printf' [GLIBC_2.2.5]
Now I can see that printhack.so is indeed being dragged in with its custom printf.
Alternatively, you can define a custom puts function as well:
static int (*orig_puts)(const char *str) = NULL;
int puts(const char *str)
{
if (orig_puts == NULL)
{
orig_puts = (int (*)(const char *str))dlsym(RTLD_NEXT, "puts");
}
// TODO: print desired message from caller.
return orig_puts("within my own puts");
}
Check
1) preprocessor output. printf can be changed to smth else
gcc -E main.c
2) ld_debug info about printf symbol and preloading
LD_DEBUG=help LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
LD_DEBUG=all LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
Change
return orig_printf("within my own printf\n");
to
return (*orig_printf)("within my own printf\n");

Resources